From 449e9a454d5cc160014f25077bfdf7cd04a411c4 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 20 Apr 2009 18:23:46 +0000 Subject: [PATCH 001/444] Bugfix 18558 In OSX, using spin/extrude etc. buttons, with more than 1 3d window open, should turn cursor in a Question Mark to indicate you have to tell which window to use (yes weak, but that's 2.4x!). OSX didn't support that type of cursor, so no hint happened. Now uses the 'hand' icon for osx... no nicer one is there afaik. --- source/blender/src/ghostwinlay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/src/ghostwinlay.c b/source/blender/src/ghostwinlay.c index 9388ac93543..794ba0cf6e0 100644 --- a/source/blender/src/ghostwinlay.c +++ b/source/blender/src/ghostwinlay.c @@ -212,7 +212,12 @@ static GHOST_TStandardCursor convert_cursor(int curs) { case CURSOR_FACESEL: return GHOST_kStandardCursorRightArrow; case CURSOR_WAIT: return GHOST_kStandardCursorWait; case CURSOR_EDIT: return GHOST_kStandardCursorCrosshair; - case CURSOR_HELP: return GHOST_kStandardCursorHelp; + case CURSOR_HELP: +#ifdef __APPLE__ + return GHOST_kStandardCursorLeftRight; +#else + return GHOST_kStandardCursorHelp; +#endif case CURSOR_X_MOVE: return GHOST_kStandardCursorLeftRight; case CURSOR_Y_MOVE: return GHOST_kStandardCursorUpDown; case CURSOR_PENCIL: return GHOST_kStandardCursorPencil; From 6afaab654d6d9df31f6cb01e8e2c834ae79927fb Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 20 Apr 2009 18:31:48 +0000 Subject: [PATCH 002/444] Bugfix for [#18554] Time + Scale Node Crash --- source/blender/nodes/intern/CMP_nodes/CMP_scale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c b/source/blender/nodes/intern/CMP_nodes/CMP_scale.c index cc6f9249495..ee3607c11f6 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_scale.c @@ -65,8 +65,8 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b newx = cbuf->x * (rd->size / 100.0f); newy = cbuf->y * (rd->size / 100.0f); } else { /* CMP_SCALE_ABSOLUTE */ - newx= (int)in[1]->vec[0]; - newy= (int)in[2]->vec[0]; + newx= MAX2((int)in[1]->vec[0], 1); + newy= MAX2((int)in[2]->vec[0], 1); } newx= MIN2(newx, CMP_SCALE_MAX); newy= MIN2(newy, CMP_SCALE_MAX); From 2d0d06f642b661b084657c05ebb0c664f998a937 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 20 Apr 2009 21:20:33 +0000 Subject: [PATCH 003/444] BGE VideoTexture: fix bug with VideoTexture.materialID() since recent commit. --- source/gameengine/VideoTexture/BlendType.h | 6 ++++-- source/gameengine/VideoTexture/Texture.cpp | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h index ac3ed8812a6..8b243c43912 100644 --- a/source/gameengine/VideoTexture/BlendType.h +++ b/source/gameengine/VideoTexture/BlendType.h @@ -25,6 +25,7 @@ http://www.gnu.org/copyleft/lesser.txt. /// class allows check type of blender python object and access its contained object +/// MUST ONLY BE USED FOR KX classes that are descendent of PyObjectPlus template class BlendType { public: @@ -48,8 +49,9 @@ public: // if pointer to type is set and don't match to type of provided object, return NULL else if (obj->ob_type != m_objType) return NULL; - // return pointer to object - return (PyObj*)obj; + // return pointer to object, this class can only be used for KX object => + // the Py object is actually a proxy + return (PyObj*)BGE_PROXY_REF(obj); } /// parse arguments to get object diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index 66c67023e38..fa941f9260e 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -163,7 +163,8 @@ void Texture_dealloc (Texture * self) // release renderer Py_XDECREF(self->m_source); // close texture - Texture_close(self); + PyObject* ret = Texture_close(self); + Py_DECREF(ret); // release scaled image buffer delete [] self->m_scaledImg; // release object From 217bbb7800679899302ddb058f9ceea1d00c7ce1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Apr 2009 23:17:52 +0000 Subject: [PATCH 004/444] BGE Python API Separate getting a normal attribute and getting __dict__, was having to do too a check for __dict__ on each class (multiple times per getattro call from python) when its not used that often. --- .../Converter/BL_ActionActuator.cpp | 4 ++ .../gameengine/Converter/BL_ActionActuator.h | 1 + .../Converter/BL_ShapeActionActuator.cpp | 4 ++ .../Converter/BL_ShapeActionActuator.h | 1 + source/gameengine/Expressions/ListValue.cpp | 4 ++ source/gameengine/Expressions/ListValue.h | 1 + .../gameengine/Expressions/PyObjectPlus.cpp | 15 +++-- source/gameengine/Expressions/PyObjectPlus.h | 11 ++-- source/gameengine/Expressions/Value.cpp | 4 ++ source/gameengine/Expressions/Value.h | 1 + .../GameLogic/SCA_2DFilterActuator.cpp | 4 ++ .../GameLogic/SCA_2DFilterActuator.h | 1 + .../GameLogic/SCA_ANDController.cpp | 4 ++ .../gameengine/GameLogic/SCA_ANDController.h | 1 + .../GameLogic/SCA_ActuatorSensor.cpp | 4 ++ .../gameengine/GameLogic/SCA_ActuatorSensor.h | 1 + .../gameengine/GameLogic/SCA_AlwaysSensor.cpp | 4 ++ .../gameengine/GameLogic/SCA_AlwaysSensor.h | 2 +- .../gameengine/GameLogic/SCA_DelaySensor.cpp | 4 ++ source/gameengine/GameLogic/SCA_DelaySensor.h | 1 + .../GameLogic/SCA_ExpressionController.h | 1 + .../gameengine/GameLogic/SCA_ILogicBrick.cpp | 7 ++- source/gameengine/GameLogic/SCA_ILogicBrick.h | 1 + source/gameengine/GameLogic/SCA_IObject.cpp | 3 + source/gameengine/GameLogic/SCA_IObject.h | 1 + source/gameengine/GameLogic/SCA_ISensor.cpp | 7 ++- source/gameengine/GameLogic/SCA_ISensor.h | 1 + .../GameLogic/SCA_JoystickSensor.cpp | 4 ++ .../gameengine/GameLogic/SCA_JoystickSensor.h | 1 + .../GameLogic/SCA_KeyboardSensor.cpp | 7 ++- .../gameengine/GameLogic/SCA_KeyboardSensor.h | 1 + .../gameengine/GameLogic/SCA_MouseSensor.cpp | 4 ++ source/gameengine/GameLogic/SCA_MouseSensor.h | 1 + .../GameLogic/SCA_NANDController.cpp | 4 ++ .../gameengine/GameLogic/SCA_NANDController.h | 1 + .../GameLogic/SCA_NORController.cpp | 4 ++ .../gameengine/GameLogic/SCA_NORController.h | 1 + .../gameengine/GameLogic/SCA_ORController.cpp | 4 ++ .../gameengine/GameLogic/SCA_ORController.h | 1 + .../GameLogic/SCA_PropertyActuator.cpp | 4 ++ .../GameLogic/SCA_PropertyActuator.h | 1 + .../GameLogic/SCA_PropertySensor.cpp | 4 ++ .../gameengine/GameLogic/SCA_PropertySensor.h | 1 + .../GameLogic/SCA_RandomActuator.cpp | 4 ++ .../gameengine/GameLogic/SCA_RandomActuator.h | 1 + .../gameengine/GameLogic/SCA_RandomSensor.cpp | 4 ++ .../gameengine/GameLogic/SCA_RandomSensor.h | 1 + .../GameLogic/SCA_XNORController.cpp | 4 ++ .../gameengine/GameLogic/SCA_XNORController.h | 1 + .../GameLogic/SCA_XORController.cpp | 4 ++ .../gameengine/GameLogic/SCA_XORController.h | 1 + source/gameengine/Ketsji/BL_Shader.cpp | 4 ++ source/gameengine/Ketsji/BL_Shader.h | 1 + .../KXNetwork/KX_NetworkMessageActuator.cpp | 4 ++ .../KXNetwork/KX_NetworkMessageActuator.h | 1 + .../KXNetwork/KX_NetworkMessageSensor.cpp | 4 ++ .../KXNetwork/KX_NetworkMessageSensor.h | 1 + .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 4 ++ source/gameengine/Ketsji/KX_BlenderMaterial.h | 1 + source/gameengine/Ketsji/KX_CDActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_CDActuator.h | 1 + source/gameengine/Ketsji/KX_Camera.cpp | 4 ++ source/gameengine/Ketsji/KX_Camera.h | 1 + .../gameengine/Ketsji/KX_CameraActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_CameraActuator.h | 1 + .../Ketsji/KX_ConstraintActuator.cpp | 4 ++ .../gameengine/Ketsji/KX_ConstraintActuator.h | 1 + .../Ketsji/KX_ConstraintWrapper.cpp | 8 ++- .../gameengine/Ketsji/KX_ConstraintWrapper.h | 1 + source/gameengine/Ketsji/KX_GameActuator.cpp | 7 ++- source/gameengine/Ketsji/KX_GameActuator.h | 1 + source/gameengine/Ketsji/KX_GameObject.cpp | 62 +++++++++---------- source/gameengine/Ketsji/KX_GameObject.h | 4 +- source/gameengine/Ketsji/KX_IpoActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_IpoActuator.h | 1 + source/gameengine/Ketsji/KX_Light.cpp | 4 ++ source/gameengine/Ketsji/KX_Light.h | 1 + source/gameengine/Ketsji/KX_MeshProxy.cpp | 4 ++ source/gameengine/Ketsji/KX_MeshProxy.h | 1 + .../gameengine/Ketsji/KX_MouseFocusSensor.cpp | 4 ++ .../gameengine/Ketsji/KX_MouseFocusSensor.h | 3 +- source/gameengine/Ketsji/KX_NearSensor.cpp | 4 ++ source/gameengine/Ketsji/KX_NearSensor.h | 1 + .../gameengine/Ketsji/KX_ObjectActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_ObjectActuator.h | 1 + .../gameengine/Ketsji/KX_ParentActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_ParentActuator.h | 1 + .../Ketsji/KX_PhysicsObjectWrapper.cpp | 5 +- .../Ketsji/KX_PhysicsObjectWrapper.h | 1 + source/gameengine/Ketsji/KX_PolyProxy.cpp | 4 ++ source/gameengine/Ketsji/KX_PolyProxy.h | 1 + .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 4 ++ source/gameengine/Ketsji/KX_PolygonMaterial.h | 1 + source/gameengine/Ketsji/KX_RadarSensor.cpp | 4 ++ source/gameengine/Ketsji/KX_RadarSensor.h | 1 + source/gameengine/Ketsji/KX_RaySensor.cpp | 4 ++ source/gameengine/Ketsji/KX_RaySensor.h | 1 + .../Ketsji/KX_SCA_AddObjectActuator.cpp | 4 ++ .../Ketsji/KX_SCA_AddObjectActuator.h | 1 + .../Ketsji/KX_SCA_DynamicActuator.cpp | 4 ++ .../Ketsji/KX_SCA_DynamicActuator.h | 1 + .../Ketsji/KX_SCA_EndObjectActuator.cpp | 4 ++ .../Ketsji/KX_SCA_EndObjectActuator.h | 1 + .../Ketsji/KX_SCA_ReplaceMeshActuator.cpp | 4 ++ .../Ketsji/KX_SCA_ReplaceMeshActuator.h | 1 + source/gameengine/Ketsji/KX_Scene.cpp | 26 ++++---- source/gameengine/Ketsji/KX_Scene.h | 6 +- source/gameengine/Ketsji/KX_SceneActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_SceneActuator.h | 1 + source/gameengine/Ketsji/KX_SoundActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_SoundActuator.h | 1 + source/gameengine/Ketsji/KX_StateActuator.cpp | 6 +- source/gameengine/Ketsji/KX_StateActuator.h | 1 + source/gameengine/Ketsji/KX_TouchSensor.cpp | 4 ++ source/gameengine/Ketsji/KX_TouchSensor.h | 1 + .../gameengine/Ketsji/KX_TrackToActuator.cpp | 4 ++ source/gameengine/Ketsji/KX_TrackToActuator.h | 1 + .../gameengine/Ketsji/KX_VehicleWrapper.cpp | 4 ++ source/gameengine/Ketsji/KX_VehicleWrapper.h | 1 + source/gameengine/Ketsji/KX_VertexProxy.cpp | 4 ++ source/gameengine/Ketsji/KX_VertexProxy.h | 1 + .../Ketsji/KX_VisibilityActuator.cpp | 4 ++ .../gameengine/Ketsji/KX_VisibilityActuator.h | 1 + 123 files changed, 357 insertions(+), 79 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 7515f3f5f91..3002005ae3f 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -1020,6 +1020,10 @@ PyObject* BL_ActionActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); } +PyObject* BL_ActionActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int BL_ActionActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); } diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 6ae7f716b4b..b3c15c08f50 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -114,6 +114,7 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,setChannel); virtual PyObject* py_getattro(PyObject* attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject* attr, PyObject* value); static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 62bc99bb437..a447ffb8aa9 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -489,6 +489,10 @@ PyObject* BL_ShapeActionActuator::py_getattro(PyObject* attr) { py_getattro_up(SCA_IActuator); } +PyObject* BL_ShapeActionActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int BL_ShapeActionActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index 3bc35ac9495..d268eef6d23 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -107,6 +107,7 @@ public: KX_PYMETHOD_DOC_VARARGS(BL_ShapeActionActuator,SetType); virtual PyObject* py_getattro(PyObject* attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject* attr, PyObject* value); static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index dd9b296dce1..7c31a29f4ac 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -273,6 +273,10 @@ PyObject* CListValue::py_getattro(PyObject* attr) { py_getattro_up(CValue); } +PyObject* CListValue::py_getattro_dict() { + py_getattro_dict_up(CValue); +} + ////////////////////////////////////////////////////////////////////// // Construction/Destruction diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 2af5a330c43..3d88b5aea9c 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -60,6 +60,7 @@ public: bool CheckEqual(CValue* first,CValue* second); virtual PyObject* py_getattro(PyObject* attr); + virtual PyObject* py_getattro_dict(); virtual PyObject* py_repr(void) { PyObject *py_proxy= this->GetProxy(); PyObject *py_list= PySequence_List(py_proxy); diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 6cfa14ddc80..c4daaff2dd1 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -143,7 +143,13 @@ PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); return NULL; } - return self_plus->py_getattro(attr); + + PyObject *ret= self_plus->py_getattro(attr); + + if(ret==NULL && (strcmp(PyString_AsString(attr), "__dict__")==0)) + ret= self_plus->py_getattro_dict(); + + return ret; } /* This should be the entry in Type since it takes the C++ class from PyObjectPlus_Proxy */ @@ -177,9 +183,6 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr) { PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ if (descr == NULL) { - if (strcmp(PyString_AsString(attr), "__dict__")==0) { - return py_getattr_dict(NULL, Type.tp_dict); /* no Attributes yet */ - } PyErr_Format(PyExc_AttributeError, "attribute \"%s\" not found", PyString_AsString(attr)); return NULL; } else { @@ -196,6 +199,10 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr) } } +PyObject* PyObjectPlus::py_getattro_dict() { + return py_getattr_dict(NULL, Type.tp_dict); +} + int PyObjectPlus::py_delattro(PyObject* attr) { PyErr_SetString(PyExc_AttributeError, "attribute cant be deleted"); diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 370717a919b..b0ddfa04e32 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -130,16 +130,12 @@ typedef struct { } \ } else { \ PyErr_Clear(); \ - PyObject *rvalue= Parent::py_getattro(attr); \ - \ - if (strcmp(PyString_AsString(attr), "__dict__")==0) { \ - return py_getattr_dict(rvalue, Type.tp_dict); \ - } \ - \ - return rvalue; \ + return Parent::py_getattro(attr); \ } \ return NULL; +#define py_getattro_dict_up(Parent) \ + return py_getattr_dict(Parent::py_getattro_dict(), Type.tp_dict); /* * nonzero values are an error for setattr @@ -434,6 +430,7 @@ public: /* These are all virtual python methods that are defined in each class * Our own fake subclassing calls these on each class, then calls the parent */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_delattro(PyObject *attr); virtual int py_setattro(PyObject *attr, PyObject *value); virtual PyObject* py_repr(void); diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 7cb97909119..106bd1256a6 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -612,6 +612,10 @@ PyObject* CValue::py_getattro(PyObject *attr) py_getattro_up(PyObjectPlus); } +PyObject* CValue::py_getattro_dict() { + py_getattro_dict_up(PyObjectPlus); +} + CValue* CValue::ConvertPythonToValue(PyObject* pyobj) { diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index a687e1a493c..88186fa95c0 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -225,6 +225,7 @@ public: virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual PyObject* ConvertValueToPython() { return NULL; } diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index 251a586308e..9bf03bf39cc 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -157,6 +157,10 @@ PyObject* SCA_2DFilterActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* SCA_2DFilterActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int SCA_2DFilterActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index de0201a4b19..b43dc092ddb 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -71,6 +71,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); }; diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index 1cb03f375cb..e4642750942 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -145,4 +145,8 @@ PyObject* SCA_ANDController::py_getattro(PyObject *attr) { py_getattro_up(SCA_IController); } +PyObject* SCA_ANDController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index fdb93d0fc42..9a359d57cb4 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -49,6 +49,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index acd906ef9dd..4c85c4f8e5e 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -165,6 +165,10 @@ PyObject* SCA_ActuatorSensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* SCA_ActuatorSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_ActuatorSensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); } diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 21960993497..974b2e43d78 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -62,6 +62,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* 3. setProperty */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index b7ecb0233a1..874883c89b1 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -143,4 +143,8 @@ PyObject* SCA_AlwaysSensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* SCA_AlwaysSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 87949babf59..769e1e883bc 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -53,7 +53,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); - + virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index 44a0175d916..0e4a00e2745 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -182,6 +182,10 @@ PyObject* SCA_DelaySensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* SCA_DelaySensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_DelaySensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); } diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index 8da76ff7189..31394fdc961 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -61,6 +61,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* setProperty */ diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 2936742be19..6a34d7b2dff 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -60,6 +60,7 @@ public: /* --------------------------------------------------------------------- */ // virtual PyObject* py_getattro(PyObject *attr); +// virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 3cd750ff63b..02a25916299 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -278,12 +278,15 @@ int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef) return 0; } -PyObject* -SCA_ILogicBrick::py_getattro(PyObject *attr) +PyObject* SCA_ILogicBrick::py_getattro(PyObject *attr) { py_getattro_up(CValue); } +PyObject* SCA_ILogicBrick::py_getattro_dict() { + py_getattro_dict_up(CValue); +} + int SCA_ILogicBrick::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(CValue); diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index e59d05ea051..f2353741d39 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -80,6 +80,7 @@ public: virtual bool LessComparedTo(SCA_ILogicBrick* other); virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); static class SCA_LogicManager* m_sCurrentLogicManager; diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 75804525e7a..8e599e6411a 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -418,3 +418,6 @@ PyObject* SCA_IObject::py_getattro(PyObject *attr) { py_getattro_up(CValue); } +PyObject* SCA_IObject::py_getattro_dict() { + py_getattro_dict_up(CValue); +} diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 44ed3c8f3fe..7f63c9f5efd 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -146,6 +146,7 @@ public: // here come the python forwarded methods virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int GetGameObjectType() {return -1;} diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index 68f5653d53a..dde970962b6 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -459,12 +459,15 @@ PyAttributeDef SCA_ISensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* -SCA_ISensor::py_getattro(PyObject *attr) +PyObject* SCA_ISensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ILogicBrick); } +PyObject* SCA_ISensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ILogicBrick); +} + int SCA_ISensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ILogicBrick); diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 6b1c8cca104..e2ceec19b69 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -137,6 +137,7 @@ public: /* Python functions: */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated functions -----> diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 1c601eded81..a8c6f87ebdd 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -339,6 +339,10 @@ PyObject* SCA_JoystickSensor::py_getattro(PyObject *attr) py_getattro_up(SCA_ISensor); } +PyObject* SCA_JoystickSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_JoystickSensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index cf3e7e74414..20fff66f66c 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -123,6 +123,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* Joystick Index */ diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index c946156283f..96969dc6dc7 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -664,12 +664,15 @@ PyAttributeDef SCA_KeyboardSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* -SCA_KeyboardSensor::py_getattro(PyObject *attr) +PyObject* SCA_KeyboardSensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* SCA_KeyboardSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_KeyboardSensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 073b3e6dbe0..1dd6ea21fcd 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -111,6 +111,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated functions -----> diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index 4dbeb156e63..0bae676d19d 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -342,6 +342,10 @@ PyObject* SCA_MouseSensor::py_getattro(PyObject *attr) py_getattro_up(SCA_ISensor); } +PyObject* SCA_MouseSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_MouseSensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index 2d1c496029d..528237475db 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -110,6 +110,7 @@ class SCA_MouseSensor : public SCA_ISensor /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated functions -----> diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index 703c9c1bbaf..dedf32df3c9 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -145,4 +145,8 @@ PyObject* SCA_NANDController::py_getattro(PyObject *attr) { py_getattro_up(SCA_IController); } +PyObject* SCA_NANDController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 11600914a1a..0ae0ff19745 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -49,6 +49,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index 06acae5a81a..8cd575ffef3 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -145,4 +145,8 @@ PyObject* SCA_NORController::py_getattro(PyObject *attr) { py_getattro_up(SCA_IController); } +PyObject* SCA_NORController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index fc814e28d37..06cbb70a489 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -49,6 +49,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 319ff04f776..a12246e9a73 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -138,4 +138,8 @@ PyObject* SCA_ORController::py_getattro(PyObject *attr) { py_getattro_up(SCA_IController); } +PyObject* SCA_ORController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index fdc81486e74..66f772c739e 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -50,6 +50,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; #endif //__KX_ORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index c4db723ee89..beb7a09a137 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -279,6 +279,10 @@ PyObject* SCA_PropertyActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); } +PyObject* SCA_PropertyActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int SCA_PropertyActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); } diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index bb841cf88ad..a8df08dfc6e 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -87,6 +87,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // python wrapped methods diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index de8a9fcf03e..c56dd3a12f4 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -356,6 +356,10 @@ PyObject* SCA_PropertySensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* SCA_PropertySensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_PropertySensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); } diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index e1e378a973c..7abf4d44a5b 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -90,6 +90,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* 1. getType */ diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index 3a72d9b7652..b9df198f7da 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -395,6 +395,10 @@ PyObject* SCA_RandomActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); } +PyObject* SCA_RandomActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int SCA_RandomActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index 8f58ed0dcec..310e8a7fbf9 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -97,6 +97,7 @@ class SCA_RandomActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); static PyObject* pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 5ead82db428..494b7a3694e 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -170,6 +170,10 @@ PyObject* SCA_RandomSensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* SCA_RandomSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int SCA_RandomSensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 764692600c3..63a96dd72d0 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -61,6 +61,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* 1. setSeed */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index e9bb37ee958..145afa6aec5 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -149,4 +149,8 @@ PyObject* SCA_XNORController::py_getattro(PyObject *attr) { py_getattro_up(SCA_IController); } +PyObject* SCA_XNORController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index c992d5f1834..4aad5763cb0 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -49,6 +49,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 791a139975f..4dfba3a56ac 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -149,4 +149,8 @@ PyObject* SCA_XORController::py_getattro(PyObject *attr) { py_getattro_up(SCA_IController); } +PyObject* SCA_XORController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + /* eof */ diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index 065b31fd901..feb9f2ed07c 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -49,6 +49,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index 88d920043e0..2b3612ec3ae 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -734,6 +734,10 @@ PyObject* BL_Shader::py_getattro(PyObject *attr) py_getattro_up(PyObjectPlus); } +PyObject* BL_Shader::py_getattro_dict() { + py_getattro_dict_up(PyObjectPlus); +} + PyMethodDef BL_Shader::Methods[] = { diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 08cad5071fd..7db40e778ae 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -203,6 +203,7 @@ public: // Python interface virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual PyObject* py_repr(void) { return PyString_FromFormat("BL_Shader\n\tvertex shader:%s\n\n\tfragment shader%s\n\n", vertProg, fragProg); } // ----------------------------------- diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp index 2483a6bfb39..9c36a899505 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp @@ -157,6 +157,10 @@ PyObject* KX_NetworkMessageActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); } +PyObject* KX_NetworkMessageActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_NetworkMessageActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index 850f825b8f3..cf92fd46fe0 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -62,6 +62,7 @@ public: /* ------------------------------------------------------------ */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index 7782567943e..b1b9c0e1fc9 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -227,6 +227,10 @@ PyObject* KX_NetworkMessageSensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* KX_NetworkMessageSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int KX_NetworkMessageSensor::py_setattro(PyObject *attr, PyObject *value) { return SCA_ISensor::py_setattro(attr, value); } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index ac0e880d25c..3abba7cfffd 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -73,6 +73,7 @@ public: /* ------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 849332008ce..2edfe4b718c 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -784,6 +784,10 @@ PyObject* KX_BlenderMaterial::py_getattro(PyObject *attr) py_getattro_up(PyObjectPlus); } +PyObject* KX_BlenderMaterial::py_getattro_dict() { + py_getattro_dict_up(PyObjectPlus); +} + int KX_BlenderMaterial::py_setattro(PyObject *attr, PyObject *pyvalue) { return PyObjectPlus::py_setattro(attr, pyvalue); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 48d4730ab07..57cdde3c947 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -83,6 +83,7 @@ public: // -------------------------------- virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *pyvalue); virtual PyObject* py_repr(void) { return PyString_FromString(mMaterial->matname.ReadPtr()); } diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index 121d4512265..6e318cdcfa3 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -220,6 +220,10 @@ PyObject* KX_CDActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_CDActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_CDActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h index b674755e59f..2fd05ab72e5 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.h +++ b/source/gameengine/Ketsji/KX_CDActuator.h @@ -82,6 +82,7 @@ public: /* -------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index c8575424751..f84ce23b7dd 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -544,6 +544,10 @@ PyObject* KX_Camera::py_getattro(PyObject *attr) py_getattro_up(KX_GameObject); } +PyObject* KX_Camera::py_getattro_dict() { + py_getattro_dict_up(KX_GameObject); +} + int KX_Camera::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(KX_GameObject); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 4accd4bc2f1..6f818cb2c57 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -278,6 +278,7 @@ public: KX_PYMETHOD_DOC_NOARGS(KX_Camera, setOnTop); virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */ + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *pyvalue); static PyObject* pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 355cdbb6263..2ef7abfd172 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -425,6 +425,10 @@ PyObject* KX_CameraActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); } +PyObject* KX_CameraActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_CameraActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); } diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index 9298e1e868d..efa4e2f38d7 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -121,6 +121,7 @@ private : /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); /* set object to look at */ diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index 1ce7fac0cfe..00fed43cbe8 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -640,6 +640,10 @@ PyObject* KX_ConstraintActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_ConstraintActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_ConstraintActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 98f6fcd7906..84512c0ecf2 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -144,6 +144,7 @@ protected: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); static int pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index 7c3abb49159..c537c9abe01 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -87,12 +87,16 @@ PyParentObject KX_ConstraintWrapper::Parents[] = { NULL }; -PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr) +//here you can search for existing data members (like mass,friction etc.) +PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr) { - //here you can search for existing data members (like mass,friction etc.) py_getattro_up(PyObjectPlus); } +PyObject* KX_ConstraintWrapper::py_getattro_dict() { + py_getattro_dict_up(PyObjectPlus); +} + int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* pyobj) { int result = 1; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 6e67d842cb6..3270d57188d 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -36,6 +36,7 @@ class KX_ConstraintWrapper : public PyObjectPlus { Py_Header; virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); public: KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 8b587c6f7de..0a411396ff8 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -253,12 +253,15 @@ PyAttributeDef KX_GameActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* -KX_GameActuator::py_getattro(PyObject *attr) +PyObject* KX_GameActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); } +PyObject* KX_GameActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_GameActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h index 570cb2e68ef..b2b1d6ec2b9 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.h +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -78,6 +78,7 @@ protected: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated functions -----> diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index bea0fcff2af..1f4c9c2e9d5 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1153,8 +1153,6 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), KX_PYATTRIBUTE_RO_FUNCTION("worldScaling", KX_GameObject, pyattr_get_worldScaling), - KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_GameObject, pyattr_get_dir_dict), - /* Experemental, dont rely on these yet */ KX_PYATTRIBUTE_RO_FUNCTION("sensors", KX_GameObject, pyattr_get_sensors), KX_PYATTRIBUTE_RO_FUNCTION("controllers", KX_GameObject, pyattr_get_controllers), @@ -1703,37 +1701,6 @@ PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE return resultlist; } -/* __dict__ only for the purpose of giving useful dir() results */ -PyObject* KX_GameObject::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ - KX_GameObject* self= static_cast(self_v); - PyObject *dict_str = PyString_FromString("__dict__"); - PyObject *dict= py_getattr_dict(self->SCA_IObject::py_getattro(dict_str), Type.tp_dict); - Py_DECREF(dict_str); - - if(dict==NULL) - return NULL; - - /* Not super fast getting as a list then making into dict keys but its only for dir() */ - PyObject *list= self->ConvertKeysToPython(); - if(list) - { - int i; - for(i=0; im_attr_dict) - PyDict_Update(dict, self->m_attr_dict); - - return dict; -} - /* We need these because the macros have a return in them */ PyObject* KX_GameObject::py_getattro__internal(PyObject *attr) { @@ -1772,6 +1739,35 @@ PyObject* KX_GameObject::py_getattro(PyObject *attr) return object; } +PyObject* KX_GameObject::py_getattro_dict() { + //py_getattro_dict_up(SCA_IObject); + PyObject *dict= py_getattr_dict(SCA_IObject::py_getattro_dict(), Type.tp_dict); + if(dict==NULL) + return NULL; + + /* normally just return this but KX_GameObject has some more items */ + + + /* Not super fast getting as a list then making into dict keys but its only for dir() */ + PyObject *list= ConvertKeysToPython(); + if(list) + { + int i; + for(i=0; iname+2 : ""); } diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 8277e7ef19c..d1075f9b296 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -304,6 +304,10 @@ PyObject* KX_RadarSensor::py_getattro(PyObject *attr) py_getattro_up(KX_NearSensor); } +PyObject* KX_RadarSensor::py_getattro_dict() { + py_getattro_dict_up(KX_NearSensor); +} + int KX_RadarSensor::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(KX_NearSensor); diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index c3a941696ce..8389a2a29eb 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -90,6 +90,7 @@ public: }; virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); //Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 06c04dbf10d..360aa1a85a8 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -449,6 +449,10 @@ PyObject* KX_RaySensor::py_getattro(PyObject *attr) { py_getattro_up(SCA_ISensor); } +PyObject* KX_RaySensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int KX_RaySensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); } diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index a5d7d15c60c..558840e2f17 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -87,6 +87,7 @@ public: virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 56d94a8d226..b5aa7a2f4c2 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -260,6 +260,10 @@ PyObject* KX_SCA_AddObjectActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_SCA_AddObjectActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_SCA_AddObjectActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 4ece5a6d83b..6746b7d1bc6 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -111,6 +111,7 @@ public: Update(); virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); SCA_IObject* diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index 9c9cdcd6c4c..dd3250f5b61 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -97,6 +97,10 @@ PyObject* KX_SCA_DynamicActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_SCA_DynamicActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_SCA_DynamicActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h index 99855124bdb..4add707f8cd 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h @@ -75,6 +75,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* 1. setOperation */ diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp index 3b42577810e..c0dc6ea6b55 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -136,4 +136,8 @@ PyObject* KX_SCA_EndObjectActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_SCA_EndObjectActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + /* eof */ diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h index 2940246f443..70d72f1f8da 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h @@ -65,6 +65,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); }; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 38f8d581d55..b7135a5503a 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -99,6 +99,10 @@ PyObject* KX_SCA_ReplaceMeshActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_SCA_ReplaceMeshActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_SCA_ReplaceMeshActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 7a18df2356d..0e7f7852701 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -72,6 +72,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator void InstantReplaceMesh(); virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); static PyObject* pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index aa7bd65f240..f91c4674113 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1630,19 +1630,6 @@ PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_ return self->GetActiveCamera()->GetProxy(); } -/* __dict__ only for the purpose of giving useful dir() results */ -PyObject* KX_Scene::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ - KX_Scene* self= static_cast(self_v); - /* Useually done by py_getattro_up but in this case we want to include m_attr_dict dict */ - PyObject *dict_str= PyString_FromString("__dict__"); - PyObject *dict= py_getattr_dict(self->PyObjectPlus::py_getattro(dict_str), Type.tp_dict); - Py_DECREF(dict_str); - - PyDict_Update(dict, self->m_attr_dict); - return dict; -} - PyAttributeDef KX_Scene::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects), @@ -1651,7 +1638,6 @@ PyAttributeDef KX_Scene::Attributes[] = { KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling), KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius), KX_PYATTRIBUTE_BOOL_RO("dbvt_culling", KX_Scene, m_dbvt_culling), - KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_Scene, pyattr_get_dir_dict), { NULL } //Sentinel }; @@ -1685,6 +1671,18 @@ PyObject* KX_Scene::py_getattro(PyObject *attr) return object; } +PyObject* KX_Scene::py_getattro_dict() { + //py_getattro_dict_up(PyObjectPlus); + + PyObject *dict= py_getattr_dict(PyObjectPlus::py_getattro_dict(), Type.tp_dict); + if(dict==NULL) + return NULL; + + /* normally just return this but KX_Scene has some more items */ + + PyDict_Update(dict, m_attr_dict); + return dict; +} int KX_Scene::py_setattro(PyObject *attr, PyObject *value) { diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index a06c66ec5dd..83a4692f815 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -593,12 +593,10 @@ public: static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_objects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); - - /* for dir(), python3 uses __dir__() */ - static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); - virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ + virtual PyObject* py_getattro_dict(); + virtual int py_setattro(PyObject *attr, PyObject *pyvalue); virtual int py_delattro(PyObject *attr); virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); } diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index f54d8542260..c525aeb1e3f 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -281,6 +281,10 @@ PyObject* KX_SceneActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_SceneActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 803c5106a60..315e97e8f70 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -93,6 +93,7 @@ class KX_SceneActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); /* 1. set */ diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 412be497c5a..4103da4ad93 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -340,6 +340,10 @@ PyObject* KX_SoundActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_SoundActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_SoundActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); } diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index d5e678bbecd..ad58087dc57 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -81,6 +81,7 @@ public: /* -------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, startSound); diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index 976e7ea5204..16512dc6699 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -156,7 +156,11 @@ PyAttributeDef KX_StateActuator::Attributes[] = { PyObject* KX_StateActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); -}; +} + +PyObject* KX_StateActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} int KX_StateActuator::py_setattro(PyObject *attr, PyObject* value) { diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index 4a64894259d..7e7056bd6af 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -76,6 +76,7 @@ class KX_StateActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetOperation); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 5a6e8e6f501..8995a0c198a 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -296,6 +296,10 @@ PyObject* KX_TouchSensor::py_getattro(PyObject *attr) py_getattro_up(SCA_ISensor); } +PyObject* KX_TouchSensor::py_getattro_dict() { + py_getattro_dict_up(SCA_ISensor); +} + int KX_TouchSensor::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_ISensor); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 15ef653c1b2..4bcc313b65b 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -121,6 +121,7 @@ public: /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index fbf43de6cf4..808bf0a55b5 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -509,6 +509,10 @@ PyObject* KX_TrackToActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_TrackToActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_TrackToActuator::py_setattro(PyObject *attr, PyObject* value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 99505f93cfe..a17147c0842 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -73,6 +73,7 @@ class KX_TrackToActuator : public SCA_IActuator /* Python part */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); /* These are used to get and set m_ob */ diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 1a6fb196db5..5a0ec3515f6 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -303,6 +303,10 @@ PyObject* KX_VehicleWrapper::py_getattro(PyObject *attr) py_getattro_up(PyObjectPlus); } +PyObject* KX_VehicleWrapper::py_getattro_dict() { + py_getattro_dict_up(PyObjectPlus); +} + int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* pyobj) { /* TODO - strange setattr, needs updating */ diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index de7fe75cfba..c2b5e3d9251 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -13,6 +13,7 @@ class KX_VehicleWrapper : public PyObjectPlus { Py_Header; virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); std::vector m_motionStates; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 88f63334285..e5078bfa18b 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -159,6 +159,10 @@ KX_VertexProxy::py_getattro(PyObject *attr) py_getattro_up(SCA_IObject); } +PyObject* KX_VertexProxy::py_getattro_dict() { + py_getattro_dict_up(SCA_IObject); +} + int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) { char *attr_str= PyString_AsString(attr); diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 67a15d96768..50fe6b27704 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -55,6 +55,7 @@ public: // stuff for python integration virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *pyvalue); KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ); diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index ba59d0d3d47..9b1849511fe 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -143,6 +143,10 @@ PyObject* KX_VisibilityActuator::py_getattro(PyObject *attr) py_getattro_up(SCA_IActuator); } +PyObject* KX_VisibilityActuator::py_getattro_dict() { + py_getattro_dict_up(SCA_IActuator); +} + int KX_VisibilityActuator::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IActuator); diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h index 04633bce665..45aba50f645 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.h +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -70,6 +70,7 @@ class KX_VisibilityActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> From 720f7a8b6900787734d11cff396945f693961250 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Apr 2009 23:27:53 +0000 Subject: [PATCH 005/444] use PyList_SET_ITEM instead of PyList_SetItem, PyList_SetItem does error checking and decref's existing values, PyList_SET_ITEM is a macro for direct assignment, only for use on new lists. --- .../gameengine/Expressions/PyObjectPlus.cpp | 8 +-- .../GameLogic/SCA_KeyboardSensor.cpp | 2 +- .../Ketsji/KX_ConstraintActuator.cpp | 6 +- .../gameengine/Ketsji/KX_ObjectActuator.cpp | 72 +++++++++---------- source/gameengine/Ketsji/KX_PythonInit.cpp | 4 +- source/gameengine/Ketsji/KX_RadarSensor.cpp | 12 ++-- source/gameengine/Ketsji/KX_RaySensor.cpp | 18 ++--- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index c4daaff2dd1..96753d56d94 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -240,14 +240,14 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef { bool *val = reinterpret_cast(ptr); ptr += sizeof(bool); - PyList_SetItem(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); break; } case KX_PYATTRIBUTE_TYPE_SHORT: { short int *val = reinterpret_cast(ptr); ptr += sizeof(short int); - PyList_SetItem(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); break; } case KX_PYATTRIBUTE_TYPE_ENUM: @@ -262,14 +262,14 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef { int *val = reinterpret_cast(ptr); ptr += sizeof(int); - PyList_SetItem(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); break; } case KX_PYATTRIBUTE_TYPE_FLOAT: { float *val = reinterpret_cast(ptr); ptr += sizeof(float); - PyList_SetItem(resultlist,i,PyFloat_FromDouble(*val)); + PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(*val)); break; } default: diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index 96969dc6dc7..2048731f73c 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -694,7 +694,7 @@ PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBU { PyObject* keypair = PyList_New(2); PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); PyList_Append(resultlist,keypair); } } diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index 00fed43cbe8..34102132db8 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -754,9 +754,9 @@ PyObject* KX_ConstraintActuator::PyGetDirection(){ ShowDeprecationWarning("getDirection()", "the direction property"); PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_refDirection[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_refDirection[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_refDirection[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_refDirection[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_refDirection[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_refDirection[2])); return retVal; } diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index c115a8f33bc..ed5539709e4 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -352,10 +352,10 @@ PyObject* KX_ObjectActuator::PyGetForce() { PyObject *retVal = PyList_New(4); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_force[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_force[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_force[2])); - PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_force[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_force[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_force[2])); + PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force)); return retVal; } @@ -379,10 +379,10 @@ PyObject* KX_ObjectActuator::PyGetTorque() { PyObject *retVal = PyList_New(4); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2])); - PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_torque[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_torque[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_torque[2])); + PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque)); return retVal; } @@ -406,10 +406,10 @@ PyObject* KX_ObjectActuator::PyGetDLoc() { PyObject *retVal = PyList_New(4); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_dloc[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_dloc[2])); - PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_dloc[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_dloc[2])); + PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc)); return retVal; } @@ -433,10 +433,10 @@ PyObject* KX_ObjectActuator::PyGetDRot() { PyObject *retVal = PyList_New(4); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_drot[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_drot[2])); - PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_drot[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_drot[2])); + PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot)); return retVal; } @@ -459,10 +459,10 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* args) PyObject* KX_ObjectActuator::PyGetLinearVelocity() { PyObject *retVal = PyList_New(4); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); - PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); + PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity)); return retVal; } @@ -486,10 +486,10 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) { PyObject* KX_ObjectActuator::PyGetAngularVelocity() { PyObject *retVal = PyList_New(4); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2])); - PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2])); + PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity)); return retVal; } @@ -526,9 +526,9 @@ PyObject* KX_ObjectActuator::PyGetForceLimitX() { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[0])); - PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[0])); + PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque)); return retVal; } @@ -551,9 +551,9 @@ PyObject* KX_ObjectActuator::PyGetForceLimitY() { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[1])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1])); - PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[1])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[1])); + PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc)); return retVal; } @@ -576,9 +576,9 @@ PyObject* KX_ObjectActuator::PyGetForceLimitZ() { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[2])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[2])); - PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot)); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[2])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[2])); + PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot)); return retVal; } @@ -601,9 +601,9 @@ PyObject* KX_ObjectActuator::PyGetPID() { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_torque[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_torque[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_torque[2])); return retVal; } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 9649e50a98b..873e49be6bb 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -216,13 +216,13 @@ static PyObject* gPyGetSpectrum(PyObject*) for (int index = 0; index < 512; index++) { - PyList_SetItem(resultlist, index, PyFloat_FromDouble(spectrum[index])); + PyList_SET_ITEM(resultlist, index, PyFloat_FromDouble(spectrum[index])); } } else { for (int index = 0; index < 512; index++) { - PyList_SetItem(resultlist, index, PyFloat_FromDouble(0.0)); + PyList_SET_ITEM(resultlist, index, PyFloat_FromDouble(0.0)); } } diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index d1075f9b296..d06728c1d4d 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -212,9 +212,9 @@ PyObject* KX_RadarSensor::PyGetConeOrigin() { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_cone_origin[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_cone_origin[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_cone_origin[2])); return retVal; } @@ -228,9 +228,9 @@ PyObject* KX_RadarSensor::PyGetConeTarget() { PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_cone_target[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_cone_target[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_cone_target[2])); return retVal; } diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 360aa1a85a8..bee644b6a30 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -404,9 +404,9 @@ PyObject* KX_RaySensor::PyGetHitPosition() PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_hitPosition[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_hitPosition[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_hitPosition[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_hitPosition[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_hitPosition[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_hitPosition[2])); return retVal; } @@ -420,9 +420,9 @@ PyObject* KX_RaySensor::PyGetRayDirection() PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_rayDirection[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_rayDirection[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_rayDirection[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_rayDirection[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_rayDirection[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_rayDirection[2])); return retVal; } @@ -436,9 +436,9 @@ PyObject* KX_RaySensor::PyGetHitNormal() PyObject *retVal = PyList_New(3); - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_hitNormal[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_hitNormal[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_hitNormal[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_hitNormal[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_hitNormal[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_hitNormal[2])); return retVal; } From 70dae5f49339a791c1c84d72047cde144e4e2843 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 01:59:14 +0000 Subject: [PATCH 006/444] [#18557] incorrect alpha IPO behavior in game engine from Louis-Dominique Dubeau (zenoparadox) report contained fix, ancient bug from rev2. --- source/blender/blenkernel/intern/ipo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 29db0ddd808..0077cf95262 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2876,7 +2876,7 @@ float IPO_GetFloatValue (Ipo *ipo, IPO_Channel channel, float ctime) calc_ipo_spec(ipo, channel, &ctime); /* unapply rotation hack, as gameengine doesn't use it */ - if ((OB_ROT_X <= channel) && (channel <= OB_DROT_Z)) + if ((ipo->blocktype == ID_OB) && (OB_ROT_X <= channel) && (channel <= OB_DROT_Z)) ctime *= (float)(M_PI_2/9.0); /* return the value of this channel */ From 2d054e00b068786996f9154e378e75f436eca239 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 07:16:29 +0000 Subject: [PATCH 007/444] Blender Python API use getseter's for quat and euler types attributes, python3 compatible module initialization for Mathutils and BGL. --- source/blender/python/api2_2x/BGL.c | 22 +- source/blender/python/api2_2x/Mathutils.c | 20 ++ source/blender/python/api2_2x/euler.c | 147 +++++++------ source/blender/python/api2_2x/quat.c | 248 +++++++++++++--------- source/blender/python/api2_2x/vector.c | 15 +- source/blender/python/api2_2x/vector.h | 2 +- 6 files changed, 270 insertions(+), 184 deletions(-) diff --git a/source/blender/python/api2_2x/BGL.c b/source/blender/python/api2_2x/BGL.c index cfbb4611c6c..ddb12eb2338 100644 --- a/source/blender/python/api2_2x/BGL.c +++ b/source/blender/python/api2_2x/BGL.c @@ -1085,9 +1085,29 @@ static struct PyMethodDef BGL_methods[] = { {NULL, NULL, 0, NULL} }; +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef BGL_module_def = { + {}, /* m_base */ + "BGL", /* m_name */ + 0, /* m_doc */ + 0, /* m_size */ + BGL_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif + PyObject *BGL_Init(const char *from) { - PyObject *mod= Py_InitModule(from, BGL_methods); + PyObject *mod; +#if (PY_VERSION_HEX >= 0x03000000) + mod = PyModule_Create(&BGL_module_def); +#else + mod= Py_InitModule(from, BGL_methods); +#endif + PyObject *dict= PyModule_GetDict(mod); PyObject *item; if( PyType_Ready( &buffer_Type) < 0) diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index b370aa0e1e8..605b5982137 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -108,6 +108,21 @@ struct PyMethodDef M_Mathutils_methods[] = { }; /*----------------------------MODULE INIT-------------------------*/ /* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */ + +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef M_Mathutils_module_def = { + {}, /* m_base */ + "Mathutils", /* m_name */ + M_Mathutils_doc, /* m_doc */ + 0, /* m_size */ + M_Mathutils_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif + PyObject *Mathutils_Init(const char *from) { PyObject *submodule; @@ -126,7 +141,12 @@ PyObject *Mathutils_Init(const char *from) if( PyType_Ready( &quaternion_Type ) < 0 ) return NULL; +#if (PY_VERSION_HEX >= 0x03000000) + submodule = PyModule_Create(&M_Mathutils_module_def); +#else submodule = Py_InitModule3(from, M_Mathutils_methods, M_Mathutils_doc); +#endif + return (submodule); } //-----------------------------METHODS---------------------------- diff --git a/source/blender/python/api2_2x/euler.c b/source/blender/python/api2_2x/euler.c index e349dd26532..52f1e00221e 100644 --- a/source/blender/python/api2_2x/euler.c +++ b/source/blender/python/api2_2x/euler.c @@ -189,71 +189,13 @@ static void Euler_dealloc(EulerObject * self) } PyObject_DEL(self); } -//----------------------------getattr()(internal) ------------------ -//object.attribute access (get) -static PyObject *Euler_getattr(EulerObject * self, char *name) -{ - if(STREQ(name,"x")){ - return PyFloat_FromDouble(self->eul[0]); - }else if(STREQ(name, "y")){ - return PyFloat_FromDouble(self->eul[1]); - }else if(STREQ(name, "z")){ - return PyFloat_FromDouble(self->eul[2]); - } - if(STREQ(name, "wrapped")){ - if(self->wrapped == Py_WRAP) - return EXPP_incr_ret((PyObject *)Py_True); - else - return EXPP_incr_ret((PyObject *)Py_False); - } - return Py_FindMethod(Euler_methods, (PyObject *) self, name); -} -//----------------------------setattr()(internal) ------------------ -//object.attribute access (set) -static int Euler_setattr(EulerObject * self, char *name, PyObject * e) -{ - PyObject *f = NULL; - f = PyNumber_Float(e); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnIntError(PyExc_TypeError, - "euler.attribute = x: argument not a number\n"); - } - - if(STREQ(name,"x")){ - self->eul[0] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "y")){ - self->eul[1] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "z")){ - self->eul[2] = (float)PyFloat_AS_DOUBLE(f); - }else{ - Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_AttributeError, - "euler.attribute = x: unknown attribute\n"); - } - - Py_DECREF(f); - return 0; -} //----------------------------print object (internal)-------------- //print the object to screen static PyObject *Euler_repr(EulerObject * self) { - int i; - char buffer[48], str[1024]; - - BLI_strncpy(str,"[",1024); - for(i = 0; i < 3; i++){ - if(i < (2)){ - sprintf(buffer, "%.6f, ", self->eul[i]); - strcat(str,buffer); - }else{ - sprintf(buffer, "%.6f", self->eul[i]); - strcat(str,buffer); - } - } - strcat(str, "](euler)"); - + char str[64]; + sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]); return PyString_FromString(str); } //------------------------tp_richcmpr @@ -409,6 +351,83 @@ static PySequenceMethods Euler_SeqMethods = { (intobjargproc) Euler_ass_item, /* sq_ass_item */ (intintobjargproc) Euler_ass_slice, /* sq_ass_slice */ }; + + + +/* + * 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; +} + +static int Euler_setAxis( EulerObject * self, PyObject * value, void * type ) +{ + float param= (float)PyFloat_AsDouble( value ); + + if (param==-1 && PyErr_Occurred()) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected a number for the vector axis" ); + + 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; +} + + +/*****************************************************************************/ +/* 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}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + //------------------PY_OBECT DEFINITION-------------------------- PyTypeObject euler_Type = { PyObject_HEAD_INIT(NULL) //tp_head @@ -418,8 +437,8 @@ PyTypeObject euler_Type = { 0, //tp_itemsize (destructor)Euler_dealloc, //tp_dealloc 0, //tp_print - (getattrfunc)Euler_getattr, //tp_getattr - (setattrfunc) Euler_setattr, //tp_setattr + 0, //tp_getattr + 0, //tp_setattr 0, //tp_compare (reprfunc) Euler_repr, //tp_repr 0, //tp_as_number @@ -439,9 +458,9 @@ PyTypeObject euler_Type = { 0, //tp_weaklistoffset 0, //tp_iter 0, //tp_iternext - 0, //tp_methods + Euler_methods, //tp_methods 0, //tp_members - 0, //tp_getset + Euler_getseters, //tp_getset 0, //tp_base 0, //tp_dict 0, //tp_descr_get diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c index 7cfc1a7cde8..1871339d0b8 100644 --- a/source/blender/python/api2_2x/quat.c +++ b/source/blender/python/api2_2x/quat.c @@ -155,109 +155,13 @@ static void Quaternion_dealloc(QuaternionObject * self) } PyObject_DEL(self); } -//----------------------------getattr()(internal) ------------------ -//object.attribute access (get) -static PyObject *Quaternion_getattr(QuaternionObject * self, char *name) -{ - int x; - double mag = 0.0f; - float vec[3]; - if(STREQ(name,"w")){ - return PyFloat_FromDouble(self->quat[0]); - }else if(STREQ(name, "x")){ - return PyFloat_FromDouble(self->quat[1]); - }else if(STREQ(name, "y")){ - return PyFloat_FromDouble(self->quat[2]); - }else if(STREQ(name, "z")){ - return PyFloat_FromDouble(self->quat[3]); - } - if(STREQ(name, "magnitude")) { - for(x = 0; x < 4; x++) { - mag += self->quat[x] * self->quat[x]; - } - mag = sqrt(mag); - return PyFloat_FromDouble(mag); - } - if(STREQ(name, "angle")) { - mag = self->quat[0]; - mag = 2 * (saacos(mag)); - mag *= (180 / Py_PI); - return PyFloat_FromDouble(mag); - } - if(STREQ(name, "axis")) { - mag = self->quat[0] * (Py_PI / 180); - mag = 2 * (saacos(mag)); - mag = sin(mag / 2); - for(x = 0; x < 3; x++) { - vec[x] = (float)(self->quat[x + 1] / mag); - } - Normalize(vec); - //If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations - if( EXPP_FloatsAreEqual(vec[0], 0.0f, 10) && - EXPP_FloatsAreEqual(vec[1], 0.0f, 10) && - EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){ - vec[0] = 1.0f; - } - return (PyObject *) newVectorObject(vec, 3, Py_NEW); - } - if(STREQ(name, "wrapped")){ - if(self->wrapped == Py_WRAP) - return EXPP_incr_ret((PyObject *)Py_True); - else - return EXPP_incr_ret((PyObject *)Py_False); - } - - return Py_FindMethod(Quaternion_methods, (PyObject *) self, name); -} -//----------------------------setattr()(internal) ------------------ -//object.attribute access (set) -static int Quaternion_setattr(QuaternionObject * self, char *name, PyObject * q) -{ - PyObject *f = NULL; - - f = PyNumber_Float(q); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnIntError(PyExc_TypeError, - "quaternion.attribute = x: argument not a number\n"); - } - - if(STREQ(name,"w")){ - self->quat[0] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "x")){ - self->quat[1] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "y")){ - self->quat[2] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "z")){ - self->quat[3] = (float)PyFloat_AS_DOUBLE(f); - }else{ - Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_AttributeError, - "quaternion.attribute = x: unknown attribute\n"); - } - - Py_DECREF(f); - return 0; -} //----------------------------print object (internal)-------------- //print the object to screen static PyObject *Quaternion_repr(QuaternionObject * self) { - int i; - char buffer[48], str[1024]; - - BLI_strncpy(str,"[",1024); - for(i = 0; i < 4; i++){ - if(i < (3)){ - sprintf(buffer, "%.6f, ", self->quat[i]); - strcat(str,buffer); - }else{ - sprintf(buffer, "%.6f", self->quat[i]); - strcat(str,buffer); - } - } - strcat(str, "](quaternion)"); - + char str[64]; + sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]); return PyString_FromString(str); } //------------------------tp_richcmpr @@ -269,9 +173,9 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){ if (comparison_type == Py_NE){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } quatA = (QuaternionObject*)objectA; @@ -294,9 +198,9 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c break; } if (result == 1){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } //------------------------tp_doc @@ -576,6 +480,138 @@ static PyNumberMethods Quaternion_NumMethods = { (unaryfunc) 0, /* __hex__ */ }; + + +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; +} + +static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type ) +{ + float param= (float)PyFloat_AsDouble( value ); + + if (param==-1 && PyErr_Occurred()) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected a number for the vector axis" ); + + 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; +} + +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)); +} + +static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type ) +{ + double ang = self->quat[0]; + ang = 2 * (saacos(ang)); + ang *= (180 / Py_PI); + return PyFloat_FromDouble(ang); +} + +static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type ) +{ + int i; + float vec[3]; + double mag = self->quat[0] * (Py_PI / 180); + mag = 2 * (saacos(mag)); + mag = sin(mag / 2); + for(i = 0; i < 3; i++) + vec[i] = (float)(self->quat[i + 1] / mag); + + Normalize(vec); + //If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations + if( EXPP_FloatsAreEqual(vec[0], 0.0f, 10) && + EXPP_FloatsAreEqual(vec[1], 0.0f, 10) && + EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){ + vec[0] = 1.0f; + } + return (PyObject *) newVectorObject(vec, 3, Py_NEW); +} + + +/*****************************************************************************/ +/* Python attributes get/set structure: */ +/*****************************************************************************/ +static PyGetSetDef Quaternion_getseters[] = { + {"w", + (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, + "Quaternion W value", + (void *)'W'}, + {"x", + (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, + "Quaternion X axis", + (void *)'X'}, + {"y", + (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, + "Quaternion Y axis", + (void *)'Y'}, + {"z", + (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, + "Quaternion Z axis", + (void *)'Z'}, + {"magnitude", + (getter)Quaternion_getMagnitude, (setter)NULL, + "Size of the quaternion", + NULL}, + {"angle", + (getter)Quaternion_getAngle, (setter)NULL, + "angle of the quaternion", + NULL}, + {"axis", + (getter)Quaternion_getAxisVec, (setter)NULL, + "quaternion axis as a vector", + NULL}, + {"wrapped", + (getter)Quaternion_getWrapped, (setter)NULL, + "True when this wraps blenders internal data", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + + //------------------PY_OBECT DEFINITION-------------------------- PyTypeObject quaternion_Type = { PyObject_HEAD_INIT(NULL) //tp_head @@ -585,8 +621,8 @@ PyObject_HEAD_INIT(NULL) //tp_head 0, //tp_itemsize (destructor)Quaternion_dealloc, //tp_dealloc 0, //tp_print - (getattrfunc)Quaternion_getattr, //tp_getattr - (setattrfunc) Quaternion_setattr, //tp_setattr + 0, //tp_getattr + 0, //tp_setattr 0, //tp_compare (reprfunc) Quaternion_repr, //tp_repr &Quaternion_NumMethods, //tp_as_number @@ -606,9 +642,9 @@ PyObject_HEAD_INIT(NULL) //tp_head 0, //tp_weaklistoffset 0, //tp_iter 0, //tp_iternext - 0, //tp_methods + Quaternion_methods, //tp_methods 0, //tp_members - 0, //tp_getset + Quaternion_getseters, //tp_getset 0, //tp_base 0, //tp_dict 0, //tp_descr_get diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index fe28f0fac42..8f2e8991519 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -1026,14 +1026,12 @@ static PyObject *Vector_getAxis( VectorObject * self, void *type ) static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) { - float param; + float param= (float)PyFloat_AsDouble( value ); - if (!PyNumber_Check(value)) + if (param==-1 && PyErr_Occurred()) return EXPP_ReturnIntError( PyExc_TypeError, "expected a number for the vector axis" ); - param= (float)PyFloat_AsDouble( value ); - switch( (long)type ) { case 'X': /* these are backwards, but that how it works */ self->vec[0]= param; @@ -1054,13 +1052,6 @@ static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) self->vec[3]= param; break; - default: - { - char errstr[1024]; - sprintf( errstr, "undefined type '%d' in Vector_setAxis", - (int)((long)type & 0xff)); - return EXPP_ReturnIntError( PyExc_RuntimeError, errstr ); - } } return 0; @@ -1160,7 +1151,7 @@ static PyGetSetDef Vector_getseters[] = { NULL}, {"wrapped", (getter)Vector_getWrapped, (setter)NULL, - "Vector Length", + "True when this wraps blenders internal data", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h index 61b50d5f458..898e3947abd 100644 --- a/source/blender/python/api2_2x/vector.h +++ b/source/blender/python/api2_2x/vector.h @@ -34,7 +34,7 @@ extern PyTypeObject vector_Type; -#define VectorObject_Check(v) ((v)->ob_type == &vector_Type) +#define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type) typedef struct { PyObject_VAR_HEAD From 106b5a435c3f10666240fccf3b7d059d54e7be89 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 21 Apr 2009 09:20:47 +0000 Subject: [PATCH 008/444] BGE: show profile in millisecond in addition to percentage. --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 83a2fa8a448..4cfe3339631 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1401,7 +1401,7 @@ void KX_KetsjiEngine::RenderDebugProperties() m_canvas->GetWidth(), m_canvas->GetHeight()); double time = m_logger->GetAverage((KX_TimeCategory)j); - debugtxt.Format("%2.2f %%", time/tottime * 100.f); + debugtxt.Format("%.3fms (%2.2f %%)", time*1000.f, time/tottime * 100.f); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), xcoord + 60 ,ycoord, From 6c5e18ca98de0dfa2fd64c7a74258c207371298b Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 21 Apr 2009 09:38:27 +0000 Subject: [PATCH 009/444] Fix compilation error in MSVC. --- source/blender/python/api2_2x/BGL.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/python/api2_2x/BGL.c b/source/blender/python/api2_2x/BGL.c index ddb12eb2338..7735f2b444f 100644 --- a/source/blender/python/api2_2x/BGL.c +++ b/source/blender/python/api2_2x/BGL.c @@ -1101,15 +1101,14 @@ static struct PyModuleDef BGL_module_def = { PyObject *BGL_Init(const char *from) { - PyObject *mod; + PyObject *mod, *dict, *item; #if (PY_VERSION_HEX >= 0x03000000) mod = PyModule_Create(&BGL_module_def); #else mod= Py_InitModule(from, BGL_methods); #endif + dict= PyModule_GetDict(mod); - PyObject *dict= PyModule_GetDict(mod); - PyObject *item; if( PyType_Ready( &buffer_Type) < 0) return NULL; /* should never happen */ From 3e7cbd5388426a612b4066fbe7f2964c976fb23e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 09:44:29 +0000 Subject: [PATCH 010/444] Blender Python API - Removed the gen_utils.c dependency from Mathutils (since gen_utils wont go into 2.5 but mathutils will), repalced with python functions. - removed Blender.Mathutils.Point, since it was not documented, the C api never used it, none of our scripts used it (and I never saw a script that used it). --- source/blender/blenkernel/BKE_scene.h | 1 + source/blender/python/BPY_interface.c | 1 + source/blender/python/api2_2x/Geometry.h | 2 +- source/blender/python/api2_2x/Group.c | 2 +- source/blender/python/api2_2x/Key.c | 2 +- source/blender/python/api2_2x/Mathutils.c | 183 ++---- source/blender/python/api2_2x/Mathutils.h | 25 +- source/blender/python/api2_2x/Node.c | 2 +- source/blender/python/api2_2x/Scene.c | 2 +- source/blender/python/api2_2x/Texture.c | 2 +- source/blender/python/api2_2x/Types.c | 4 - source/blender/python/api2_2x/euler.c | 93 ++-- source/blender/python/api2_2x/gen_utils.c | 32 +- source/blender/python/api2_2x/gen_utils.h | 9 +- source/blender/python/api2_2x/matrix.c | 233 ++++---- source/blender/python/api2_2x/point.c | 523 ------------------ source/blender/python/api2_2x/point.h | 64 --- source/blender/python/api2_2x/quat.c | 97 ++-- source/blender/python/api2_2x/vector.c | 386 ++++++------- source/blender/python/api2_2x/vector.h | 1 - .../render/intern/source/convertblender.c | 1 - source/gameengine/Ketsji/CMakeLists.txt | 2 - source/gameengine/Ketsji/SConscript | 2 - 23 files changed, 467 insertions(+), 1202 deletions(-) delete mode 100644 source/blender/python/api2_2x/point.c delete mode 100644 source/blender/python/api2_2x/point.h diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 2c3ef42c021..647f7e95fd9 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -35,6 +35,7 @@ struct bglMats; struct Scene; struct Object; struct Base; +struct Text; struct AviCodecData; struct QuicktimeCodecData; struct SculptData; diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index ea3d6a54162..d86c317ee7e 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -70,6 +70,7 @@ #include "api2_2x/Object.h" #include "api2_2x/Registry.h" #include "api2_2x/Pose.h" +#include "api2_2x/Mathutils.h" #include "api2_2x/bpy.h" /* for the new "bpy" module */ #include "api2_2x/bpy_internal_import.h" diff --git a/source/blender/python/api2_2x/Geometry.h b/source/blender/python/api2_2x/Geometry.h index d7de9561078..e9e365cc9ae 100644 --- a/source/blender/python/api2_2x/Geometry.h +++ b/source/blender/python/api2_2x/Geometry.h @@ -32,7 +32,7 @@ #define EXPP_Geometry_H #include -#include "vector.h" +#include "Mathutils.h" PyObject *Geometry_Init( void ); diff --git a/source/blender/python/api2_2x/Group.c b/source/blender/python/api2_2x/Group.c index 0998053e7e1..eefa6fe58d6 100644 --- a/source/blender/python/api2_2x/Group.c +++ b/source/blender/python/api2_2x/Group.c @@ -46,7 +46,7 @@ #include "gen_utils.h" #include "gen_library.h" -#include "vector.h" +#include "Mathutils.h" /* checks for the group being removed */ #define GROUP_DEL_CHECK_PY(bpy_group) if (!(bpy_group->group)) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "Group has been removed" ) ) diff --git a/source/blender/python/api2_2x/Key.c b/source/blender/python/api2_2x/Key.c index 856dabdde74..45a68bfa0e6 100644 --- a/source/blender/python/api2_2x/Key.c +++ b/source/blender/python/api2_2x/Key.c @@ -29,7 +29,7 @@ */ #include "Key.h" /*This must come first*/ -#include "vector.h" +#include "Mathutils.h" #include "DNA_scene_types.h" diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index 605b5982137..c85d781f4dd 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -69,7 +69,6 @@ static char M_Mathutils_TriangleArea_doc[] = "(v1, v2, v3) - returns the area si static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined"; static char M_Mathutils_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined"; static char M_Mathutils_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other"; -static char M_Mathutils_Point_doc[] = "Creates a 2d or 3d point object"; //-----------------------METHOD DEFINITIONS ---------------------- struct PyMethodDef M_Mathutils_methods[] = { {"Rand", (PyCFunction) M_Mathutils_Rand, METH_VARARGS, M_Mathutils_Rand_doc}, @@ -103,7 +102,6 @@ struct PyMethodDef M_Mathutils_methods[] = { {"TriangleNormal", ( PyCFunction ) M_Mathutils_TriangleNormal, METH_VARARGS, M_Mathutils_TriangleNormal_doc}, {"QuadNormal", ( PyCFunction ) M_Mathutils_QuadNormal, METH_VARARGS, M_Mathutils_QuadNormal_doc}, {"LineIntersect", ( PyCFunction ) M_Mathutils_LineIntersect, METH_VARARGS, M_Mathutils_LineIntersect_doc}, - {"Point", (PyCFunction) M_Mathutils_Point, METH_VARARGS, M_Mathutils_Point_doc}, {NULL, NULL, 0, NULL} }; /*----------------------------MODULE INIT-------------------------*/ @@ -184,36 +182,7 @@ PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) } return newVectorObject(vecNew, vec->size, Py_NEW); } -//This is a helper for point/matrix translation -PyObject *column_point_multiplication(MatrixObject * mat, PointObject* pt) -{ - float ptNew[4], ptCopy[4]; - double dot = 0.0f; - int x, y, z = 0; - - if(mat->rowSize != pt->size){ - if(mat->rowSize == 4 && pt->size != 3){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "matrix * point: matrix row size and point size must be the same\n"); - }else{ - ptCopy[3] = 0.0f; - } - } - - for(x = 0; x < pt->size; x++){ - ptCopy[x] = pt->coord[x]; - } - - for(x = 0; x < mat->rowSize; x++) { - for(y = 0; y < mat->colSize; y++) { - dot += mat->matrix[x][y] * ptCopy[y]; - } - ptNew[z++] = (float)dot; - dot = 0.0f; - } - return newPointObject(ptNew, pt->size, Py_NEW); -} //-----------------row_vector_multiplication (internal)----------- //ROW VECTOR Multiplication - Vector X Matrix //[x][y][z] * [1][2][3] @@ -249,36 +218,7 @@ PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) } return newVectorObject(vecNew, vec_size, Py_NEW); } -//This is a helper for the point class -PyObject *row_point_multiplication(PointObject* pt, MatrixObject * mat) -{ - float ptNew[4], ptCopy[4]; - double dot = 0.0f; - int x, y, z = 0, size; - if(mat->colSize != pt->size){ - if(mat->rowSize == 4 && pt->size != 3){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "point * matrix: matrix column size and the point size must be the same\n"); - }else{ - ptCopy[3] = 0.0f; - } - } - size = pt->size; - for(x = 0; x < pt->size; x++){ - ptCopy[x] = pt->coord[x]; - } - - //muliplication - for(x = 0; x < mat->colSize; x++) { - for(y = 0; y < mat->rowSize; y++) { - dot += mat->matrix[y][x] * ptCopy[y]; - } - ptNew[z++] = (float)dot; - dot = 0.0f; - } - return newPointObject(ptNew, size, Py_NEW); -} //-----------------quat_rotation (internal)----------- //This function multiplies a vector/point * quat or vice versa //to rotate the point/vector by the quaternion @@ -288,7 +228,6 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) float rot[3]; QuaternionObject *quat = NULL; VectorObject *vec = NULL; - PointObject *pt = NULL; if(QuaternionObject_Check(arg1)){ quat = (QuaternionObject*)arg1; @@ -307,21 +246,6 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] - quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2]; return newVectorObject(rot, 3, Py_NEW); - }else if(PointObject_Check(arg2)){ - pt = (PointObject*)arg2; - rot[0] = quat->quat[0]*quat->quat[0]*pt->coord[0] + 2*quat->quat[2]*quat->quat[0]*pt->coord[2] - - 2*quat->quat[3]*quat->quat[0]*pt->coord[1] + quat->quat[1]*quat->quat[1]*pt->coord[0] + - 2*quat->quat[2]*quat->quat[1]*pt->coord[1] + 2*quat->quat[3]*quat->quat[1]*pt->coord[2] - - quat->quat[3]*quat->quat[3]*pt->coord[0] - quat->quat[2]*quat->quat[2]*pt->coord[0]; - rot[1] = 2*quat->quat[1]*quat->quat[2]*pt->coord[0] + quat->quat[2]*quat->quat[2]*pt->coord[1] + - 2*quat->quat[3]*quat->quat[2]*pt->coord[2] + 2*quat->quat[0]*quat->quat[3]*pt->coord[0] - - quat->quat[3]*quat->quat[3]*pt->coord[1] + quat->quat[0]*quat->quat[0]*pt->coord[1] - - 2*quat->quat[1]*quat->quat[0]*pt->coord[2] - quat->quat[1]*quat->quat[1]*pt->coord[1]; - rot[2] = 2*quat->quat[1]*quat->quat[3]*pt->coord[0] + 2*quat->quat[2]*quat->quat[3]*pt->coord[1] + - quat->quat[3]*quat->quat[3]*pt->coord[2] - 2*quat->quat[0]*quat->quat[2]*pt->coord[0] - - quat->quat[2]*quat->quat[2]*pt->coord[2] + 2*quat->quat[0]*quat->quat[1]*pt->coord[1] - - quat->quat[1]*quat->quat[1]*pt->coord[2] + quat->quat[0]*quat->quat[0]*pt->coord[2]; - return newPointObject(rot, 3, Py_NEW); } }else if(VectorObject_Check(arg1)){ vec = (VectorObject*)arg1; @@ -341,24 +265,6 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2]; return newVectorObject(rot, 3, Py_NEW); } - }else if(PointObject_Check(arg1)){ - pt = (PointObject*)arg1; - if(QuaternionObject_Check(arg2)){ - quat = (QuaternionObject*)arg2; - rot[0] = quat->quat[0]*quat->quat[0]*pt->coord[0] + 2*quat->quat[2]*quat->quat[0]*pt->coord[2] - - 2*quat->quat[3]*quat->quat[0]*pt->coord[1] + quat->quat[1]*quat->quat[1]*pt->coord[0] + - 2*quat->quat[2]*quat->quat[1]*pt->coord[1] + 2*quat->quat[3]*quat->quat[1]*pt->coord[2] - - quat->quat[3]*quat->quat[3]*pt->coord[0] - quat->quat[2]*quat->quat[2]*pt->coord[0]; - rot[1] = 2*quat->quat[1]*quat->quat[2]*pt->coord[0] + quat->quat[2]*quat->quat[2]*pt->coord[1] + - 2*quat->quat[3]*quat->quat[2]*pt->coord[2] + 2*quat->quat[0]*quat->quat[3]*pt->coord[0] - - quat->quat[3]*quat->quat[3]*pt->coord[1] + quat->quat[0]*quat->quat[0]*pt->coord[1] - - 2*quat->quat[1]*quat->quat[0]*pt->coord[2] - quat->quat[1]*quat->quat[1]*pt->coord[1]; - rot[2] = 2*quat->quat[1]*quat->quat[3]*pt->coord[0] + 2*quat->quat[2]*quat->quat[3]*pt->coord[1] + - quat->quat[3]*quat->quat[3]*pt->coord[2] - 2*quat->quat[0]*quat->quat[2]*pt->coord[0] - - quat->quat[2]*quat->quat[2]*pt->coord[2] + 2*quat->quat[0]*quat->quat[1]*pt->coord[1] - - quat->quat[1]*quat->quat[1]*pt->coord[2] + quat->quat[0]*quat->quat[0]*pt->coord[2]; - return newPointObject(rot, 3, Py_NEW); - } } return (EXPP_ReturnPyObjError(PyExc_RuntimeError, @@ -1329,60 +1235,7 @@ PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args) Py_DECREF(listObject); return newEulerObject(eul, Py_NEW); } -//----------------------------------POINT FUNCTIONS--------------------- -//----------------------------------Mathutils.Point() ------------------ -PyObject *M_Mathutils_Point(PyObject * self, PyObject * args) -{ - PyObject *listObject = NULL; - int size, i; - float point[3]; - PyObject *v, *f; - size = PySequence_Length(args); - if (size == 1) { - listObject = PySequence_GetItem(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - } else { // Single argument was not a sequence - Py_XDECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Point(): 2-3 floats or ints expected (optionally in a sequence)\n"); - } - } else if (size == 0) { - //returns a new empty 3d point - return newPointObject(NULL, 3, Py_NEW); - } else { - listObject = EXPP_incr_ret(args); - } - - if (size<2 || size>3) { // Invalid vector size - Py_XDECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Point(): 2-3 floats or ints expected (optionally in a sequence)\n"); - } - - for (i=0; i 0 && floatSteps < (4 * 1024 * 1024)); + a = *(int*)&A; + if (a < 0) + a = 0x80000000 - a; + b = *(int*)&B; + if (b < 0) + b = 0x80000000 - b; + delta = abs(a - b); + if (delta <= floatSteps) + return 1; + return 0; +} +/*---------------------- EXPP_VectorsAreEqual ------------------------- + Builds on EXPP_FloatsAreEqual to test vectors */ +int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ + + int x; + for (x=0; x< size; x++){ + if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) + return 0; + } + return 1; +} + + + //####################################################################### //#############################DEPRECATED################################ diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index 0db83216178..d3d3354d42f 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -36,13 +36,10 @@ #include "matrix.h" #include "quat.h" #include "euler.h" -#include "point.h" PyObject *Mathutils_Init( const char * from ); PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); -PyObject *row_point_multiplication(PointObject* pt, MatrixObject * mat); -PyObject *column_point_multiplication(MatrixObject * mat, PointObject* pt); PyObject *quat_rotation(PyObject *arg1, PyObject *arg2); PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args); @@ -69,7 +66,6 @@ PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ); PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ); PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ); PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ); -PyObject *M_Mathutils_Point(PyObject * self, PyObject * args); //DEPRECATED PyObject *M_Mathutils_CopyMat(PyObject * self, PyObject * args); PyObject *M_Mathutils_CopyVec(PyObject * self, PyObject * args); @@ -79,4 +75,25 @@ PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args); PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args); PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args); +int EXPP_FloatsAreEqual(float A, float B, int floatSteps); +int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); + + +#define Py_PI 3.14159265358979323846 +#define Py_WRAP 1024 +#define Py_NEW 2048 + + +/* Allow us to build with Py3k */ +#if (PY_VERSION_HEX >= 0x03000000) +#define PyString_FromString PyUnicode_FromString +#define intobjargproc ssizeobjargproc +#define intintobjargproc ssizessizeobjargproc +#define intargfunc ssizeargfunc +#define intintargfunc ssizessizeargfunc + + +#endif + + #endif /* EXPP_Mathutils_H */ diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c index 792b2331508..813f5999678 100644 --- a/source/blender/python/api2_2x/Node.c +++ b/source/blender/python/api2_2x/Node.c @@ -40,7 +40,7 @@ #include "BLI_blenlib.h" #include "gen_utils.h" -#include "vector.h" +#include "Mathutils.h" static PyObject *Node_repr( BPy_Node * self ); static int Node_compare(BPy_Node *a, BPy_Node *b); diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 8a2be2391a4..6d10205c0e3 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -85,7 +85,7 @@ struct View3D; #include "BKE_utildefines.h" /* vec copy */ -#include "vector.h" +#include "Mathutils.h" PyObject *M_Object_Get( PyObject * self, PyObject * args ); /* from Object.c */ diff --git a/source/blender/python/api2_2x/Texture.c b/source/blender/python/api2_2x/Texture.c index 51e1c389528..455badef4ad 100644 --- a/source/blender/python/api2_2x/Texture.c +++ b/source/blender/python/api2_2x/Texture.c @@ -53,7 +53,7 @@ #include "gen_utils.h" #include "gen_library.h" -#include "vector.h" /* for Texture_evaluate(vec) */ +#include "Mathutils.h" /* for Texture_evaluate(vec) */ #include "Material.h" /* for EXPP_Colorband_fromPyList and EXPP_PyList_fromColorband */ #include "RE_shader_ext.h" diff --git a/source/blender/python/api2_2x/Types.c b/source/blender/python/api2_2x/Types.c index 10b968cacba..65d816ac7b0 100644 --- a/source/blender/python/api2_2x/Types.c +++ b/source/blender/python/api2_2x/Types.c @@ -60,7 +60,6 @@ extern PyTypeObject World_Type; extern PyTypeObject property_Type; extern PyTypeObject buffer_Type, constant_Type, euler_Type; extern PyTypeObject matrix_Type, quaternion_Type, rgbTuple_Type, vector_Type; -extern PyTypeObject point_Type; extern PyTypeObject Modifier_Type, ModSeq_Type; extern PyTypeObject EditBone_Type; extern PyTypeObject ThemeSpace_Type; @@ -246,7 +245,6 @@ void types_InitAll( void ) PyType_Ready( &rgbTuple_Type ); vector_Type.ob_type = &PyType_Type; property_Type.ob_type = &PyType_Type; - point_Type.ob_type = &PyType_Type; PyType_Ready( &Modifier_Type ); PyType_Ready( &ModSeq_Type ); PyType_Ready( &EditBone_Type ); @@ -358,8 +356,6 @@ PyObject *Types_Init( void ) ( PyObject * ) &Pose_Type ); PyDict_SetItemString( dict, "propertyType", ( PyObject * ) &property_Type ); - PyDict_SetItemString( dict, "pointType", - ( PyObject * ) &point_Type ); PyDict_SetItemString( dict, "ModifierType", ( PyObject * ) &Modifier_Type ); PyDict_SetItemString( dict, "ModSeqType", diff --git a/source/blender/python/api2_2x/euler.c b/source/blender/python/api2_2x/euler.c index 52f1e00221e..23f82fc0eb0 100644 --- a/source/blender/python/api2_2x/euler.c +++ b/source/blender/python/api2_2x/euler.c @@ -31,7 +31,6 @@ #include "BLI_arithb.h" #include "BKE_utildefines.h" #include "BLI_blenlib.h" -#include "gen_utils.h" //-------------------------DOC STRINGS --------------------------- @@ -128,7 +127,8 @@ PyObject *Euler_Unique(EulerObject * self) self->eul[1] = (float)(pitch * 180 / (float)Py_PI); self->eul[2] = (float)(bank * 180 / (float)Py_PI); - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject *)self; } //----------------------------Euler.zero()------------------------- //sets the euler to 0,0,0 @@ -138,7 +138,8 @@ PyObject *Euler_Zero(EulerObject * self) self->eul[1] = 0.0; self->eul[2] = 0.0; - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject *)self; } //----------------------------Euler.rotate()----------------------- //rotates a euler a certain amount and returns the result @@ -150,12 +151,12 @@ PyObject *Euler_Rotate(EulerObject * self, PyObject *args) int x; if(!PyArg_ParseTuple(args, "fs", &angle, &axis)){ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "euler.rotate():expected angle (float) and axis (x,y,z)"); + PyErr_SetString(PyExc_TypeError, "euler.rotate():expected angle (float) and axis (x,y,z)"); + return NULL; } if(!STREQ3(axis,"x","y","z")){ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "euler.rotate(): expected axis to be 'x', 'y' or 'z'"); + PyErr_SetString(PyExc_TypeError, "euler.rotate(): expected axis to be 'x', 'y' or 'z'"); + return NULL; } //covert to radians @@ -169,7 +170,8 @@ PyObject *Euler_Rotate(EulerObject * self, PyObject *args) self->eul[x] *= (180 / (float)Py_PI); } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject *)self; } //----------------------------Euler.rotate()----------------------- // return a copy of the euler @@ -207,9 +209,9 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar if (!EulerObject_Check(objectA) || !EulerObject_Check(objectB)){ if (comparison_type == Py_NE){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } eulA = (EulerObject*)objectA; @@ -232,9 +234,9 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar break; } if (result == 1){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } //------------------------tp_doc @@ -250,32 +252,36 @@ static int Euler_len(EulerObject * self) //sequence accessor (get) static PyObject *Euler_item(EulerObject * self, int i) { - if(i < 0 || i >= 3) - return EXPP_ReturnPyObjError(PyExc_IndexError, - "euler[attribute]: array index out of range\n"); - + if(i<0) + i= 3-i; + + if(i < 0 || i >= 3) { + PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range"); + return NULL; + } return PyFloat_FromDouble(self->eul[i]); } //----------------------------object[]------------------------- //sequence accessor (set) -static int Euler_ass_item(EulerObject * self, int i, PyObject * ob) +static int Euler_ass_item(EulerObject * self, int i, PyObject * value) { - PyObject *f = NULL; + float f = PyFloat_AsDouble(value); - f = PyNumber_Float(ob); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnIntError(PyExc_TypeError, - "euler[attribute] = x: argument not a number\n"); + if(f == -1 && PyErr_Occurred()) { // parsed item not a number + PyErr_SetString(PyExc_TypeError, "euler[attribute] = x: argument not a number"); + return -1; } + if(i<0) + i= 3-i; + if(i < 0 || i >= 3){ - Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_IndexError, - "euler[attribute] = x: array assignment index out of range\n"); + PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n"); + return -1; } - self->eul[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + + self->eul[i] = f; return 0; } //----------------------------object[z:y]------------------------ @@ -314,26 +320,27 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end, size = PySequence_Length(seq); if(size != (end - begin)){ - return EXPP_ReturnIntError(PyExc_TypeError, - "euler[begin:end] = []: size mismatch in slice assignment\n"); + PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: size mismatch in slice assignment"); + return -1; } for (i = 0; i < size; i++) { e = PySequence_GetItem(seq, i); if (e == NULL) { // Failed to read sequence - return EXPP_ReturnIntError(PyExc_RuntimeError, - "euler[begin:end] = []: unable to read sequence\n"); + PyErr_SetString(PyExc_RuntimeError, "euler[begin:end] = []: unable to read sequence"); + return -1; } f = PyNumber_Float(e); if(f == NULL) { // parsed item not a number Py_DECREF(e); - return EXPP_ReturnIntError(PyExc_TypeError, - "euler[begin:end] = []: sequence argument not a number\n"); + PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number"); + return -1; } eul[i] = (float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(f,e); + Py_DECREF(f); + Py_DECREF(e); } //parsed well - now set in vector for(y = 0; y < 3; y++){ @@ -377,9 +384,10 @@ static int Euler_setAxis( EulerObject * self, PyObject * value, void * type ) { float param= (float)PyFloat_AsDouble( value ); - if (param==-1 && PyErr_Occurred()) - return EXPP_ReturnIntError( PyExc_TypeError, - "expected a number for the vector axis" ); + 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 */ @@ -430,8 +438,13 @@ static PyGetSetDef Euler_getseters[] = { //------------------PY_OBECT DEFINITION-------------------------- PyTypeObject euler_Type = { - PyObject_HEAD_INIT(NULL) //tp_head - 0, //tp_internal +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "euler", //tp_name sizeof(EulerObject), //tp_basicsize 0, //tp_itemsize @@ -513,6 +526,6 @@ PyObject *newEulerObject(float *eul, int type) }else{ //bad type return NULL; } - return (PyObject *) self; + return (PyObject *)self; } diff --git a/source/blender/python/api2_2x/gen_utils.c b/source/blender/python/api2_2x/gen_utils.c index de3704164ac..53ace2759a2 100644 --- a/source/blender/python/api2_2x/gen_utils.c +++ b/source/blender/python/api2_2x/gen_utils.c @@ -42,36 +42,6 @@ #include "constant.h" -/*---------------------- EXPP_FloatsAreEqual ------------------------- - Floating point comparisons - floatStep = number of representable floats allowable in between - float A and float B to be considered equal. */ -int EXPP_FloatsAreEqual(float A, float B, int floatSteps) -{ - int a, b, delta; - assert(floatSteps > 0 && floatSteps < (4 * 1024 * 1024)); - a = *(int*)&A; - if (a < 0) - a = 0x80000000 - a; - b = *(int*)&B; - if (b < 0) - b = 0x80000000 - b; - delta = abs(a - b); - if (delta <= floatSteps) - return 1; - return 0; -} -/*---------------------- EXPP_VectorsAreEqual ------------------------- - Builds on EXPP_FloatsAreEqual to test vectors */ -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ - - int x; - for (x=0; x< size; x++){ - if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) - return 0; - } - return 1; -} /*---------------------- EXPP_GetModuleConstant ------------------------- Helper function for returning a module constant */ PyObject *EXPP_GetModuleConstant(char *module, char *constant) @@ -781,7 +751,7 @@ int EXPP_setModuleConstant ( BPy_constant *constant, void *param, char type ) { PyObject *item; - if( constant->ob_type != &constant_Type ) + if( ((PyObject *)constant)->ob_type != &constant_Type ) return EXPP_ReturnIntError( PyExc_TypeError, "expected module constant" ); diff --git a/source/blender/python/api2_2x/gen_utils.h b/source/blender/python/api2_2x/gen_utils.h index f33dc69d703..3486b265949 100644 --- a/source/blender/python/api2_2x/gen_utils.h +++ b/source/blender/python/api2_2x/gen_utils.h @@ -37,9 +37,9 @@ #include "constant.h" -#define Py_PI 3.14159265358979323846 -#define Py_WRAP 1024 -#define Py_NEW 2048 +// #define Py_PI 3.14159265358979323846 +// #define Py_WRAP 1024 +// #define Py_NEW 2048 /* Py_RETURN_NONE @@ -77,9 +77,6 @@ typedef int Py_ssize_t; /* name of list of Armature weak refs built into __main__ */ #define ARM_WEAKREF_LIST_NAME "__arm_weakrefs" -int EXPP_FloatsAreEqual(float A, float B, int floatSteps); -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); - PyObject *EXPP_GetModuleConstant(char *module, char *constant); int StringEqual( const char *string1, const char *string2 ); diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c index 7802de822cb..a8816ae4baa 100644 --- a/source/blender/python/api2_2x/matrix.c +++ b/source/blender/python/api2_2x/matrix.c @@ -30,7 +30,6 @@ #include "BKE_utildefines.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" -#include "gen_utils.h" /*-------------------------DOC STRINGS ---------------------------*/ char Matrix_Zero_doc[] = "() - set all values in the matrix to 0"; @@ -70,8 +69,8 @@ PyObject *Matrix_toQuat(MatrixObject * self) /*must be 3-4 cols, 3-4 rows, square matrix*/ if(self->colSize < 3 || self->rowSize < 3 || (self->colSize != self->rowSize)) { - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.toQuat(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.toQuat(): inappropriate matrix size - expects 3x3 or 4x4 matrix"); + return NULL; } if(self->colSize == 3){ Mat3ToQuat((float (*)[3])*self->matrix, quat); @@ -95,10 +94,10 @@ PyObject *Matrix_toEuler(MatrixObject * self) float tempmat3[3][3]; Mat3CpyMat4(tempmat3, (float (*)[4])*self->matrix); Mat3ToEul(tempmat3, eul); - }else - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); - + }else { + PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); + return NULL; + } /*have to convert to degrees*/ for(x = 0; x < 3; x++) { eul[x] *= (float) (180 / Py_PI); @@ -111,20 +110,20 @@ PyObject *Matrix_Resize4x4(MatrixObject * self) int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index; if(self->data.blend_data){ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "cannot resize wrapped data - only python matrices\n"); + PyErr_SetString(PyExc_TypeError, "cannot resize wrapped data - only python matrices"); + return NULL; } self->data.py_data = PyMem_Realloc(self->data.py_data, (sizeof(float) * 16)); if(self->data.py_data == NULL) { - return EXPP_ReturnPyObjError(PyExc_MemoryError, - "matrix.resize4x4(): problem allocating pointer space\n\n"); + PyErr_SetString(PyExc_MemoryError, "matrix.resize4x4(): problem allocating pointer space"); + return NULL; } self->contigPtr = self->data.py_data; /*force*/ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float *) * 4)); if(self->matrix == NULL) { - return EXPP_ReturnPyObjError(PyExc_MemoryError, - "matrix.resize4x4(): problem allocating pointer space\n\n"); + PyErr_SetString(PyExc_MemoryError, "matrix.resize4x4(): problem allocating pointer space"); + return NULL; } /*set row pointers*/ for(x = 0; x < 4; x++) { @@ -155,7 +154,9 @@ PyObject *Matrix_Resize4x4(MatrixObject * self) } self->rowSize = 4; self->colSize = 4; - return EXPP_incr_ret((PyObject*)self); + + Py_INCREF(self); + return (PyObject *)self; } /*---------------------------Matrix.translationPart() ------------*/ PyObject *Matrix_TranslationPart(MatrixObject * self) @@ -163,8 +164,8 @@ PyObject *Matrix_TranslationPart(MatrixObject * self) float vec[4]; if(self->colSize < 3 || self->rowSize < 4){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.translationPart: inappropriate matrix size\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.translationPart: inappropriate matrix size"); + return NULL; } vec[0] = self->matrix[3][0]; @@ -180,8 +181,8 @@ PyObject *Matrix_RotationPart(MatrixObject * self) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; if(self->colSize < 3 || self->rowSize < 3){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.rotationPart: inappropriate matrix size\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.rotationPart: inappropriate matrix size\n"); + return NULL; } mat[0] = self->matrix[0][0]; @@ -207,10 +208,10 @@ PyObject *Matrix_scalePart(MatrixObject * self) Mat3CpyMat4(mat, (float (*)[4])*self->matrix); else if(self->colSize == 3 && self->rowSize == 3) Mat3CpyMat3(mat, (float (*)[3])*self->matrix); - else - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.scalePart(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); - + else { + PyErr_SetString(PyExc_AttributeError, "Matrix.scalePart(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); + return NULL; + } /* functionality copied from editobject.c apply_obmat */ Mat3ToEul(mat, rot); EulToMat3(rot, tmat); @@ -233,8 +234,8 @@ PyObject *Matrix_Invert(MatrixObject * self) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; if(self->rowSize != self->colSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.invert(ed): only square matrices are supported\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.invert(ed): only square matrices are supported"); + return NULL; } /*calculate the determinant*/ @@ -268,10 +269,12 @@ PyObject *Matrix_Invert(MatrixObject * self) /*transpose Matrix_Transpose(self);*/ } else { - return EXPP_ReturnPyObjError(PyExc_ValueError, - "matrix does not have an inverse"); + PyErr_SetString(PyExc_ValueError, "matrix does not have an inverse"); + return NULL; } - return EXPP_incr_ret((PyObject*)self); + + Py_INCREF(self); + return (PyObject *)self; } @@ -281,8 +284,8 @@ PyObject *Matrix_Determinant(MatrixObject * self) float det = 0.0f; if(self->rowSize != self->colSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.determinant: only square matrices are supported\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.determinant: only square matrices are supported"); + return NULL; } if(self->rowSize == 2) { @@ -306,8 +309,8 @@ PyObject *Matrix_Transpose(MatrixObject * self) float t = 0.0f; if(self->rowSize != self->colSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.transpose(d): only square matrices are supported\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.transpose(d): only square matrices are supported"); + return NULL; } if(self->rowSize == 2) { @@ -320,7 +323,8 @@ PyObject *Matrix_Transpose(MatrixObject * self) Mat4Transp((float (*)[4])*self->matrix); } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject *)self; } @@ -334,14 +338,15 @@ PyObject *Matrix_Zero(MatrixObject * self) self->matrix[row][col] = 0.0f; } } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject *)self; } /*---------------------------Matrix.identity(() ------------------*/ PyObject *Matrix_Identity(MatrixObject * self) { if(self->rowSize != self->colSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix.identity: only square matrices are supported\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix.identity: only square matrices are supported\n"); + return NULL; } if(self->rowSize == 2) { @@ -355,7 +360,8 @@ PyObject *Matrix_Identity(MatrixObject * self) Mat4One((float (*)[4]) *self->matrix); } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject *)self; } /*---------------------------Matrix.inverted() ------------------*/ @@ -387,9 +393,9 @@ static PyObject *Matrix_getattr(MatrixObject * self, char *name) } if(STREQ(name, "wrapped")){ if(self->wrapped == Py_WRAP) - return EXPP_incr_ret((PyObject *)Py_True); + Py_RETURN_TRUE; else - return EXPP_incr_ret((PyObject *)Py_False); + Py_RETURN_FALSE; } return Py_FindMethod(Matrix_methods, (PyObject *) self, name); } @@ -435,9 +441,9 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa if (!MatrixObject_Check(objectA) || !MatrixObject_Check(objectB)){ if (comparison_type == Py_NE){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } matA = (MatrixObject*)objectA; @@ -445,9 +451,9 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa if (matA->colSize != matB->colSize || matA->rowSize != matB->rowSize){ if (comparison_type == Py_NE){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } @@ -471,9 +477,9 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa break; } if (result == 1){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } /*------------------------tp_doc*/ @@ -490,10 +496,10 @@ 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(i < 0 || i >= self->rowSize) - return EXPP_ReturnPyObjError(PyExc_IndexError, - "matrix[attribute]: array index out of range\n"); - + if(i < 0 || i >= self->rowSize) { + PyErr_SetString(PyExc_IndexError, "matrix[attribute]: array index out of range"); + return NULL; + } return newVectorObject(self->matrix[i], self->colSize, Py_WRAP); } /*----------------------------object[]------------------------- @@ -505,32 +511,33 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) PyObject *m, *f; if(i >= self->rowSize || i < 0){ - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[attribute] = x: bad row\n"); + PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad row\n"); + return -1; } if(PySequence_Check(ob)){ size = PySequence_Length(ob); if(size != self->colSize){ - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[attribute] = x: bad sequence size\n"); + PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad sequence size\n"); + return -1; } for (x = 0; x < size; x++) { m = PySequence_GetItem(ob, x); if (m == NULL) { /*Failed to read sequence*/ - return EXPP_ReturnIntError(PyExc_RuntimeError, - "matrix[attribute] = x: unable to read sequence\n"); + PyErr_SetString(PyExc_RuntimeError, "matrix[attribute] = x: unable to read sequence\n"); + return -1; } f = PyNumber_Float(m); if(f == NULL) { /*parsed item not a number*/ Py_DECREF(m); - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[attribute] = x: sequence argument not a number\n"); + PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: sequence argument not a number\n"); + return -1; } vec[x] = (float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(m, f); + Py_DECREF(m); + Py_DECREF(f); } /*parsed well - now set in matrix*/ for(y = 0; y < size; y++){ @@ -538,8 +545,8 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) } return 0; }else{ - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[attribute] = x: expects a sequence of column size\n"); + PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size\n"); + return -1; } } /*----------------------------object[z:y]------------------------ @@ -579,16 +586,16 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, if(PySequence_Check(seq)){ size = PySequence_Length(seq); if(size != (end - begin)){ - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[begin:end] = []: size mismatch in slice assignment\n"); + PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: size mismatch in slice assignment\n"); + return -1; } /*parse sub items*/ for (i = 0; i < size; i++) { /*parse each sub sequence*/ subseq = PySequence_GetItem(seq, i); if (subseq == NULL) { /*Failed to read sequence*/ - return EXPP_ReturnIntError(PyExc_RuntimeError, - "matrix[begin:end] = []: unable to read sequence\n"); + PyErr_SetString(PyExc_RuntimeError, "matrix[begin:end] = []: unable to read sequence"); + return -1; } if(PySequence_Check(subseq)){ @@ -596,31 +603,33 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, sub_size = PySequence_Length(subseq); if(sub_size != self->colSize){ Py_DECREF(subseq); - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[begin:end] = []: size mismatch in slice assignment\n"); + PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: size mismatch in slice assignment\n"); + return -1; } for (y = 0; y < sub_size; y++) { m = PySequence_GetItem(subseq, y); if (m == NULL) { /*Failed to read sequence*/ Py_DECREF(subseq); - return EXPP_ReturnIntError(PyExc_RuntimeError, - "matrix[begin:end] = []: unable to read sequence\n"); + PyErr_SetString(PyExc_RuntimeError, "matrix[begin:end] = []: unable to read sequence\n"); + return -1; } f = PyNumber_Float(m); if(f == NULL) { /*parsed item not a number*/ - EXPP_decr2(m, subseq); - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[begin:end] = []: sequence argument not a number\n"); + Py_DECREF(m); + Py_DECREF(subseq); + PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: sequence argument not a number\n"); + return -1; } mat[(i * self->colSize) + y] = (float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(f, m); + Py_DECREF(m); + Py_DECREF(subseq); } }else{ Py_DECREF(subseq); - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[begin:end] = []: illegal argument type for built-in operation\n"); + PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n"); + return -1; } Py_DECREF(subseq); } @@ -630,8 +639,8 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, } return 0; }else{ - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix[begin:end] = []: illegal argument type for built-in operation\n"); + PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n"); + return -1; } } /*------------------------NUMERIC PROTOCOLS---------------------- @@ -647,12 +656,12 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2) mat2 = (MatrixObject*)m2; if(mat1->coerced_object || mat2->coerced_object){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix addition: arguments not valid for this operation....\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); + return NULL; } if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix addition: matrices must have the same dimensions for this operation\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); + return NULL; } for(x = 0; x < mat1->rowSize; x++) { @@ -676,12 +685,12 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2) mat2 = (MatrixObject*)m2; if(mat1->coerced_object || mat2->coerced_object){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix addition: arguments not valid for this operation....\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); + return NULL; } if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix addition: matrices must have the same dimensions for this operation\n"); + PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); + return NULL; } for(x = 0; x < mat1->rowSize; x++) { @@ -703,7 +712,6 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) double dot = 0.0f; MatrixObject *mat1 = NULL, *mat2 = NULL; PyObject *f = NULL; - PointObject *pt = NULL; mat1 = (MatrixObject*)m1; mat2 = (MatrixObject*)m2; @@ -713,8 +721,8 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) PyInt_Check(mat1->coerced_object)){ /*FLOAT/INT * MATRIX*/ f = PyNumber_Float(mat1->coerced_object); if(f == NULL) { /*parsed item not a number*/ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Matrix multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); + return NULL; } scalar = (float)PyFloat_AS_DOUBLE(f); @@ -733,15 +741,11 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) vec = (VectorObject*)mat2->coerced_object; return column_vector_multiplication(mat1, vec); }else */ - if(PointObject_Check(mat2->coerced_object)){ /*MATRIX * POINT*/ - pt = (PointObject*)mat2->coerced_object; - return column_point_multiplication(mat1, pt); - }else if (PyFloat_Check(mat2->coerced_object) || - PyInt_Check(mat2->coerced_object)){ /*MATRIX * FLOAT/INT*/ + if (PyFloat_Check(mat2->coerced_object) || PyInt_Check(mat2->coerced_object)){ /*MATRIX * FLOAT/INT*/ f = PyNumber_Float(mat2->coerced_object); if(f == NULL) { /*parsed item not a number*/ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Matrix multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation\n"); + return NULL; } scalar = (float)PyFloat_AS_DOUBLE(f); @@ -755,8 +759,8 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } }else{ /*MATRIX * MATRIX*/ if(mat1->colSize != mat2->rowSize){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Matrix multiplication: matrix A rowsize must equal matrix B colsize\n"); + PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize"); + return NULL; } for(x = 0; x < mat1->rowSize; x++) { for(y = 0; y < mat2->colSize; y++) { @@ -771,8 +775,8 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } } - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Matrix multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation\n"); + return NULL; } static PyObject* Matrix_inv(MatrixObject *self) { @@ -789,17 +793,17 @@ static PyObject* Matrix_inv(MatrixObject *self) then call vector.multiply(vector, scalar_cast_as_vector)*/ static int Matrix_coerce(PyObject ** m1, PyObject ** m2) { - if(VectorObject_Check(*m2) || PyFloat_Check(*m2) || PyInt_Check(*m2) || - PointObject_Check(*m2)) { - PyObject *coerced = EXPP_incr_ret(*m2); + if(VectorObject_Check(*m2) || PyFloat_Check(*m2) || PyInt_Check(*m2)) { + PyObject *coerced = (PyObject *)(*m2); + Py_INCREF(coerced); *m2 = newMatrixObject(NULL,3,3,Py_NEW); ((MatrixObject*)*m2)->coerced_object = coerced; Py_INCREF (*m1); return 0; } - return EXPP_ReturnIntError(PyExc_TypeError, - "matrix.coerce(): unknown operand - can't coerce for numeric protocols"); + PyErr_SetString(PyExc_TypeError, "matrix.coerce(): unknown operand - can't coerce for numeric protocols"); + return -1; } /*-----------------PROTOCOL DECLARATIONS--------------------------*/ static PySequenceMethods Matrix_SeqMethods = { @@ -838,8 +842,13 @@ static PyNumberMethods Matrix_NumMethods = { }; /*------------------PY_OBECT DEFINITION--------------------------*/ PyTypeObject matrix_Type = { - PyObject_HEAD_INIT(NULL) /*tp_head*/ - 0, /*tp_internal*/ +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "matrix", /*tp_name*/ sizeof(MatrixObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -910,8 +919,8 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) /*matrix objects can be any 2-4row x 2-4col matrix*/ if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4){ - return EXPP_ReturnPyObjError(PyExc_RuntimeError, - "matrix(): row and column sizes must be between 2 and 4\n"); + PyErr_SetString(PyExc_RuntimeError, "matrix(): row and column sizes must be between 2 and 4"); + return NULL; } self = PyObject_NEW(MatrixObject, &matrix_Type); @@ -927,8 +936,8 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) /*create pointer array*/ self->matrix = PyMem_Malloc(rowSize * sizeof(float *)); if(self->matrix == NULL) { /*allocation failure*/ - return EXPP_ReturnPyObjError( PyExc_MemoryError, - "matrix(): problem allocating pointer space\n"); + PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space"); + return NULL; } /*pointer array points to contigous memory*/ for(x = 0; x < rowSize; x++) { @@ -938,16 +947,16 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) }else if (type == Py_NEW){ self->data.py_data = PyMem_Malloc(rowSize * colSize * sizeof(float)); if(self->data.py_data == NULL) { /*allocation failure*/ - return EXPP_ReturnPyObjError( PyExc_MemoryError, - "matrix(): problem allocating pointer space\n"); + PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space\n"); + return NULL; } self->contigPtr = self->data.py_data; /*create pointer array*/ self->matrix = PyMem_Malloc(rowSize * sizeof(float *)); if(self->matrix == NULL) { /*allocation failure*/ PyMem_Free(self->data.py_data); - return EXPP_ReturnPyObjError( PyExc_MemoryError, - "matrix(): problem allocating pointer space\n"); + PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space"); + return NULL; } /*pointer array points to contigous memory*/ for(x = 0; x < rowSize; x++) { diff --git a/source/blender/python/api2_2x/point.c b/source/blender/python/api2_2x/point.c deleted file mode 100644 index 0bdedfecdd6..00000000000 --- a/source/blender/python/api2_2x/point.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** -*/ -#include "Mathutils.h" - -#include "BLI_blenlib.h" -#include "BKE_utildefines.h" -#include "gen_utils.h" - -//-------------------------DOC STRINGS --------------------------- -char Point_Zero_doc[] = "() - set all values in the point to 0"; -char Point_toVector_doc[] = "() - create a vector representation of this point"; -//-----------------------METHOD DEFINITIONS ---------------------- -struct PyMethodDef Point_methods[] = { - {"zero", (PyCFunction) Point_Zero, METH_NOARGS, Point_Zero_doc}, - {"toVector", (PyCFunction) Point_toVector, METH_NOARGS, Point_toVector_doc}, - {NULL, NULL, 0, NULL} -}; -//-----------------------------METHODS---------------------------- -//--------------------------Vector.toPoint()---------------------- -//create a new point object to represent this vector -PyObject *Point_toVector(PointObject * self) -{ - float vec[3]; - int x; - - for(x = 0; x < self->size; x++){ - vec[x] = self->coord[x]; - } - - return newVectorObject(vec, self->size, Py_NEW); -} -//----------------------------Point.zero() ---------------------- -//set the point data to 0,0,0 -PyObject *Point_Zero(PointObject * self) -{ - int x; - for(x = 0; x < self->size; x++) { - self->coord[x] = 0.0f; - } - return EXPP_incr_ret((PyObject*)self); -} -//----------------------------dealloc()(internal) ---------------- -//free the py_object -static void Point_dealloc(PointObject * self) -{ - Py_XDECREF(self->coerced_object); - //only free py_data - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); -} -//----------------------------getattr()(internal) ---------------- -//object.attribute access (get) -static PyObject *Point_getattr(PointObject * self, char *name) -{ - if(STREQ(name,"x")){ - return PyFloat_FromDouble(self->coord[0]); - }else if(STREQ(name, "y")){ - return PyFloat_FromDouble(self->coord[1]); - }else if(STREQ(name, "z")){ - if(self->size > 2){ - return PyFloat_FromDouble(self->coord[2]); - }else{ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "point.z: illegal attribute access\n"); - } - } - if(STREQ(name, "wrapped")){ - if(self->wrapped == Py_WRAP) - return EXPP_incr_ret((PyObject *)Py_True); - else - return EXPP_incr_ret((PyObject *)Py_False); - } - return Py_FindMethod(Point_methods, (PyObject *) self, name); -} -//----------------------------setattr()(internal) ---------------- -//object.attribute access (set) -static int Point_setattr(PointObject * self, char *name, PyObject * v) -{ - PyObject *f = NULL; - - f = PyNumber_Float(v); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnIntError(PyExc_TypeError, - "point.attribute = x: argument not a number\n"); - } - - if(STREQ(name,"x")){ - self->coord[0] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "y")){ - self->coord[1] = (float)PyFloat_AS_DOUBLE(f); - }else if(STREQ(name, "z")){ - if(self->size > 2){ - self->coord[2] = (float)PyFloat_AS_DOUBLE(f); - }else{ - Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_AttributeError, - "point.z = x: illegal attribute access\n"); - } - }else{ - Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_AttributeError, - "point.attribute = x: unknown attribute\n"); - } - - Py_DECREF(f); - return 0; -} -//----------------------------print object (internal)------------- -//print the object to screen -static PyObject *Point_repr(PointObject * self) -{ - int i; - char buffer[48], str[1024]; - - BLI_strncpy(str,"[",1024); - for(i = 0; i < self->size; i++){ - if(i < (self->size - 1)){ - sprintf(buffer, "%.6f, ", self->coord[i]); - strcat(str,buffer); - }else{ - sprintf(buffer, "%.6f", self->coord[i]); - strcat(str,buffer); - } - } - strcat(str, "](point)"); - - return PyString_FromString(str); -} -//---------------------SEQUENCE PROTOCOLS------------------------ -//----------------------------len(object)------------------------ -//sequence length -static int Point_len(PointObject * self) -{ - return self->size; -} -//----------------------------object[]--------------------------- -//sequence accessor (get) -static PyObject *Point_item(PointObject * self, int i) -{ - if(i < 0 || i >= self->size) - return EXPP_ReturnPyObjError(PyExc_IndexError, - "point[attribute]: array index out of range\n"); - - return PyFloat_FromDouble( (double)self->coord[i] ); - -} -//----------------------------object[]------------------------- -//sequence accessor (set) -static int Point_ass_item(PointObject * self, int i, PyObject * ob) -{ - PyObject *f = NULL; - - f = PyNumber_Float(ob); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnIntError(PyExc_TypeError, - "point[attribute] = x: argument not a number\n"); - } - - if(i < 0 || i >= self->size){ - Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_IndexError, - "point[attribute] = x: array assignment index out of range\n"); - } - self->coord[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - return 0; -} -//----------------------------object[z:y]------------------------ -//sequence slice (get) -static PyObject *Point_slice(PointObject * self, int begin, int end) -{ - PyObject *list = NULL; - int count; - - CLAMP(begin, 0, self->size); - CLAMP(end, 0, self->size); - begin = MIN2(begin,end); - - list = PyList_New(end - begin); - for(count = begin; count < end; count++) { - PyList_SetItem(list, count - begin, - PyFloat_FromDouble(self->coord[count])); - } - - return list; -} -//----------------------------object[z:y]------------------------ -//sequence slice (set) -static int Point_ass_slice(PointObject * self, int begin, int end, - PyObject * seq) -{ - int i, y, size = 0; - float coord[3]; - PyObject *v, *f; - - CLAMP(begin, 0, self->size); - CLAMP(end, 0, self->size); - begin = MIN2(begin,end); - - size = PySequence_Length(seq); - if(size != (end - begin)){ - return EXPP_ReturnIntError(PyExc_TypeError, - "point[begin:end] = []: size mismatch in slice assignment\n"); - } - - for (i = 0; i < size; i++) { - v = PySequence_GetItem(seq, i); - if (v == NULL) { // Failed to read sequence - return EXPP_ReturnIntError(PyExc_RuntimeError, - "point[begin:end] = []: unable to read sequence\n"); - } - f = PyNumber_Float(v); - if(f == NULL) { // parsed item not a number - Py_DECREF(v); - return EXPP_ReturnIntError(PyExc_TypeError, - "point[begin:end] = []: sequence argument not a number\n"); - } - - coord[i] = (float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(f,v); - } - //parsed well - now set in point - for(y = 0; y < size; y++){ - self->coord[begin + y] = coord[y]; - } - return 0; -} -//------------------------NUMERIC PROTOCOLS---------------------- -//------------------------obj + obj------------------------------ -//addition -static PyObject *Point_add(PyObject * v1, PyObject * v2) -{ - int x, size; - float coord[3]; - PointObject *coord1 = NULL, *coord2 = NULL; - VectorObject *vec = NULL; - - coord1 = (PointObject*)v1; - coord2 = (PointObject*)v2; - - if(!coord1->coerced_object){ - if(coord2->coerced_object){ - if(VectorObject_Check(coord2->coerced_object)){ //POINT + VECTOR - //Point translation - vec = (VectorObject*)coord2->coerced_object; - size = coord1->size; - if(vec->size == size){ - for(x = 0; x < size; x++){ - coord[x] = coord1->coord[x] + vec->vec[x]; - } - }else{ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Point addition: arguments are the wrong size....\n"); - } - return newPointObject(coord, size, Py_NEW); - } - }else{ //POINT + POINT - size = coord1->size; - if(coord2->size == size){ - for(x = 0; x < size; x++) { - coord[x] = coord1->coord[x] + coord2->coord[x]; - } - }else{ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Point addition: arguments are the wrong size....\n"); - } - return newPointObject(coord, size, Py_NEW); - } - } - - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Point addition: arguments not valid for this operation....\n"); -} -//------------------------obj - obj------------------------------ -//subtraction -static PyObject *Point_sub(PyObject * v1, PyObject * v2) -{ - int x, size; - float coord[3]; - PointObject *coord1 = NULL, *coord2 = NULL; - - coord1 = (PointObject*)v1; - coord2 = (PointObject*)v2; - - if(coord1->coerced_object || coord2->coerced_object){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Point subtraction: arguments not valid for this operation....\n"); - } - if(coord1->size != coord2->size){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Point subtraction: points must have the same dimensions for this operation\n"); - } - - size = coord1->size; - for(x = 0; x < size; x++) { - coord[x] = coord1->coord[x] - coord2->coord[x]; - } - - //Point - Point = Vector - return newVectorObject(coord, size, Py_NEW); -} -//------------------------obj * obj------------------------------ -//mulplication -static PyObject *Point_mul(PyObject * p1, PyObject * p2) -{ - int x, size; - float coord[3], scalar; - PointObject *coord1 = NULL, *coord2 = NULL; - PyObject *f = NULL; - MatrixObject *mat = NULL; - QuaternionObject *quat = NULL; - - coord1 = (PointObject*)p1; - coord2 = (PointObject*)p2; - - if(coord1->coerced_object){ - if (PyFloat_Check(coord1->coerced_object) || - PyInt_Check(coord1->coerced_object)){ // FLOAT/INT * POINT - f = PyNumber_Float(coord1->coerced_object); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Point multiplication: arguments not acceptable for this operation\n"); - } - - scalar = (float)PyFloat_AS_DOUBLE(f); - size = coord2->size; - for(x = 0; x < size; x++) { - coord[x] = coord2->coord[x] * scalar; - } - Py_DECREF(f); - return newPointObject(coord, size, Py_NEW); - } - }else{ - if(coord2->coerced_object){ - if (PyFloat_Check(coord2->coerced_object) || - PyInt_Check(coord2->coerced_object)){ // POINT * FLOAT/INT - f = PyNumber_Float(coord2->coerced_object); - if(f == NULL) { // parsed item not a number - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Point multiplication: arguments not acceptable for this operation\n"); - } - - scalar = (float)PyFloat_AS_DOUBLE(f); - size = coord1->size; - for(x = 0; x < size; x++) { - coord[x] = coord1->coord[x] * scalar; - } - Py_DECREF(f); - return newPointObject(coord, size, Py_NEW); - }else if(MatrixObject_Check(coord2->coerced_object)){ //POINT * MATRIX - mat = (MatrixObject*)coord2->coerced_object; - return row_point_multiplication(coord1, mat); - }else if(QuaternionObject_Check(coord2->coerced_object)){ //POINT * QUATERNION - quat = (QuaternionObject*)coord2->coerced_object; - if(coord1->size != 3){ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Point multiplication: only 3D point rotations (with quats) currently supported\n"); - } - return quat_rotation((PyObject*)coord1, (PyObject*)quat); - } - } - } - - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Point multiplication: arguments not acceptable for this operation\n"); -} -//-------------------------- -obj ------------------------------- -//returns the negative of this object -static PyObject *Point_neg(PointObject *self) -{ - int x; - float coord[3]; - - for(x = 0; x < self->size; x++) - coord[x] = -self->coord[x]; - - return newPointObject(coord, self->size, Py_NEW); -} - -//------------------------coerce(obj, obj)----------------------- -//coercion of unknown types to type PointObject for numeric protocols -/*Coercion() is called whenever a math operation has 2 operands that - it doesn't understand how to evaluate. 2+Matrix for example. We want to - evaluate some of these operations like: (vector * 2), however, for math - to proceed, the unknown operand must be cast to a type that python math will - understand. (e.g. in the case above case, 2 must be cast to a vector and - then call vector.multiply(vector, scalar_cast_as_vector)*/ -static int Point_coerce(PyObject ** p1, PyObject ** p2) -{ - if(VectorObject_Check(*p2) || PyFloat_Check(*p2) || PyInt_Check(*p2) || - MatrixObject_Check(*p2) || QuaternionObject_Check(*p2)) { - PyObject *coerced = EXPP_incr_ret(*p2); - *p2 = newPointObject(NULL,3,Py_NEW); - ((PointObject*)*p2)->coerced_object = coerced; - Py_INCREF (*p1); - return 0; - } - - return EXPP_ReturnIntError(PyExc_TypeError, - "point.coerce(): unknown operand - can't coerce for numeric protocols"); -} -//-----------------PROTOCOL DECLARATIONS-------------------------- -static PySequenceMethods Point_SeqMethods = { - (inquiry) Point_len, /* sq_length */ - (binaryfunc) 0, /* sq_concat */ - (intargfunc) 0, /* sq_repeat */ - (intargfunc) Point_item, /* sq_item */ - (intintargfunc) Point_slice, /* sq_slice */ - (intobjargproc) Point_ass_item, /* sq_ass_item */ - (intintobjargproc) Point_ass_slice, /* sq_ass_slice */ -}; -static PyNumberMethods Point_NumMethods = { - (binaryfunc) Point_add, /* __add__ */ - (binaryfunc) Point_sub, /* __sub__ */ - (binaryfunc) Point_mul, /* __mul__ */ - (binaryfunc) 0, /* __div__ */ - (binaryfunc) 0, /* __mod__ */ - (binaryfunc) 0, /* __divmod__ */ - (ternaryfunc) 0, /* __pow__ */ - (unaryfunc) Point_neg, /* __neg__ */ - (unaryfunc) 0, /* __pos__ */ - (unaryfunc) 0, /* __abs__ */ - (inquiry) 0, /* __nonzero__ */ - (unaryfunc) 0, /* __invert__ */ - (binaryfunc) 0, /* __lshift__ */ - (binaryfunc) 0, /* __rshift__ */ - (binaryfunc) 0, /* __and__ */ - (binaryfunc) 0, /* __xor__ */ - (binaryfunc) 0, /* __or__ */ - (coercion) Point_coerce, /* __coerce__ */ - (unaryfunc) 0, /* __int__ */ - (unaryfunc) 0, /* __long__ */ - (unaryfunc) 0, /* __float__ */ - (unaryfunc) 0, /* __oct__ */ - (unaryfunc) 0, /* __hex__ */ - -}; -//------------------PY_OBECT DEFINITION-------------------------- -PyTypeObject point_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size */ - "point", /*tp_name */ - sizeof(PointObject), /*tp_basicsize */ - 0, /*tp_itemsize */ - (destructor) Point_dealloc, /*tp_dealloc */ - (printfunc) 0, /*tp_print */ - (getattrfunc) Point_getattr, /*tp_getattr */ - (setattrfunc) Point_setattr, /*tp_setattr */ - 0, /*tp_compare */ - (reprfunc) Point_repr, /*tp_repr */ - &Point_NumMethods, /*tp_as_number */ - &Point_SeqMethods, /*tp_as_sequence */ -}; -//------------------------newPointObject (internal)------------- -//creates a new point object -/*pass Py_WRAP - if point is a WRAPPER for data allocated by BLENDER - (i.e. it was allocated elsewhere by MEM_mallocN()) - pass Py_NEW - if point is not a WRAPPER and managed by PYTHON - (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newPointObject(float *coord, int size, int type) -{ - PointObject *self; - int x; - - point_Type.ob_type = &PyType_Type; - self = PyObject_NEW(PointObject, &point_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; - if(size > 3 || size < 2) - return NULL; - self->size = size; - self->coerced_object = NULL; - - if(type == Py_WRAP){ - self->data.blend_data = coord; - self->coord = self->data.blend_data; - self->wrapped = Py_WRAP; - }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(size * sizeof(float)); - self->coord = self->data.py_data; - if(!coord) { //new empty - for(x = 0; x < size; x++){ - self->coord[x] = 0.0f; - } - }else{ - for(x = 0; x < size; x++){ - self->coord[x] = coord[x]; - } - } - self->wrapped = Py_NEW; - }else{ //bad type - return NULL; - } - return (PyObject *) self; -} diff --git a/source/blender/python/api2_2x/point.h b/source/blender/python/api2_2x/point.h deleted file mode 100644 index a9c4e5e4e2c..00000000000 --- a/source/blender/python/api2_2x/point.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Joseph Gilbert - * - * ***** END GPL LICENSE BLOCK ***** -*/ - -#ifndef EXPP_point_h -#define EXPP_point_h - -#include - -extern PyTypeObject point_Type; - -#define PointObject_Check(v) ((v)->ob_type == &point_Type) - -typedef struct { - PyObject_VAR_HEAD - struct{ - float *py_data; //python managed - float *blend_data; //blender managed - }data; - float *coord; //1D array of data (alias) - int size; - int wrapped; //is wrapped data? - PyObject *coerced_object; -} PointObject; -/*coerced_object is a pointer to the object that it was -coerced from when a dummy vector needs to be created from -the coerce() function for numeric protocol operations*/ - -/*struct data contains a pointer to the actual data that the -object uses. It can use either PyMem allocated data (which will -be stored in py_data) or be a wrapper for data allocated through -blender (stored in blend_data). This is an either/or struct not both*/ - -//prototypes -PyObject *Point_Zero( PointObject * self ); -PyObject *Point_toVector(PointObject * self); -PyObject *newPointObject(float *coord, int size, int type); - -#endif /* EXPP_point_h */ diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c index 1871339d0b8..9c718d95c63 100644 --- a/source/blender/python/api2_2x/quat.c +++ b/source/blender/python/api2_2x/quat.c @@ -31,7 +31,6 @@ #include "BLI_arithb.h" #include "BKE_utildefines.h" #include "BLI_blenlib.h" -#include "gen_utils.h" //-------------------------DOC STRINGS --------------------------- @@ -84,7 +83,8 @@ PyObject *Quaternion_ToMatrix(QuaternionObject * self) PyObject *Quaternion_Normalize(QuaternionObject * self) { NormalQuat(self->quat); - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } //----------------------------Quaternion.inverse()------------------ //invert the quat @@ -104,7 +104,8 @@ PyObject *Quaternion_Inverse(QuaternionObject * self) self->quat[x] /= (float)(mag * mag); } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } //----------------------------Quaternion.identity()----------------- //generate the identity quaternion @@ -115,7 +116,8 @@ PyObject *Quaternion_Identity(QuaternionObject * self) self->quat[2] = 0.0; self->quat[3] = 0.0; - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } //----------------------------Quaternion.negate()------------------- //negate the quat @@ -125,7 +127,8 @@ PyObject *Quaternion_Negate(QuaternionObject * self) for(x = 0; x < 4; x++) { self->quat[x] = -self->quat[x]; } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } //----------------------------Quaternion.conjugate()---------------- //negate the vector part @@ -135,7 +138,8 @@ PyObject *Quaternion_Conjugate(QuaternionObject * self) for(x = 1; x < 4; x++) { self->quat[x] = -self->quat[x]; } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } //----------------------------Quaternion.copy()---------------- //return a copy of the quat @@ -216,9 +220,10 @@ static int Quaternion_len(QuaternionObject * self) //sequence accessor (get) static PyObject *Quaternion_item(QuaternionObject * self, int i) { - if(i < 0 || i >= 4) - return EXPP_ReturnPyObjError(PyExc_IndexError, - "quaternion[attribute]: array index out of range\n"); + if(i < 0 || i >= 4) { + PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range\n"); + return NULL; + } return PyFloat_FromDouble(self->quat[i]); } @@ -230,14 +235,14 @@ static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob) f = PyNumber_Float(ob); if(f == NULL) { // parsed item not a number - return EXPP_ReturnIntError(PyExc_TypeError, - "quaternion[attribute] = x: argument not a number\n"); + PyErr_SetString(PyExc_TypeError, "quaternion[attribute] = x: argument not a number\n"); + return -1; } if(i < 0 || i >= 4){ Py_DECREF(f); - return EXPP_ReturnIntError(PyExc_IndexError, - "quaternion[attribute] = x: array assignment index out of range\n"); + 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); @@ -279,26 +284,27 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, size = PySequence_Length(seq); if(size != (end - begin)){ - return EXPP_ReturnIntError(PyExc_TypeError, - "quaternion[begin:end] = []: size mismatch in slice assignment\n"); + PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: size mismatch in slice assignment\n"); + return -1; } for (i = 0; i < size; i++) { q = PySequence_GetItem(seq, i); if (q == NULL) { // Failed to read sequence - return EXPP_ReturnIntError(PyExc_RuntimeError, - "quaternion[begin:end] = []: unable to read sequence\n"); + PyErr_SetString(PyExc_RuntimeError, "quaternion[begin:end] = []: unable to read sequence\n"); + return -1; } f = PyNumber_Float(q); if(f == NULL) { // parsed item not a number Py_DECREF(q); - return EXPP_ReturnIntError(PyExc_TypeError, - "quaternion[begin:end] = []: sequence argument not a number\n"); + PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: sequence argument not a number\n"); + return -1; } quat[i] = (float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(f,q); + Py_DECREF(f); + Py_DECREF(q); } //parsed well - now set in vector for(y = 0; y < size; y++){ @@ -319,8 +325,8 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2) quat2 = (QuaternionObject*)q2; if(quat1->coerced_object || quat2->coerced_object){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Quaternion addition: arguments not valid for this operation....\n"); + PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n"); + return NULL; } for(x = 0; x < 4; x++) { quat[x] = quat1->quat[x] + quat2->quat[x]; @@ -340,8 +346,8 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2) quat2 = (QuaternionObject*)q2; if(quat1->coerced_object || quat2->coerced_object){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Quaternion addition: arguments not valid for this operation....\n"); + PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n"); + return NULL; } for(x = 0; x < 4; x++) { quat[x] = quat1->quat[x] - quat2->quat[x]; @@ -359,7 +365,6 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) QuaternionObject *quat1 = NULL, *quat2 = NULL; PyObject *f = NULL; VectorObject *vec = NULL; - PointObject *pt = NULL; quat1 = (QuaternionObject*)q1; quat2 = (QuaternionObject*)q2; @@ -369,8 +374,8 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) PyInt_Check(quat1->coerced_object)){ // FLOAT/INT * QUAT f = PyNumber_Float(quat1->coerced_object); if(f == NULL) { // parsed item not a number - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Quaternion multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n"); + return NULL; } scalar = (float)PyFloat_AS_DOUBLE(f); @@ -386,8 +391,8 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) PyInt_Check(quat2->coerced_object)){ // QUAT * FLOAT/INT f = PyNumber_Float(quat2->coerced_object); if(f == NULL) { // parsed item not a number - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Quaternion multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n"); + return NULL; } scalar = (float)PyFloat_AS_DOUBLE(f); @@ -399,17 +404,10 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) }else if(VectorObject_Check(quat2->coerced_object)){ //QUAT * VEC vec = (VectorObject*)quat2->coerced_object; if(vec->size != 3){ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Quaternion multiplication: only 3D vector rotations currently supported\n"); + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n"); + return NULL; } return quat_rotation((PyObject*)quat1, (PyObject*)vec); - }else if(PointObject_Check(quat2->coerced_object)){ //QUAT * POINT - pt = (PointObject*)quat2->coerced_object; - if(pt->size != 3){ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Quaternion multiplication: only 3D point rotations currently supported\n"); - } - return quat_rotation((PyObject*)quat1, (PyObject*)pt); } }else{ //QUAT * QUAT (dot product) for(x = 0; x < 4; x++) { @@ -419,8 +417,8 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) } } - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Quaternion multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n"); + return NULL; } //------------------------coerce(obj, obj)----------------------- //coercion of unknown types to type QuaternionObject for numeric protocols @@ -432,17 +430,18 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) then call vector.multiply(vector, scalar_cast_as_vector)*/ static int Quaternion_coerce(PyObject ** q1, PyObject ** q2) { - if(VectorObject_Check(*q2) || PyFloat_Check(*q2) || PyInt_Check(*q2) || - PointObject_Check(*q2)) { - PyObject *coerced = EXPP_incr_ret(*q2); + if(VectorObject_Check(*q2) || PyFloat_Check(*q2) || PyInt_Check(*q2)) { + PyObject *coerced = (PyObject *)(*q2); + Py_INCREF(coerced); + *q2 = newQuaternionObject(NULL,Py_NEW); ((QuaternionObject*)*q2)->coerced_object = coerced; Py_INCREF (*q1); return 0; } - return EXPP_ReturnIntError(PyExc_TypeError, - "quaternion.coerce(): unknown operand - can't coerce for numeric protocols"); + PyErr_SetString(PyExc_TypeError, "quaternion.coerce(): unknown operand - can't coerce for numeric protocols"); + return -1; } //-----------------PROTOCOL DECLARATIONS-------------------------- static PySequenceMethods Quaternion_SeqMethods = { @@ -503,10 +502,10 @@ static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * { float param= (float)PyFloat_AsDouble( value ); - if (param==-1 && PyErr_Occurred()) - return EXPP_ReturnIntError( PyExc_TypeError, - "expected a number for the vector axis" ); - + 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; diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index 8f2e8991519..f65c4dff600 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -30,7 +30,6 @@ #include "BLI_blenlib.h" #include "BKE_utildefines.h" #include "BLI_arithb.h" -#include "gen_utils.h" /*-------------------------DOC STRINGS ---------------------------*/ @@ -40,7 +39,6 @@ char Vector_Negate_doc[] = "() - changes vector to it's additive inverse"; char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; -char Vector_toPoint_doc[] = "() - create a new Point Object from this vector"; char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; char Vector_reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; char Vector_copy_doc[] = "() - return a copy of the vector"; @@ -52,7 +50,6 @@ struct PyMethodDef Vector_methods[] = { {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, Vector_Resize2D_doc}, {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, - {"toPoint", (PyCFunction) Vector_toPoint, METH_NOARGS, Vector_toPoint_doc}, {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, {"reflect", ( PyCFunction ) Vector_reflect, METH_O, Vector_reflect_doc}, {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, @@ -61,23 +58,6 @@ struct PyMethodDef Vector_methods[] = { }; /*-----------------------------METHODS---------------------------- - --------------------------Vector.toPoint()---------------------- - create a new point object to represent this vector */ -PyObject *Vector_toPoint(VectorObject * self) -{ - float coord[3]; - int i; - - if(self->size < 2 || self->size > 3) { - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector.toPoint(): inappropriate vector size - expects 2d or 3d vector\n"); - } - for(i = 0; i < self->size; i++){ - coord[i] = self->vec[i]; - } - - return newPointObject(coord, self->size, Py_NEW); -} /*----------------------------Vector.zero() ---------------------- set the vector data to 0,0,0 */ PyObject *Vector_Zero(VectorObject * self) @@ -86,7 +66,8 @@ PyObject *Vector_Zero(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] = 0.0f; } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } /*----------------------------Vector.normalize() ----------------- normalize the vector data to a unit vector */ @@ -102,7 +83,8 @@ PyObject *Vector_Normalize(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] /= norm; } - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } @@ -110,50 +92,54 @@ PyObject *Vector_Normalize(VectorObject * self) resize the vector to x,y */ PyObject *Vector_Resize2D(VectorObject * self) { - if(self->wrapped==Py_WRAP) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "vector.resize2d(): cannot resize wrapped data - only python vectors\n"); - + if(self->wrapped==Py_WRAP) { + PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n"); + return NULL; + } self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2)); - if(self->vec == NULL) - return EXPP_ReturnPyObjError(PyExc_MemoryError, - "vector.resize2d(): problem allocating pointer space\n\n"); + if(self->vec == NULL) { + PyErr_SetString(PyExc_MemoryError, "vector.resize2d(): problem allocating pointer space\n\n"); + return NULL; + } self->size = 2; - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } /*----------------------------Vector.resize3D() ------------------ resize the vector to x,y,z */ PyObject *Vector_Resize3D(VectorObject * self) { - if (self->wrapped==Py_WRAP) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "vector.resize3d(): cannot resize wrapped data - only python vectors\n"); - + if (self->wrapped==Py_WRAP) { + PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n"); + return NULL; + } self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3)); - if(self->vec == NULL) - return EXPP_ReturnPyObjError(PyExc_MemoryError, - "vector.resize3d(): problem allocating pointer space\n\n"); + if(self->vec == NULL) { + PyErr_SetString(PyExc_MemoryError, "vector.resize3d(): problem allocating pointer space\n\n"); + return NULL; + } if(self->size == 2) self->vec[2] = 0.0f; self->size = 3; - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } /*----------------------------Vector.resize4D() ------------------ resize the vector to x,y,z,w */ PyObject *Vector_Resize4D(VectorObject * self) { - if(self->wrapped==Py_WRAP) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "vector.resize4d(): cannot resize wrapped data - only python vectors\n"); - + if(self->wrapped==Py_WRAP) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors"); + return NULL; + } self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4)); - if(self->vec == NULL) - return EXPP_ReturnPyObjError(PyExc_MemoryError, - "vector.resize4d(): problem allocating pointer space\n\n"); - + if(self->vec == NULL) { + PyErr_SetString(PyExc_MemoryError, "vector.resize4d(): problem allocating pointer space\n\n"); + return NULL; + } if(self->size == 2){ self->vec[2] = 0.0f; self->vec[3] = 1.0f; @@ -161,7 +147,8 @@ PyObject *Vector_Resize4D(VectorObject * self) self->vec[3] = 1.0f; } self->size = 4; - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } /*----------------------------Vector.toTrackQuat(track, up) ---------------------- extract a quaternion from the vector and the track and up axis */ @@ -172,11 +159,12 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) short track = 2, up = 1; if( !PyArg_ParseTuple ( args, "|ss", &strack, &sup ) ) { - return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected optional two strings\n" ); + PyErr_SetString( PyExc_TypeError, "expected optional two strings\n" ); + return NULL; } if (self->size != 3) { - return EXPP_ReturnPyObjError( PyExc_TypeError, "only for 3D vectors\n" ); + PyErr_SetString( PyExc_TypeError, "only for 3D vectors\n" ); + return NULL; } if (strack) { @@ -196,13 +184,13 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) track = 5; break; default: - return EXPP_ReturnPyObjError( PyExc_ValueError, - "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + PyErr_SetString( PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + return NULL; } } else { - return EXPP_ReturnPyObjError( PyExc_ValueError, - "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + PyErr_SetString( PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + return NULL; } } else if (strlen(strack) == 1) { @@ -221,13 +209,13 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) track = 2; break; default: - return EXPP_ReturnPyObjError( PyExc_ValueError, - "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + PyErr_SetString( PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + return NULL; } } else { - return EXPP_ReturnPyObjError( PyExc_ValueError, - "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + PyErr_SetString( PyExc_ValueError, "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + return NULL; } } @@ -247,19 +235,19 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) up = 2; break; default: - return EXPP_ReturnPyObjError( PyExc_ValueError, - "only X, Y or Z for up axis\n" ); + PyErr_SetString( PyExc_ValueError, "only X, Y or Z for up axis\n" ); + return NULL; } } else { - return EXPP_ReturnPyObjError( PyExc_ValueError, - "only X, Y or Z for up axis\n" ); + PyErr_SetString( PyExc_ValueError, "only X, Y or Z for up axis\n" ); + return NULL; } } if (track == up) { - return EXPP_ReturnPyObjError( PyExc_ValueError, - "Can't have the same axis for track and up\n" ); + PyErr_SetString( PyExc_ValueError, "Can't have the same axis for track and up\n" ); + return NULL; } /* @@ -291,9 +279,10 @@ PyObject *Vector_reflect( VectorObject * self, PyObject * value ) int i; float norm = 0.0f; - if (!VectorObject_Check(value)) - return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a vector argument" ); - + if (!VectorObject_Check(value)) { + PyErr_SetString( PyExc_TypeError, "expected a vector argument" ); + return NULL; + } mirrvec = (VectorObject *)value; mirror[0] = mirrvec->vec[0]; @@ -375,9 +364,10 @@ static int Vector_len(VectorObject * self) sequence accessor (get)*/ static PyObject *Vector_item(VectorObject * self, int i) { - if(i < 0 || i >= self->size) - return EXPP_ReturnPyObjError(PyExc_IndexError, - "vector[index]: out of range\n"); + if(i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError,"vector[index]: out of range\n"); + return NULL; + } return PyFloat_FromDouble(self->vec[i]); @@ -388,13 +378,13 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob) { if(!(PyNumber_Check(ob))) { /* parsed item not a number */ - return EXPP_ReturnIntError(PyExc_TypeError, - "vector[index] = x: index argument not a number\n"); + PyErr_SetString(PyExc_TypeError, "vector[index] = x: index argument not a number\n"); + return -1; } if(i < 0 || i >= self->size){ - return EXPP_ReturnIntError(PyExc_IndexError, - "vector[index] = x: assignment index out of range\n"); + PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n"); + return -1; } self->vec[i] = (float)PyFloat_AsDouble(ob); return 0; @@ -436,21 +426,21 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, size = PySequence_Length(seq); if(size != (end - begin)){ - return EXPP_ReturnIntError(PyExc_TypeError, - "vector[begin:end] = []: size mismatch in slice assignment\n"); + PyErr_SetString(PyExc_TypeError, "vector[begin:end] = []: size mismatch in slice assignment\n"); + return -1; } for (i = 0; i < size; i++) { v = PySequence_GetItem(seq, i); if (v == NULL) { /* Failed to read sequence */ - return EXPP_ReturnIntError(PyExc_RuntimeError, - "vector[begin:end] = []: unable to read sequence\n"); + PyErr_SetString(PyExc_RuntimeError, "vector[begin:end] = []: unable to read sequence\n"); + return -1; } if(!PyNumber_Check(v)) { /* parsed item not a number */ Py_DECREF(v); - return EXPP_ReturnIntError(PyExc_TypeError, - "vector[begin:end] = []: sequence argument not a number\n"); + PyErr_SetString(PyExc_TypeError, "vector[begin:end] = []: sequence argument not a number\n"); + return -1; } vec[i] = (float)PyFloat_AsDouble(v); @@ -481,33 +471,18 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { /*VECTOR + VECTOR*/ - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector addition: vectors must have the same dimensions for this operation\n"); - + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); + return NULL; + } for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] + vec2->vec[i]; } return newVectorObject(vec, vec1->size, Py_NEW); } - if(PointObject_Check(v2)){ /*VECTOR + POINT*/ - /*Point translation*/ - PointObject *pt = (PointObject*)v2; - - if(pt->size == vec1->size){ - for(i = 0; i < vec1->size; i++){ - vec[i] = vec1->vec[i] + pt->coord[i]; - } - }else{ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector addition: arguments are the wrong size....\n"); - } - return newPointObject(vec, vec1->size, Py_NEW); - } - - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector addition: arguments not valid for this operation....\n"); + PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); + return NULL; } /* ------------------------obj += obj------------------------------ @@ -527,10 +502,10 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { /*VECTOR + VECTOR*/ - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector addition: vectors must have the same dimensions for this operation\n"); - + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); + return NULL; + } for(i = 0; i < vec1->size; i++) { vec1->vec[i] += vec2->vec[i]; } @@ -538,24 +513,8 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) return v1; } - if(PointObject_Check(v2)){ /*VECTOR + POINT*/ - /*Point translation*/ - PointObject *pt = (PointObject*)v2; - - if(pt->size == vec1->size){ - for(i = 0; i < vec1->size; i++){ - vec1->vec[i] += pt->coord[i]; - } - }else{ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector addition: arguments are the wrong size....\n"); - } - Py_INCREF( v1 ); - return v1; - } - - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector addition: arguments not valid for this operation....\n"); + PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); + return NULL; } /*------------------------obj - obj------------------------------ @@ -566,17 +525,17 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) float vec[4]; VectorObject *vec1 = NULL, *vec2 = NULL; - if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector subtraction: arguments not valid for this operation....\n"); - + if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { + PyErr_SetString(PyExc_AttributeError, "Vector subtraction: arguments not valid for this operation....\n"); + return NULL; + } vec1 = (VectorObject*)v1; vec2 = (VectorObject*)v2; - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector subtraction: vectors must have the same dimensions for this operation\n"); - + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); + return NULL; + } for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] - vec2->vec[i]; } @@ -591,16 +550,17 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) int i, size; VectorObject *vec1 = NULL, *vec2 = NULL; - if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector subtraction: arguments not valid for this operation....\n"); - + if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { + PyErr_SetString(PyExc_AttributeError, "Vector subtraction: arguments not valid for this operation....\n"); + return NULL; + } vec1 = (VectorObject*)v1; vec2 = (VectorObject*)v2; - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector subtraction: vectors must have the same dimensions for this operation\n"); + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); + return NULL; + } size = vec1->size; for(i = 0; i < vec1->size; i++) { @@ -628,9 +588,10 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) int i; double dot = 0.0f; - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Vector multiplication: vectors must have the same dimensions for this operation\n"); + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Vector multiplication: vectors must have the same dimensions for this operation\n"); + return NULL; + } /*dot product*/ for(i = 0; i < vec1->size; i++) { @@ -664,15 +625,15 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) return row_vector_multiplication(vec1, (MatrixObject*)v2); } else if (QuaternionObject_Check(v2)) { QuaternionObject *quat = (QuaternionObject*)v2; - if(vec1->size != 3) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Vector multiplication: only 3D vector rotations (with quats) currently supported\n"); - + if(vec1->size != 3) { + PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n"); + return NULL; + } return quat_rotation((PyObject*)vec1, (PyObject*)quat); } - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Vector multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); + return NULL; } /*------------------------obj *= obj------------------------------ @@ -702,8 +663,8 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) if(mat->colSize != size){ if(mat->rowSize == 4 && vec->size != 3){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "vector * matrix: matrix column size and the vector size must be the same"); + PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); + return NULL; } else { vecCopy[3] = 1.0f; } @@ -726,8 +687,8 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) Py_INCREF( v1 ); return v1; } - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Vector multiplication: arguments not acceptable for this operation\n"); + PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); + return NULL; } /*------------------------obj / obj------------------------------ @@ -738,22 +699,22 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) float vec[4], scalar; VectorObject *vec1 = NULL; - if(!VectorObject_Check(v1)) /* not a vector */ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Vector division: Vector must be divided by a float\n"); - + if(!VectorObject_Check(v1)) { /* not a vector */ + PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); + return NULL; + } vec1 = (VectorObject*)v1; /* vector */ - if(!PyNumber_Check(v2)) /* parsed item not a number */ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Vector division: Vector must be divided by a float\n"); - + if(!PyNumber_Check(v2)) { /* parsed item not a number */ + PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); + return NULL; + } scalar = (float)PyFloat_AsDouble(v2); - if(scalar==0.0) /* not a vector */ - return EXPP_ReturnPyObjError(PyExc_ZeroDivisionError, - "Vector division: divide by zero error.\n"); - + if(scalar==0.0) { /* not a vector */ + PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error.\n"); + return NULL; + } size = vec1->size; for(i = 0; i < size; i++) { vec[i] = vec1->vec[i] / scalar; @@ -769,22 +730,24 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) float scalar; VectorObject *vec1 = NULL; - /*if(!VectorObject_Check(v1)) - return EXPP_ReturnIntError(PyExc_TypeError, - "Vector division: Vector must be divided by a float\n");*/ + /*if(!VectorObject_Check(v1)) { + PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); + return -1; + }*/ vec1 = (VectorObject*)v1; /* vector */ - if(!PyNumber_Check(v2)) /* parsed item not a number */ - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Vector division: Vector must be divided by a float\n"); + if(!PyNumber_Check(v2)) { /* parsed item not a number */ + PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); + return NULL; + } scalar = (float)PyFloat_AsDouble(v2); - if(scalar==0.0) /* not a vector */ - return EXPP_ReturnPyObjError(PyExc_ZeroDivisionError, - "Vector division: divide by zero error.\n"); - + if(scalar==0.0) { /* not a vector */ + PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error.\n"); + return NULL; + } size = vec1->size; for(i = 0; i < size; i++) { vec1->vec[i] /= scalar; @@ -854,9 +817,9 @@ PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_t if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)){ if (comparison_type == Py_NE){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } vecA = (VectorObject*)objectA; @@ -864,9 +827,9 @@ PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_t if (vecA->size != vecB->size){ if (comparison_type == Py_NE){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } @@ -919,9 +882,9 @@ PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_t break; } if (result == 1){ - return EXPP_incr_ret(Py_True); + Py_RETURN_TRUE; }else{ - return EXPP_incr_ret(Py_False); + Py_RETURN_FALSE; } } /*-----------------PROTCOL DECLARATIONS--------------------------*/ @@ -1003,23 +966,24 @@ static PyObject *Vector_getAxis( VectorObject * self, void *type ) case 'Y': return PyFloat_FromDouble(self->vec[1]); case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "vector.z: error, cannot get this axis for a 2D vector\n"); - else + if(self->size < 3) { + PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); + return NULL; + } + else { return PyFloat_FromDouble(self->vec[2]); + } case 'W': - if(self->size < 4) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "vector.w: error, cannot get this axis for a 3D vector\n"); + if(self->size < 4) { + PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); + return NULL; + } return PyFloat_FromDouble(self->vec[3]); default: { - char errstr[1024]; - sprintf( errstr, "undefined type '%d' in Vector_getAxis", - (int)((long)type & 0xff)); - return EXPP_ReturnPyObjError( PyExc_RuntimeError, errstr ); + PyErr_SetString( PyExc_RuntimeError, "undefined type in Vector_getAxis" ); + return NULL; } } } @@ -1028,10 +992,10 @@ static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) { float param= (float)PyFloat_AsDouble( value ); - if (param==-1 && PyErr_Occurred()) - return EXPP_ReturnIntError( PyExc_TypeError, - "expected a number for the vector axis" ); - + 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->vec[0]= param; @@ -1040,16 +1004,17 @@ static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) self->vec[1]= param; break; case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) - return EXPP_ReturnIntError(PyExc_AttributeError, - "vector.z: error, cannot get this axis for a 2D vector\n"); + if(self->size < 3) { + PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); + return -1; + } self->vec[2]= param; break; case 'W': - if(self->size < 4) - return EXPP_ReturnIntError(PyExc_AttributeError, - "vector.w: error, cannot get this axis for a 3D vector\n"); - + if(self->size < 4) { + PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); + return -1; + } self->vec[3]= param; break; } @@ -1074,16 +1039,16 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) double dot = 0.0f, param; int i; - if (!PyNumber_Check(value)) - return EXPP_ReturnIntError( PyExc_TypeError, - "expected a number for the vector axis" ); - + if (!PyNumber_Check(value)) { + PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); + return -1; + } param= PyFloat_AsDouble( value ); - if (param < 0) - return EXPP_ReturnIntError( PyExc_TypeError, - "cannot set a vectors length to a negative value" ); - + if (param < 0) { + PyErr_SetString( PyExc_TypeError, "cannot set a vectors length to a negative value" ); + return -1; + } if (param==0) { for(i = 0; i < self->size; i++){ self->vec[i]= 0; @@ -1297,7 +1262,8 @@ PyObject *Vector_Negate(VectorObject * self) self->vec[i] = -(self->vec[i]); } /*printf("Vector.negate(): Deprecated: use -vector instead\n");*/ - return EXPP_incr_ret((PyObject*)self); + Py_INCREF(self); + return (PyObject*)self; } /*################################################################### ###########################DEPRECATED##############################*/ diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h index 898e3947abd..9ec2eff8047 100644 --- a/source/blender/python/api2_2x/vector.h +++ b/source/blender/python/api2_2x/vector.h @@ -50,7 +50,6 @@ PyObject *Vector_Negate( VectorObject * self ); PyObject *Vector_Resize2D( VectorObject * self ); PyObject *Vector_Resize3D( VectorObject * self ); PyObject *Vector_Resize4D( VectorObject * self ); -PyObject *Vector_toPoint( VectorObject * self ); PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); PyObject *Vector_reflect( VectorObject * self, PyObject * value ); PyObject *Vector_copy( VectorObject * self ); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 06ba8f16a3b..cd141799f64 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1437,7 +1437,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem Object *ob= obr->ob; Object *tob=0; Material *ma=0; - MTFace *mtface; ParticleSystemModifierData *psmd; ParticleSystem *tpsys=0; ParticleSettings *part, *tpart=0; diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index b848fa9ef42..c4623b5b6fe 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -30,9 +30,7 @@ SET(SRC ../../../source/blender/python/api2_2x/Mathutils.c ../../../source/blender/python/api2_2x/constant.c ../../../source/blender/python/api2_2x/euler.c - ../../../source/blender/python/api2_2x/gen_utils.c ../../../source/blender/python/api2_2x/matrix.c - ../../../source/blender/python/api2_2x/point.c ../../../source/blender/python/api2_2x/quat.c ../../../source/blender/python/api2_2x/vector.c ../../../source/blender/python/api2_2x/bpy_internal_import.c diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 61e722fb957..d97f13b0758 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -11,9 +11,7 @@ sources.extend([\ '#source/blender/python/api2_2x/Mathutils.c',\ '#source/blender/python/api2_2x/constant.c',\ '#source/blender/python/api2_2x/euler.c',\ - '#source/blender/python/api2_2x/gen_utils.c',\ '#source/blender/python/api2_2x/matrix.c',\ - '#source/blender/python/api2_2x/point.c',\ '#source/blender/python/api2_2x/quat.c',\ '#source/blender/python/api2_2x/vector.c',\ ]) From d11a5bbef2750c9e95c0657eb9d965de375b2982 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 21 Apr 2009 11:01:09 +0000 Subject: [PATCH 011/444] BGE: Support mesh modifiers in the game engine. Realtime modifiers applied on mesh objects will be supported in the game engine with the following limitations: - Only real time modifiers are supported (basically all of them!) - Virtual modifiers resulting from parenting are not supported: armature, curve, lattice. You can still use these modifiers (armature is really not recommended) but in non parent mode. The BGE has it's own parenting capability for armature. - Modifiers are computed on the host (using blender modifier stack). - Modifiers are statically evaluated: any possible time dependency in the modifiers is not supported (don't know enough about modifiers to be more specific). - Modifiers are reevaluated if the underlying mesh is deformed due to shape action or armature action. Beware that this is very CPU intensive; modifiers should really be used for static objects only. - Physics is still based on the original mesh: if you have a mirror modifier, the physic shape will be limited to one half of the resulting object. Therefore, the modifiers should preferably be used on graphic objects. - Scripts have no access to the modified mesh. - Modifiers that are based on objects interaction (boolean,..) will not be dependent on the objects position in the GE. What you see in the 3D view is what you get in the GE regardless on the object position, velocity, etc. Besides that, the feature is compatible with all the BGE features that affect meshes: armature action, shape action, relace mesh, VideoTexture, add object, dupligroup. Known problems: - This feature is a bit hacky: the BGE uses the derived mesh draw functions to display the object. This drawing method is a bit slow and is not 100% compatible with the BGE. There may be some problems in multi-texture mode: the multi-texture coordinates are not sent to the GPU. Texface and GLSL on the other hand should be fully supported. - Culling is still based on the extend of the original mesh. If you have a modifer that extends the size of the mesh, the object may disappear while still in the view frustrum. - Derived mesh is not shared between replicas. The derived mesh is allocated and computed for each object with modifiers, regardless if they are static replicas. - Display list are not created on objects with modifiers. I should be able to fix the above problems before release. However, the feature is already useful for game development. Once you are ready to release the game, you can apply the modifiers to get back display list support and mesh sharing capability. MSVC, scons, Cmake, makefile updated. Enjoy /benoit --- .../blender/BPY_python/BPY_python.vcproj | 8 - .../gameengine/converter/KX_converter.vcproj | 16 +- .../rasterizer/RAS_rasterizer.vcproj | 13 +- .../RAS_openglrasterizer.vcproj | 13 +- .../gameengine/videotexture/TEX_Video.vcproj | 1 - source/blender/blenkernel/BKE_DerivedMesh.h | 3 + .../blender/blenkernel/intern/DerivedMesh.c | 21 ++- .../Converter/BL_BlenderDataConversion.cpp | 18 ++- .../Converter/BL_ModifierDeformer.cpp | 149 ++++++++++++++++++ .../Converter/BL_ModifierDeformer.h | 97 ++++++++++++ .../gameengine/Converter/BL_ShapeDeformer.cpp | 10 +- .../gameengine/Converter/BL_ShapeDeformer.h | 3 +- .../gameengine/Converter/BL_SkinDeformer.cpp | 52 +++--- source/gameengine/Converter/BL_SkinDeformer.h | 4 +- .../Converter/BL_SkinMeshObject.cpp | 2 +- source/gameengine/Ketsji/BL_Material.cpp | 2 +- source/gameengine/Ketsji/BL_Material.h | 3 +- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 24 ++- source/gameengine/Ketsji/KX_BlenderMaterial.h | 4 +- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 14 ++ source/gameengine/Ketsji/KX_PolygonMaterial.h | 6 +- source/gameengine/Ketsji/KX_Scene.cpp | 36 ++++- source/gameengine/Rasterizer/CMakeLists.txt | 1 + source/gameengine/Rasterizer/Makefile | 1 + source/gameengine/Rasterizer/RAS_Deformer.h | 4 + .../Rasterizer/RAS_IPolygonMaterial.cpp | 30 ++++ .../Rasterizer/RAS_IPolygonMaterial.h | 11 +- .../Rasterizer/RAS_MaterialBucket.cpp | 39 +++++ .../Rasterizer/RAS_MaterialBucket.h | 3 + .../gameengine/Rasterizer/RAS_MeshObject.cpp | 13 ++ source/gameengine/Rasterizer/RAS_MeshObject.h | 1 + .../RAS_OpenGLRasterizer/CMakeLists.txt | 4 + .../Rasterizer/RAS_OpenGLRasterizer/Makefile | 5 + .../RAS_ListRasterizer.cpp | 36 +++-- .../RAS_OpenGLRasterizer/RAS_ListRasterizer.h | 8 +- .../RAS_OpenGLRasterizer.cpp | 79 ++++++++++ .../RAS_VAOpenGLRasterizer.cpp | 12 ++ .../RAS_OpenGLRasterizer/SConscript | 2 + 38 files changed, 660 insertions(+), 88 deletions(-) create mode 100644 source/gameengine/Converter/BL_ModifierDeformer.cpp create mode 100644 source/gameengine/Converter/BL_ModifierDeformer.h diff --git a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj index ff5fe62806c..55ef074178b 100644 --- a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj +++ b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj @@ -589,10 +589,6 @@ RelativePath="..\..\..\source\blender\python\api2_2x\Particle.c" > - - @@ -882,10 +878,6 @@ RelativePath="..\..\..\source\blender\python\api2_2x\Particle.h" > - - diff --git a/projectfiles_vc9/gameengine/converter/KX_converter.vcproj b/projectfiles_vc9/gameengine/converter/KX_converter.vcproj index 53a628ed5ee..4f5b34485cf 100644 --- a/projectfiles_vc9/gameengine/converter/KX_converter.vcproj +++ b/projectfiles_vc9/gameengine/converter/KX_converter.vcproj @@ -479,10 +479,6 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_ActionActuator.cpp" > - - @@ -495,6 +491,10 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_MeshDeformer.cpp" > + + @@ -552,6 +552,10 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_ActionActuator.h" > + + @@ -568,6 +572,10 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_MeshDeformer.h" > + + diff --git a/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj b/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj index 924babfbd21..d3d35ff4826 100644 --- a/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj +++ b/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="RAS_rasterizer" ProjectGUID="{51FB3D48-2467-4BFA-A321-D848252B437E}" + RootNamespace="RAS_rasterizer" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 263b17151e7..7ee8a424d03 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -444,6 +444,9 @@ DerivedMesh *mesh_create_derived_no_deform(struct Object *ob, DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob, float (*vertCos)[3], CustomDataMask dataMask); +/* for gameengine */ +DerivedMesh *mesh_create_derived_no_virtual(struct Object *ob, float (*vertCos)[3], + CustomDataMask dataMask); DerivedMesh *editmesh_get_derived_base(void); DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d43cbdebe72..eb2975be0c0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2111,6 +2111,11 @@ static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh * DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); } +/* new value for useDeform -1 (hack for the gameengine): + * - apply only the modifier stack of the object, skipping the virtual modifiers, + * - don't apply the key + * - apply deform modifiers and input vertexco + */ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, @@ -2125,7 +2130,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], int numVerts = me->totvert; int required_mode; - md = firstmd = modifiers_getVirtualModifierList(ob); + md = firstmd = (useDeform<0) ? ob->modifiers.first : modifiers_getVirtualModifierList(ob); modifiers_clearErrors(ob); @@ -2142,8 +2147,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], else required_mode = eModifierMode_Realtime; if(useDeform) { - if(do_ob_key(ob)) /* shape key makes deform verts */ + if(useDeform > 0 && do_ob_key(ob)) /* shape key makes deform verts */ deformedVerts = mesh_getVertexCos(me, &numVerts); + else if(inputVertexCos) + deformedVerts = inputVertexCos; /* Apply all leading deforming modifiers */ for(;md; md = md->next, curr = curr->next) { @@ -2947,6 +2954,16 @@ DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3], return final; } +DerivedMesh *mesh_create_derived_no_virtual(Object *ob, float (*vertCos)[3], + CustomDataMask dataMask) +{ + DerivedMesh *final; + + mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1); + + return final; +} + DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3], CustomDataMask dataMask) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 9f214721c82..b7f74d57ca4 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -90,6 +90,7 @@ #include "BKE_object.h" #include "BKE_scene.h" #include "BL_SkinMeshObject.h" +#include "BL_ModifierDeformer.h" #include "BL_ShapeDeformer.h" #include "BL_SkinDeformer.h" #include "BL_MeshDeformer.h" @@ -341,6 +342,7 @@ BL_Material* ConvertMaterial( material->IdMode = DEFAULT_BLENDER; material->glslmat = (validmat)? glslmat: false; + material->materialindex = mface->mat_nr; // -------------------------------- if(validmat) { @@ -747,7 +749,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* } // Determine if we need to make a skinned mesh - if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0)) + if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0) || BL_ModifierDeformer::HasCompatibleDeformer(blenderobj)) { meshobj = new BL_SkinMeshObject(mesh, lightlayer); skinMesh = true; @@ -853,8 +855,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); - bl_mat->material_index = (int)mface->mat_nr; - visible = ((bl_mat->ras_mode & POLY_VIS)!=0); collider = ((bl_mat->ras_mode & COLLIDER)!=0); twoside = ((bl_mat->mode & TF_TWOSIDE)!=0); @@ -874,6 +874,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* /* then the KX_BlenderMaterial */ polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer); + } else { /* do Texture Face materials */ @@ -956,7 +957,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bool alpha = (transp == TF_ALPHA || transp == TF_ADD); bool zsort = (mode & TF_ALPHASORT)? alpha: 0; - polymat = new KX_PolygonMaterial(imastr, ma, + polymat = new KX_PolygonMaterial(imastr, ma, (int)mface->mat_nr, tile, tilexrep, tileyrep, mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol); @@ -1689,8 +1690,15 @@ static KX_GameObject *gameobject_from_blenderobject( bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE; bool bHasDvert = mesh->dvert != NULL && ob->defbase.first; bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert); + bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob); - if (bHasShapeKey) { + if (bHasModifier) { + BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj, + ob, (BL_SkinMeshObject *)meshobj); + ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); + if (bHasShapeKey && bHasArmature) + dcont->LoadShapeDrivers(ob->parent); + } else if (bHasShapeKey) { // not that we can have shape keys without dvert! BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, ob, (BL_SkinMeshObject*)meshobj); diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp new file mode 100644 index 00000000000..6113f88e331 --- /dev/null +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -0,0 +1,149 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif //WIN32 + +#include "MEM_guardedalloc.h" +#include "BL_ModifierDeformer.h" +#include "GEN_Map.h" +#include "STR_HashedString.h" +#include "RAS_IPolygonMaterial.h" +#include "BL_SkinMeshObject.h" + +//#include "BL_ArmatureController.h" +#include "DNA_armature_types.h" +#include "DNA_action_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_ipo_types.h" +#include "DNA_curve_types.h" +#include "DNA_modifier_types.h" +#include "BKE_armature.h" +#include "BKE_action.h" +#include "BKE_key.h" +#include "BKE_ipo.h" +#include "MT_Point3.h" + +extern "C"{ + #include "BKE_customdata.h" + #include "BKE_DerivedMesh.h" + #include "BKE_lattice.h" + #include "BKE_modifier.h" +} + #include "BKE_utildefines.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#define __NLA_DEFNORMALS +//#undef __NLA_DEFNORMALS + + +BL_ModifierDeformer::~BL_ModifierDeformer() +{ + if (m_dm) { + m_dm->needsFree = 1; + m_dm->release(m_dm); + } +}; + +RAS_Deformer *BL_ModifierDeformer::GetReplica(class KX_GameObject* replica) +{ + BL_ModifierDeformer *result; + + result = new BL_ModifierDeformer(*this); + result->ProcessReplica(); + return result; +} + +void BL_ModifierDeformer::ProcessReplica() +{ + BL_ShapeDeformer::ProcessReplica(); + m_dm = NULL; + m_lastModifierUpdate = -1; +} + +bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob) +{ + if (!ob->modifiers.first) + return false; + ModifierData* md; + for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) { + if (md->mode & eModifierMode_Realtime) + return true; + } + return false; +} + +bool BL_ModifierDeformer::Update(void) +{ + bool bShapeUpdate = BL_ShapeDeformer::Update(); + + if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) { + /* execute the modifiers */ + Object* blendobj = m_gameobj->GetBlendObject(); + /* hack: the modifiers require that the mesh is attached to the object + It may not be the case here because of replace mesh actuator */ + Mesh *oldmesh = (Mesh*)blendobj->data; + blendobj->data = m_bmesh; + /* execute the modifiers */ + DerivedMesh *dm = mesh_create_derived_no_virtual(blendobj, m_transverts, CD_MASK_MESH); + /* restore object data */ + blendobj->data = oldmesh; + /* free the current derived mesh and replace, (dm should never be NULL) */ + if (m_dm != NULL) { + m_dm->needsFree = 1; + m_dm->release(m_dm); + } + m_dm = dm; + m_lastModifierUpdate=m_gameobj->GetLastFrame(); + bShapeUpdate = true; + } + return bShapeUpdate; +} + +bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat) +{ + if (!Update()) + return false; + + // drawing is based on derived mesh, must set it in the mesh slots + int nmat = m_pMeshObject->NumMaterials(); + for (int imat=0; imatGetMeshMaterial(imat); + RAS_MeshSlot *slot = *mmat->m_slots[(void*)m_gameobj]; + if(!slot) + continue; + slot->m_pDerivedMesh = m_dm; + } + return true; +} diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h new file mode 100644 index 00000000000..0caaabf8055 --- /dev/null +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -0,0 +1,97 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BL_MODIFIERDEFORMER +#define BL_MODIFIERDEFORMER + +#ifdef WIN32 +#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif //WIN32 + +#include "BL_ShapeDeformer.h" +#include "BL_DeformableGameObject.h" +#include + +struct DerivedMesh; +struct Object; + +class BL_ModifierDeformer : public BL_ShapeDeformer +{ +public: + static bool HasCompatibleDeformer(Object *ob); + + + BL_ModifierDeformer(BL_DeformableGameObject *gameobj, + Object *bmeshobj, + BL_SkinMeshObject *mesh) + : + BL_ShapeDeformer(gameobj,bmeshobj, mesh), + m_lastModifierUpdate(-1), + m_dm(NULL) + { + m_recalcNormal = false; + }; + + /* this second constructor is needed for making a mesh deformable on the fly. */ + BL_ModifierDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class BL_SkinMeshObject *mesh, + bool release_object, + BL_ArmatureObject* arma = NULL) + : + BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma), + m_lastModifierUpdate(-1), + m_dm(NULL) + { + }; + + virtual void ProcessReplica(); + virtual RAS_Deformer *GetReplica(class KX_GameObject* replica); + virtual ~BL_ModifierDeformer(); + virtual bool UseVertexArray() + { + return false; + } + + bool Update (void); + bool Apply(RAS_IPolyMaterial *mat); + void ForceUpdate() + { + m_lastModifierUpdate = -1.0; + }; + +protected: + double m_lastModifierUpdate; + DerivedMesh *m_dm; + +}; + +#endif + diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index fc6498579ad..499732c7f70 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -79,6 +79,7 @@ RAS_Deformer *BL_ShapeDeformer::GetReplica(class KX_GameObject* replica) void BL_ShapeDeformer::ProcessReplica() { + BL_SkinDeformer::ProcessReplica(); } bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma) @@ -87,7 +88,7 @@ bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma) m_shapeDrivers.clear(); // check if this mesh has armature driven shape keys - if (m_bmesh->key->ipo) { + if (m_bmesh->key && m_bmesh->key->ipo) { for(icu= (IpoCurve*)m_bmesh->key->ipo->curve.first; icu; icu= (IpoCurve*)icu->next) { if(icu->driver && (icu->flag & IPO_MUTE) == 0 && @@ -147,7 +148,9 @@ bool BL_ShapeDeformer::Update(void) m_pMeshObject->CheckWeightCache(blendobj); /* we will blend the key directly in mvert array: it is used by armature as the start position */ - do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0); + /* m_bmesh->key can be NULL in case of Modifier deformer */ + if (m_bmesh->key) + do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0); // Don't release the weight array as in Blender, it will most likely be reusable on next frame // The weight array are ultimately deleted when the skin mesh is destroyed @@ -174,7 +177,8 @@ bool BL_ShapeDeformer::Update(void) VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); #ifdef __NLA_DEFNORMALS - RecalcNormals(); + if (m_recalcNormal) + RecalcNormals(); #endif bSkinUpdate = true; } diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index 90b9f5caea1..901a1d82295 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -58,9 +58,10 @@ public: struct Object *bmeshobj_new, class BL_SkinMeshObject *mesh, bool release_object, + bool recalc_normal, BL_ArmatureObject* arma = NULL) : - BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, arma), + BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, recalc_normal, arma), m_lastShapeUpdate(-1) { }; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index d8563763954..ae3e1a10005 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -65,9 +65,10 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj, BL_MeshDeformer(gameobj, bmeshobj, mesh), m_armobj(arma), m_lastArmaUpdate(-1), - m_defbase(&bmeshobj->defbase), + //m_defbase(&bmeshobj->defbase), m_releaseobject(false), - m_poseApplied(false) + m_poseApplied(false), + m_recalcNormal(true) { Mat4CpyMat4(m_obmat, bmeshobj->obmat); }; @@ -78,12 +79,14 @@ BL_SkinDeformer::BL_SkinDeformer( struct Object *bmeshobj_new, // Blender object that owns the original mesh class BL_SkinMeshObject *mesh, bool release_object, + bool recalc_normal, BL_ArmatureObject* arma) : BL_MeshDeformer(gameobj, bmeshobj_old, mesh), m_armobj(arma), m_lastArmaUpdate(-1), - m_defbase(&bmeshobj_old->defbase), - m_releaseobject(release_object) + //m_defbase(&bmeshobj_old->defbase), + m_releaseobject(release_object), + m_recalcNormal(recalc_normal) { // this is needed to ensure correct deformation of mesh: // the deformation is done with Blender's armature_deform_verts() function @@ -118,31 +121,33 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) RAS_MeshSlot::iterator it; RAS_MeshMaterial *mmat; RAS_MeshSlot *slot; - size_t i; + size_t i, nmat, imat; // update the vertex in m_transverts - Update(); + if (!Update()) + return false; - // The vertex cache can only be updated for this deformer: - // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object) - // share the same mesh (=the same cache). As the rendering is done per polymaterial - // cycling through the objects, the entire mesh cache cannot be updated in one shot. - mmat = m_pMeshObject->GetMeshMaterial(mat); - if(!mmat->m_slots[(void*)m_gameobj]) - return true; + // the vertex cache is unique to this deformer, no need to update it + // if it wasn't updated! We must update all the materials at once + // because we will not get here again for the other material + nmat = m_pMeshObject->NumMaterials(); + for (imat=0; imatGetMeshMaterial(imat); + if(!mmat->m_slots[(void*)m_gameobj]) + continue; - slot = *mmat->m_slots[(void*)m_gameobj]; + slot = *mmat->m_slots[(void*)m_gameobj]; - // for each array - for(slot->begin(it); !slot->end(it); slot->next(it)) { - // for each vertex - // copy the untransformed data from the original mvert - for(i=it.startvertex; ibegin(it); !slot->end(it); slot->next(it)) { + // for each vertex + // copy the untransformed data from the original mvert + for(i=it.startvertex; iobmat, obmat); #ifdef __NLA_DEFNORMALS - RecalcNormals(); + if (m_recalcNormal) + RecalcNormals(); #endif /* Update the current frame */ diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index f87860021c6..c93188b0c5a 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -64,6 +64,7 @@ public: struct Object *bmeshobj_new, class BL_SkinMeshObject *mesh, bool release_object, + bool recalc_normal, BL_ArmatureObject* arma = NULL); virtual void ProcessReplica(); @@ -88,10 +89,11 @@ protected: BL_ArmatureObject* m_armobj; // Our parent object float m_time; double m_lastArmaUpdate; - ListBase* m_defbase; + //ListBase* m_defbase; float m_obmat[4][4]; // the reference matrix for skeleton deform bool m_releaseobject; bool m_poseApplied; + bool m_recalcNormal; }; diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index eb3f9d0588d..0a18296f261 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -87,7 +87,7 @@ void BL_SkinMeshObject::UpdateBuckets(void* clientobj,double* oglmatrix,bool use continue; RAS_MeshSlot *slot = *it->m_slots[clientobj]; - slot->m_pDeformer = ((BL_DeformableGameObject*)clientobj)->GetDeformer(); + slot->SetDeformer(((BL_DeformableGameObject*)clientobj)->GetDeformer()); } RAS_MeshObject::UpdateBuckets(clientobj, oglmatrix, useObjectColor, rgbavec, visible, culled); diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 7e3d6984f19..022ed71ef7b 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -52,7 +52,7 @@ BL_Material::BL_Material() mode = 0; material = 0; tface = 0; - material_index = 0; + materialindex = 0; amb=0.5f; num_enabled = 0; num_users = 1; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index 0eaa234566c..a0ce37aace0 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -54,6 +54,7 @@ public: int tile,tilexrep[MAXTEX],tileyrep[MAXTEX]; STR_String matname; STR_String mtexname[MAXTEX]; + int materialindex; float matcolor[4]; float speccolor[3]; @@ -68,8 +69,6 @@ public: int mode; int num_enabled; - int material_index; - BL_Mapping mapping[MAXTEX]; STR_String imageId[MAXTEX]; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 2edfe4b718c..7378113bc31 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -53,6 +53,7 @@ KX_BlenderMaterial::KX_BlenderMaterial( RAS_IPolyMaterial( STR_String( data->texname[0] ), STR_String( data->matname ), // needed for physics! + data->materialindex, data->tile, data->tilexrep[0], data->tileyrep[0], @@ -120,6 +121,27 @@ unsigned int* KX_BlenderMaterial::GetMCol(void) const return mMaterial->rgb; } +void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const +{ + if (mMaterial) { + *rgba++ = (unsigned char) (mMaterial->matcolor[0]*255.0); + *rgba++ = (unsigned char) (mMaterial->matcolor[1]*255.0); + *rgba++ = (unsigned char) (mMaterial->matcolor[2]*255.0); + *rgba++ = (unsigned char) (mMaterial->matcolor[3]*255.0); + } else + RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); +} + +Material *KX_BlenderMaterial::GetBlenderMaterial() const +{ + return mMaterial->material; +} + +Scene* KX_BlenderMaterial::GetBlenderScene() const +{ + return mScene->GetBlenderScene(); +} + void KX_BlenderMaterial::OnConstruction() { if (mConstructed) @@ -863,7 +885,7 @@ void KX_BlenderMaterial::SetBlenderGLSLShader(void) KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") { - return PyInt_FromLong( mMaterial->material_index ); + return PyInt_FromLong( GetMaterialIndex() ); } KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" ) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 57cdde3c947..eeb919a1bf1 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -73,7 +73,6 @@ public: Image * getImage (unsigned int idx) { return (idx < MAXTEX && mMaterial) ? mMaterial->img[idx] : NULL; } - // for ipos void UpdateIPO( MT_Vector4 rgba, MT_Vector3 specrgb, @@ -117,6 +116,9 @@ private: void ActivateTexGen( RAS_IRasterizer *ras ) const; bool UsesLighting(RAS_IRasterizer *rasty) const; + void GetMaterialRGBAColor(unsigned char *rgba) const; + Material* GetBlenderMaterial() const; + Scene* GetBlenderScene() const; // message centers void setTexData( bool enable,RAS_IRasterizer *ras); diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 2d5a5f99cea..a8105c1e4f3 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -53,6 +53,7 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, Material *material, + int materialindex, int tile, int tilexrep, int tileyrep, @@ -67,6 +68,7 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, : PyObjectPlus(T), RAS_IPolyMaterial(texname, STR_String(material?material->id.name:""), + materialindex, tile, tilexrep, tileyrep, @@ -167,6 +169,18 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c rasty->SetPolygonOffset(-m_material->zoffs, 0.0); } +void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const +{ + if (m_material) { + *rgba++ = (unsigned char) (m_material->r*255.0); + *rgba++ = (unsigned char) (m_material->g*255.0); + *rgba++ = (unsigned char) (m_material->b*255.0); + *rgba++ = (unsigned char) (m_material->alpha*255.0); + } else + RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); +} + + //---------------------------------------------------------------------------- //Python diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index e5816058bbf..b6f5f373335 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -53,7 +53,6 @@ private: MTFace* m_tface; unsigned int* m_mcol; Material* m_material; - PyObject* m_pymaterial; mutable int m_pass; @@ -61,6 +60,7 @@ public: KX_PolygonMaterial(const STR_String &texname, Material* ma, + int materialindex, int tile, int tilexrep, int tileyrep, @@ -107,8 +107,8 @@ public: { return m_mcol; } - - + virtual void GetMaterialRGBAColor(unsigned char *rgba) const; + KX_PYMETHOD_DOC(KX_PolygonMaterial, updateTexture); KX_PYMETHOD_DOC(KX_PolygonMaterial, setTexture); KX_PYMETHOD_DOC(KX_PolygonMaterial, activate); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index f91c4674113..f57a38d290d 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -80,6 +80,7 @@ #include "KX_BlenderSceneConverter.h" #include "KX_MotionState.h" +#include "BL_ModifierDeformer.h" #include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" @@ -1038,6 +1039,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) Object* oldblendobj = static_cast(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName())); Mesh* blendmesh = mesh->GetMesh(); + bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(blendobj); bool bHasShapeKey = blendmesh->key != NULL && blendmesh->key->type==KEY_RELATIVE; bool bHasDvert = blendmesh->dvert != NULL; bool bHasArmature = @@ -1053,10 +1055,37 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) if (oldblendobj==NULL) { std::cout << "warning: ReplaceMesh() new mesh is not used in an object from the current scene, you will get incorrect behavior" << std::endl; - bHasShapeKey= bHasDvert= bHasArmature= false; + bHasShapeKey= bHasDvert= bHasArmature=bHasModifier= false; } - if (bHasShapeKey) + if (bHasModifier) + { + BL_ModifierDeformer* modifierDeformer; + if (bHasShapeKey || bHasArmature) + { + modifierDeformer = new BL_ModifierDeformer( + newobj, + oldblendobj, blendobj, + static_cast(mesh), + true, + static_cast( parentobj ) + ); + releaseParent= false; + modifierDeformer->LoadShapeDrivers(blendobj->parent); + } + else + { + modifierDeformer = new BL_ModifierDeformer( + newobj, + oldblendobj, blendobj, + static_cast(mesh), + false, + NULL + ); + } + newobj->SetDeformer(modifierDeformer); + } + else if (bHasShapeKey) { BL_ShapeDeformer* shapeDeformer; if (bHasArmature) @@ -1066,6 +1095,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) oldblendobj, blendobj, static_cast(mesh), true, + true, static_cast( parentobj ) ); releaseParent= false; @@ -1078,6 +1108,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) oldblendobj, blendobj, static_cast(mesh), false, + true, NULL ); } @@ -1090,6 +1121,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) oldblendobj, blendobj, static_cast(mesh), true, + true, static_cast( parentobj ) ); releaseParent= false; diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index 6d53ee53471..69a167e54a9 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -29,6 +29,7 @@ FILE(GLOB SRC *.cpp) SET(INC . ../../../source/kernel/gen_system + ../../../source/blender/makesdna ../../../intern/string ../../../intern/moto/include ../../../extern/glew/include diff --git a/source/gameengine/Rasterizer/Makefile b/source/gameengine/Rasterizer/Makefile index 917f70c7108..fa6cf94c4b6 100644 --- a/source/gameengine/Rasterizer/Makefile +++ b/source/gameengine/Rasterizer/Makefile @@ -40,6 +40,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../kernel/gen_system +CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I../BlenderRoutines CPPFLAGS += -I../Expressions diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index 3332ac4c0a7..dc5a49a0f99 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -49,6 +49,10 @@ public: { return false; } + virtual bool UseVertexArray() + { + return true; + } protected: class RAS_MeshObject *m_pMesh; }; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index cd88112007b..e8f451382b9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -29,12 +29,16 @@ #include "RAS_IPolygonMaterial.h" #include "RAS_IRasterizer.h" +#include "DNA_image_types.h" +#include "DNA_meshdata_types.h" + #ifdef HAVE_CONFIG_H #include #endif RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, + int materialindex, int tile, int tilexrep, int tileyrep, @@ -45,6 +49,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, int lightlayer) : m_texturename(texname), m_materialname(matname), + m_materialindex(materialindex), m_tile(tile), m_tilexrep(tilexrep), m_tileyrep(tileyrep), @@ -95,6 +100,15 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const } } + +void RAS_IPolyMaterial::GetMaterialRGBAColor(unsigned char *rgba) const +{ + *rgba++ = 0xFF; + *rgba++ = 0xFF; + *rgba++ = 0xFF; + *rgba++ = 0xFF; +} + bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const { if (Equals(rhs)) @@ -143,6 +157,22 @@ const STR_String& RAS_IPolyMaterial::GetTextureName() const return m_texturename; } +int RAS_IPolyMaterial::GetMaterialIndex() const +{ + return m_materialindex; +} + +Material *RAS_IPolyMaterial::GetBlenderMaterial() const +{ + return NULL; +} + +Scene* RAS_IPolyMaterial::GetBlenderScene() const +{ + return NULL; +} + + unsigned int RAS_IPolyMaterial::GetFlag() const { return m_flag; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index e5b24070c4b..dcd8b53402e 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -39,6 +39,9 @@ #include "STR_HashedString.h" class RAS_IRasterizer; +struct MTFace; +struct Material; +struct Scene; enum MaterialProps { @@ -71,6 +74,7 @@ protected: bool m_alpha; bool m_zsort; int m_lightlayer; + int m_materialindex; unsigned int m_polymatid; static unsigned int m_newpolymatid; @@ -98,6 +102,7 @@ public: RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, + int materialindex, int tile, int tilexrep, int tileyrep, @@ -139,10 +144,14 @@ public: dword GetMaterialNameHash() const; const STR_String& GetTextureName() const; unsigned int GetFlag() const; + int GetMaterialIndex() const; + virtual Material* GetBlenderMaterial() const; + virtual Scene* GetBlenderScene() const; + virtual void GetMaterialRGBAColor(unsigned char *rgba) const; virtual bool UsesLighting(RAS_IRasterizer *rasty) const; virtual bool UsesObjectColor() const; - + /* * PreCalculate texture gen */ diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 6beab28d61f..d63e9c98415 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -56,6 +56,7 @@ RAS_MeshSlot::RAS_MeshSlot() m_DisplayList = NULL; m_bDisplayList = true; m_joinSlot = NULL; + m_pDerivedMesh = NULL; } RAS_MeshSlot::~RAS_MeshSlot() @@ -87,6 +88,7 @@ RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot) m_clientObj = NULL; m_pDeformer = NULL; + m_pDerivedMesh = NULL; m_OpenGLMatrix = NULL; m_mesh = slot.m_mesh; m_bucket = slot.m_bucket; @@ -279,6 +281,43 @@ void RAS_MeshSlot::AddPolygonVertex(int offset) m_endindex++; } +void RAS_MeshSlot::SetDeformer(RAS_Deformer* deformer) +{ + if (deformer && m_pDeformer != deformer) { + // we create local copy of RAS_DisplayArray when we have a deformer: + // this way we can avoid conflict between the vertex cache of duplicates + RAS_DisplayArrayList::iterator it; + for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) { + if (deformer->UseVertexArray()) { + // the deformer makes use of vertex array, make sure we have our local copy + if ((*it)->m_users > 1) { + // only need to copy if there are other users + // note that this is the usual case as vertex arrays are held by the material base slot + RAS_DisplayArray *newarray = new RAS_DisplayArray(*(*it)); + newarray->m_users = 1; + (*it)->m_users--; + *it = newarray; + } + } else { + // the deformer is not using vertex array (Modifier), release them + (*it)->m_users--; + if((*it)->m_users == 0) + delete *it; + } + } + if (!deformer->UseVertexArray()) { + m_displayArrays.clear(); + m_startarray = 0; + m_startvertex = 0; + m_startindex = 0; + m_endarray = 0; + m_endvertex = 0; + m_endindex = 0; + } + } + m_pDeformer = deformer; +} + bool RAS_MeshSlot::Equals(RAS_MeshSlot *target) { if(!m_OpenGLMatrix || !target->m_OpenGLMatrix) diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index f5c8cd3e107..b07f86b079e 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -69,6 +69,7 @@ class RAS_DisplayArray; class RAS_MeshSlot; class RAS_MeshMaterial; class RAS_MaterialBucket; +struct DerivedMesh; /* An array with data used for OpenGL drawing */ @@ -110,6 +111,7 @@ public: RAS_MeshObject* m_mesh; void* m_clientObj; RAS_Deformer* m_pDeformer; + DerivedMesh* m_pDerivedMesh; double* m_OpenGLMatrix; // visibility bool m_bVisible; @@ -148,6 +150,7 @@ public: /* used during construction */ void SetDisplayArray(int numverts); RAS_DisplayArray *CurrentDisplayArray(); + void SetDeformer(RAS_Deformer* deformer); void AddPolygon(int numverts); int AddVertex(const RAS_TexVert& tv); diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 162f9a81335..5625b172913 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -215,6 +215,19 @@ RAS_MeshMaterial *RAS_MeshObject::GetMeshMaterial(RAS_IPolyMaterial *mat) return NULL; } +int RAS_MeshObject::GetMaterialId(RAS_IPolyMaterial *mat) +{ + list::iterator mit; + int imat; + + /* find a mesh material */ + for(imat=0, mit = m_materials.begin(); mit != m_materials.end(); mit++, imat++) + if(mit->m_bucket->GetPolyMaterial() == mat) + return imat; + + return -1; +} + RAS_Polygon* RAS_MeshObject::AddPolygon(RAS_MaterialBucket *bucket, int numverts) { RAS_MeshMaterial *mmat; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 404b7f16a59..cc50f9c783d 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -89,6 +89,7 @@ public: RAS_MeshMaterial* GetMeshMaterial(unsigned int matid); RAS_MeshMaterial* GetMeshMaterial(RAS_IPolyMaterial *mat); + int GetMaterialId(RAS_IPolyMaterial *mat); list::iterator GetFirstMaterial(); list::iterator GetLastMaterial(); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index e4403ace69f..322d7b79e6f 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -31,8 +31,12 @@ SET(INC ../../../../intern/string ../../../../intern/moto/include ../../../../source/gameengine/Rasterizer + ../../../../source/gameengine/Ketsji ../../../../extern/glew/include ../../../../source/blender/gpu + ../../../../source/blender/makesdna + ../../../../source/blender/blenkernel + ../../../../source/blender/blenlib ) BLENDERLIB(bf_oglrasterizer "${SRC}" "${INC}") diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile index aee485a22be..b55f6492805 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile @@ -42,8 +42,13 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../../kernel/gen_system CPPFLAGS += -I../../../blender/gpu +CPPFLAGS += -I../../../blender/makesdna +CPPFLAGS += -I../../../blender/blenlib +CPPFLAGS += -I../../../blender/blenkernel CPPFLAGS += -I../../BlenderRoutines +CPPFLAGS += -I../../Ketsji CPPFLAGS += -I.. +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include ifeq ($(OS),darwin) CPPFLAGS += -fpascal-strings diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index 65aadd63a40..06c61fb4b09 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -116,10 +116,13 @@ RAS_ListRasterizer::~RAS_ListRasterizer() void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list) { - RAS_Lists::iterator it = mLists.begin(); - while(it != mLists.end()) { + if (list->m_flag & LIST_STANDALONE) + return ; + + RAS_ArrayLists::iterator it = mArrayLists.begin(); + while(it != mArrayLists.end()) { if (it->second == list) { - mLists.erase(it); + mArrayLists.erase(it); break; } it++; @@ -136,12 +139,19 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms) */ RAS_ListSlot* localSlot = (RAS_ListSlot*)ms.m_DisplayList; if(!localSlot) { - RAS_Lists::iterator it = mLists.find(ms.m_displayArrays); - if(it == mLists.end()) { + if (ms.m_pDerivedMesh) { + // that means that we draw based on derived mesh, a display list is possible + // but it's unique to this mesh slot localSlot = new RAS_ListSlot(this); - mLists.insert(std::pair(ms.m_displayArrays, localSlot)); + localSlot->m_flag |= LIST_STANDALONE; } else { - localSlot = static_cast(it->second->AddRef()); + RAS_ArrayLists::iterator it = mArrayLists.find(ms.m_displayArrays); + if(it == mArrayLists.end()) { + localSlot = new RAS_ListSlot(this); + mArrayLists.insert(std::pair(ms.m_displayArrays, localSlot)); + } else { + localSlot = static_cast(it->second->AddRef()); + } } } MT_assert(localSlot); @@ -150,12 +160,12 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms) void RAS_ListRasterizer::ReleaseAlloc() { - RAS_Lists::iterator it = mLists.begin(); - while(it != mLists.end()) { + RAS_ArrayLists::iterator it = mArrayLists.begin(); + while(it != mArrayLists.end()) { delete it->second; it++; } - mLists.clear(); + mArrayLists.clear(); } void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms) @@ -172,8 +182,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms) return; } } - - if (mUseVertexArrays) + // derived mesh cannot use vertex array + if (mUseVertexArrays && !ms.m_pDerivedMesh) RAS_VAOpenGLRasterizer::IndexPrimitives(ms); else RAS_OpenGLRasterizer::IndexPrimitives(ms); @@ -204,7 +214,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) // workaround: note how we do not use vertex arrays for making display // lists, since glVertexAttribPointerARB doesn't seem to work correct // in display lists on ATI? either a bug in the driver or in Blender .. - if (mUseVertexArrays && !localSlot) + if (mUseVertexArrays && !localSlot && !ms.m_pDerivedMesh) RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms); else RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index 653bb43e534..19211894896 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -9,6 +9,7 @@ class RAS_ListRasterizer; class RAS_ListSlot : public KX_ListSlot { + friend class RAS_ListRasterizer; unsigned int m_list; unsigned int m_flag; RAS_ListRasterizer* m_rasty; @@ -32,15 +33,16 @@ enum RAS_ListSlotFlags { LIST_NOCREATE =8, LIST_BEGIN =16, LIST_END =32, - LIST_REGEN =64 + LIST_REGEN =64, + LIST_STANDALONE =128, }; -typedef std::map RAS_Lists; +typedef std::map RAS_ArrayLists; class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer { bool mUseVertexArrays; - RAS_Lists mLists; + RAS_ArrayLists mArrayLists; RAS_ListSlot* FindOrAdd(class RAS_MeshSlot& ms); void ReleaseAlloc(); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 1a9a28916de..50f56db0645 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -35,11 +35,20 @@ #include "RAS_Rect.h" #include "RAS_TexVert.h" +#include "RAS_MeshObject.h" #include "MT_CmMatrix4x4.h" #include "RAS_IRenderTools.h" // rendering text #include "GPU_draw.h" #include "GPU_material.h" +#include "GPU_extensions.h" + +#include "DNA_image_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_material_types.h" +#include "DNA_scene_types.h" + +#include "BKE_DerivedMesh.h" /** * 32x32 bit masks for vinterlace stereo mode @@ -703,6 +712,51 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) IndexPrimitivesInternal(ms, true); } +static bool current_wireframe; +static RAS_MaterialBucket *current_bucket; +static RAS_IPolyMaterial *current_polymat; +static RAS_MeshSlot *current_ms; +static RAS_MeshObject *current_mesh; +static int current_blmat_nr; +static GPUVertexAttribs current_gpu_attribs; +static int CheckMaterialDM(int matnr, void *attribs) +{ + // only draw the current material + if (matnr != current_blmat_nr) + return 0; + GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; + if (gattribs) + memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); + return 1; +} +static int CheckTexfaceDM(void *mcol, int index) +{ + + // index is the original face index, retrieve the polygon + RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? + current_mesh->GetPolygon(index) : NULL; + if (polygon && polygon->GetMaterial() == current_bucket) { + // must handle color. + if (current_wireframe) + return 2; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + return 2; + } + if (!mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + glColor4ubv((const GLubyte *)rgba); + return 2; + } + return 1; + } + return 0; +} + void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) { bool obcolor = ms.m_bObjectColor; @@ -710,6 +764,31 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) MT_Vector4& rgba = ms.m_RGBAcolor; RAS_MeshSlot::iterator it; + if (ms.m_pDerivedMesh) { + // mesh data is in derived mesh, + current_bucket = ms.m_bucket; + current_polymat = current_bucket->GetPolyMaterial(); + current_ms = &ms; + current_mesh = ms.m_mesh; + current_wireframe = wireframe; + MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); + if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { + // GetMaterialIndex return the original mface material index, + // increment by 1 to match what derived mesh is doing + current_blmat_nr = current_polymat->GetMaterialIndex()+1; + // For GLSL we need to retrieve the GPU material attribute + Material* blmat = current_polymat->GetBlenderMaterial(); + Scene* blscene = current_polymat->GetBlenderScene(); + if (!wireframe && blscene && blmat) + GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); + else + memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); + ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); + } else { + ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); + } + return; + } // iterate over display arrays, each containing an index + vertex array for(ms.begin(it); !ms.end(it); ms.next(it)) { RAS_TexVert *vertex; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index 2cb3b52adfb..00f0f27b6c1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -110,6 +110,12 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) RAS_MeshSlot::iterator it; GLenum drawmode; + if (ms.m_pDerivedMesh) { + // cannot be handled here, pass to RAS_OpenGLRasterizer + RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false); + return; + } + if(!wireframe) glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -167,6 +173,12 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) RAS_MeshSlot::iterator it; GLenum drawmode; + if (ms.m_pDerivedMesh) { + // cannot be handled here, pass to RAS_OpenGLRasterizer + RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true); + return; + } + if(!wireframe) EnableTextures(true); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index 6731da9a776..314630297e0 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -5,6 +5,8 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines ' incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] +incs += ' #source/blender/gameengine/Ketsji #source/blender/makesdna #source/blender/blenkernel' +incs += ' #intern/guardedalloc #source/blender/blenlib' cxxflags = [] if env['OURPLATFORM']=='win32-vc': From aa3c9ad0d8061f0087ba94da3ba96ff03716b717 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 12:42:37 +0000 Subject: [PATCH 012/444] needed to remove gen_utils functions from Mathutils.c --- source/blender/python/api2_2x/Mathutils.c | 509 ++++++++++++---------- source/blender/python/api2_2x/Mathutils.h | 13 - source/blender/python/api2_2x/vector.c | 2 +- 3 files changed, 272 insertions(+), 252 deletions(-) diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index c85d781f4dd..9217d94ba1c 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -162,8 +162,8 @@ PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) if(mat->rowSize != vec->size){ if(mat->rowSize == 4 && vec->size != 3){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "matrix * vector: matrix row size and vector size must be the same"); + PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same"); + return NULL; }else{ vecCopy[3] = 1.0f; } @@ -197,8 +197,8 @@ PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) if(mat->colSize != vec_size){ if(mat->rowSize == 4 && vec_size != 3){ - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "vector * matrix: matrix column size and the vector size must be the same"); + PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); + return NULL; }else{ vecCopy[3] = 1.0f; } @@ -267,8 +267,9 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) } } - return (EXPP_ReturnPyObjError(PyExc_RuntimeError, - "quat_rotation(internal): internal problem rotating vector/point\n")); + PyErr_SetString(PyExc_RuntimeError, "quat_rotation(internal): internal problem rotating vector/point\n"); + return NULL; + } //----------------------------------Mathutils.Rand() -------------------- @@ -281,14 +282,15 @@ PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args) high = 1.0; low = 0.0; - if(!PyArg_ParseTuple(args, "|ff", &low, &high)) - return (EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Rand(): expected nothing or optional (float, float)\n")); - - if((high < low) || (high < 0 && low > 0)) - return (EXPP_ReturnPyObjError(PyExc_ValueError, - "Mathutils.Rand(): high value should be larger than low value\n")); + if(!PyArg_ParseTuple(args, "|ff", &low, &high)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.Rand(): expected nothing or optional (float, float)\n"); + return NULL; + } + if((high < low) || (high < 0 && low > 0)) { + PyErr_SetString(PyExc_ValueError, "Mathutils.Rand(): high value should be larger than low value\n"); + return NULL; + } //get the random number 0 - 1 drand = BLI_drand(); @@ -317,40 +319,42 @@ PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args) size = PySequence_Length(listObject); } else { // Single argument was not a sequence Py_XDECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + return NULL; } } else if (size == 0) { //returns a new empty 3d vector return newVectorObject(NULL, 3, Py_NEW); } else { - listObject = EXPP_incr_ret(args); + Py_INCREF(args); + listObject = args; } if (size<2 || size>4) { // Invalid vector size Py_XDECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + return NULL; } for (i=0; isize != 3 || vec2->size != 3) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.CrossVecs(): expects (2) 3D vector objects\n"); - + if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.CrossVecs(): expects (2) 3D vector objects\n"); + return NULL; + } + + if(vec1->size != 3 || vec2->size != 3) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.CrossVecs(): expects (2) 3D vector objects\n"); + return NULL; + } vecCross = newVectorObject(NULL, 3, Py_NEW); Crossf(((VectorObject*)vecCross)->vec, vec1->vec, vec2->vec); return vecCross; @@ -381,12 +387,15 @@ PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args) double dot = 0.0f; int x; - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.DotVecs(): expects (2) vector objects of the same size\n"); - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.DotVecs(): expects (2) vector objects of the same size\n"); + if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.DotVecs(): expects (2) vector objects of the same size\n"); + return NULL; + } + + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.DotVecs(): expects (2) vector objects of the same size\n"); + return NULL; + } for(x = 0; x < vec1->size; x++) { dot += vec1->vec[x] * vec2->vec[x]; @@ -428,12 +437,12 @@ PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) return PyFloat_FromDouble(angleRads * (180/ Py_PI)); AttributeError1: - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n"); + return NULL; AttributeError2: - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.AngleBetweenVecs(): zero length vectors are not acceptable arguments\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): zero length vectors are not acceptable arguments\n"); + return NULL; } //----------------------------------Mathutils.MidpointVecs() ------------- //calculates the midpoint between 2 vectors @@ -443,12 +452,14 @@ PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) float vec[4]; int x; - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); + if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); + return NULL; + } + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); + return NULL; + } for(x = 0; x < vec1->size; x++) { vec[x] = 0.5f * (vec1->vec[x] + vec2->vec[x]); @@ -464,12 +475,14 @@ PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) double dot = 0.0f, dot2 = 0.0f; int x, size; - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n"); - if(vec1->size != vec2->size) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n"); + if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n"); + return NULL; + } + if(vec1->size != vec2->size) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n"); + return NULL; + } //since they are the same size... size = vec1->size; @@ -501,8 +514,8 @@ PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args) argSize = PySequence_Length(args); if(argSize > 4){ //bad arg nums - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; } else if (argSize == 0) { //return empty 4D matrix return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW); }else if (argSize == 1){ @@ -525,15 +538,15 @@ PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args) if(seqSize){ //0 at first if(PySequence_Length(argObject) != seqSize){ //seq size not same Py_DECREF(argObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; } } seqSize = PySequence_Length(argObject); }else{ //arg not a sequence Py_XDECREF(argObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; } Py_DECREF(argObject); } @@ -542,27 +555,29 @@ PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args) for (i = 0; i < argSize; i++){ m = PySequence_GetItem(listObject, i); if (m == NULL) { // Failed to read sequence - return EXPP_ReturnPyObjError(PyExc_RuntimeError, - "Mathutils.Matrix(): failed to parse arguments...\n"); + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n"); + return NULL; } for (j = 0; j < seqSize; j++) { s = PySequence_GetItem(m, j); - if (s == NULL) { // Failed to read sequence + if (s == NULL) { // Failed to read sequence Py_DECREF(m); - return EXPP_ReturnPyObjError(PyExc_RuntimeError, - "Mathutils.Matrix(): failed to parse arguments...\n"); + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n"); + return NULL; } f = PyNumber_Float(s); if(f == NULL) { // parsed item is not a number - EXPP_decr2(m,s); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + Py_DECREF(m); + Py_DECREF(s); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; } matrix[(seqSize*i)+j]=(float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(f,s); + Py_DECREF(f); + Py_DECREF(s); } Py_DECREF(m); } @@ -581,10 +596,9 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) 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(!PyArg_ParseTuple - (args, "fi|sO!", &angle, &matSize, &axis, &vector_Type, &vec)) { - return EXPP_ReturnPyObjError (PyExc_TypeError, - "Mathutils.RotationMatrix(): expected float int and optional string and vector\n"); + if(!PyArg_ParseTuple(args, "fi|sO!", &angle, &matSize, &axis, &vector_Type, &vec)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n"); + return NULL; } /* Clamp to -360:360 */ @@ -593,25 +607,29 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) while (angle>360.0f) angle-=360.0; - if(matSize != 2 && matSize != 3 && matSize != 4) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); - if(matSize == 2 && (axis != NULL || vec != NULL)) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis\n"); - if((matSize == 3 || matSize == 4) && axis == NULL) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.RotationMatrix(): please choose an axis of rotation for 3d and 4d matrices\n"); + if(matSize != 2 && matSize != 3 && matSize != 4) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); + return NULL; + } + if(matSize == 2 && (axis != NULL || vec != NULL)) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis\n"); + return NULL; + } + if((matSize == 3 || matSize == 4) && axis == NULL) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): please choose an axis of rotation for 3d and 4d matrices\n"); + return NULL; + } if(axis) { - if(((strcmp(axis, "r") == 0) || - (strcmp(axis, "R") == 0)) && vec == NULL) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.RotationMatrix(): please define the arbitrary axis of rotation\n"); + if(((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) && vec == NULL) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): please define the arbitrary axis of rotation\n"); + return NULL; + } } if(vec) { - if(vec->size != 3) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n"); + if(vec->size != 3) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n"); + return NULL; + } } //convert to radians angle = angle * (float) (Py_PI / 180); @@ -679,8 +697,8 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) cosAngle; } } else { - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n"); + return NULL; } if(matSize == 4) { //resize matrix @@ -704,12 +722,12 @@ PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; if(!VectorObject_Check(vec)) { - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.TranslationMatrix(): expected vector\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.TranslationMatrix(): expected vector\n"); + return NULL; } if(vec->size != 3 && vec->size != 4) { - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.TranslationMatrix(): vector must be 3D or 4D\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.TranslationMatrix(): vector must be 3D or 4D\n"); + return NULL; } //create a identity matrix and add translation Mat4One((float(*)[4]) mat); @@ -730,18 +748,19 @@ PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) 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(!PyArg_ParseTuple - (args, "fi|O!", &factor, &matSize, &vector_Type, &vec)) { - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.ScaleMatrix(): expected float int and optional vector\n"); + if(!PyArg_ParseTuple(args, "fi|O!", &factor, &matSize, &vector_Type, &vec)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.ScaleMatrix(): expected float int and optional vector\n"); + return NULL; + } + if(matSize != 2 && matSize != 3 && matSize != 4) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.ScaleMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); + return NULL; } - if(matSize != 2 && matSize != 3 && matSize != 4) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.ScaleMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); if(vec) { - if(vec->size > 2 && matSize == 2) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n"); + if(vec->size > 2 && matSize == 2) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n"); + return NULL; + } } if(vec == NULL) { //scaling along axis if(matSize == 2) { @@ -804,18 +823,19 @@ PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args) 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(!PyArg_ParseTuple - (args, "si|O!", &plane, &matSize, &vector_Type, &vec)) { - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.OrthoProjectionMatrix(): expected string and int and optional vector\n"); + if(!PyArg_ParseTuple(args, "si|O!", &plane, &matSize, &vector_Type, &vec)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.OrthoProjectionMatrix(): expected string and int and optional vector\n"); + return NULL; + } + if(matSize != 2 && matSize != 3 && matSize != 4) { + PyErr_SetString(PyExc_AttributeError,"Mathutils.OrthoProjectionMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); + return NULL; } - if(matSize != 2 && matSize != 3 && matSize != 4) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.OrthoProjectionMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); if(vec) { - if(vec->size > 2 && matSize == 2) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n"); + if(vec->size > 2 && matSize == 2) { + PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n"); + return NULL; + } } if(vec == NULL) { //ortho projection onto cardinal plane if(((strcmp(plane, "x") == 0) @@ -841,8 +861,8 @@ PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args) mat[4] = 1.0f; mat[8] = 1.0f; } else { - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: x, y, xy, xz, yz\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: x, y, xy, xz, yz\n"); + return NULL; } } else { //arbitrary plane //normalize arbitrary axis @@ -872,8 +892,8 @@ PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args) mat[7] = -(vec->vec[1] * vec->vec[2]); mat[8] = 1 - (vec->vec[2] * vec->vec[2]); } else { - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: 'r' expected for axis designation\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: 'r' expected for axis designation\n"); + return NULL; } } if(matSize == 4) { @@ -901,12 +921,13 @@ PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; if(!PyArg_ParseTuple(args, "sfi", &plane, &factor, &matSize)) { - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.ShearMatrix(): expected string float and int\n"); + PyErr_SetString(PyExc_TypeError,"Mathutils.ShearMatrix(): expected string float and int\n"); + return NULL; + } + if(matSize != 2 && matSize != 3 && matSize != 4) { + PyErr_SetString(PyExc_AttributeError,"Mathutils.ShearMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); + return NULL; } - if(matSize != 2 && matSize != 3 && matSize != 4) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.ShearMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); if(((strcmp(plane, "x") == 0) || (strcmp(plane, "X") == 0)) && matSize == 2) { @@ -939,8 +960,8 @@ PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) mat[4] = 1.0f; mat[8] = 1.0f; } else { - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.ShearMatrix(): expected: x, y, xy, xz, yz or wrong matrix size for shearing plane\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.ShearMatrix(): expected: x, y, xy, xz, yz or wrong matrix size for shearing plane\n"); + return NULL; } if(matSize == 4) { //resize matrix @@ -974,15 +995,15 @@ PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) (size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) { // invalid args/size Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } if(size == 3){ //get angle in axis/angle n = PyNumber_Float(PySequence_GetItem(args, 1)); if(n == NULL) { // parsed item not a number or getItem fail Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } angle = PyFloat_AS_DOUBLE(n); Py_DECREF(n); @@ -994,40 +1015,41 @@ PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) if (size != 3) { // invalid args/size Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } n = PyNumber_Float(PySequence_GetItem(args, 0)); if(n == NULL) { // parsed item not a number or getItem fail Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } angle = PyFloat_AS_DOUBLE(n); Py_DECREF(n); } else { // argument was not a sequence Py_XDECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } } } else if (size == 0) { //returns a new empty quat return newQuaternionObject(NULL, Py_NEW); } else { - listObject = EXPP_incr_ret(args); + Py_INCREF(args); + listObject = args; } if (size == 3) { // invalid quat size if(PySequence_Length(args) != 2){ Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } }else{ if(size != 4){ Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } } @@ -1035,19 +1057,21 @@ PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) q = PySequence_GetItem(listObject, i); if (q == NULL) { // Failed to read sequence Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_RuntimeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } f = PyNumber_Float(q); if(f == NULL) { // parsed item not a number - EXPP_decr2(q, listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + Py_DECREF(q); + Py_DECREF(listObject); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; } quat[i] = (float)PyFloat_AS_DOUBLE(f); - EXPP_decr2(f, q); + Py_DECREF(f); + 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]); @@ -1072,9 +1096,10 @@ PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args) QuaternionObject *quatU = NULL, *quatV = NULL; float quat[4]; - if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, - &quaternion_Type, &quatV)) - return EXPP_ReturnPyObjError(PyExc_TypeError,"Mathutils.CrossQuats(): expected Quaternion types"); + if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) { + PyErr_SetString(PyExc_TypeError,"Mathutils.CrossQuats(): expected Quaternion types"); + return NULL; + } QuatMul(quat, quatU->quat, quatV->quat); return newQuaternionObject(quat, Py_NEW); @@ -1087,9 +1112,10 @@ PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args) double dot = 0.0f; int x; - if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, - &quaternion_Type, &quatV)) - return EXPP_ReturnPyObjError(PyExc_TypeError, "Mathutils.DotQuats(): expected Quaternion types"); + if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.DotQuats(): expected Quaternion types"); + return NULL; + } for(x = 0; x < 4; x++) { dot += quatU->quat[x] * quatV->quat[x]; @@ -1105,10 +1131,10 @@ PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) double dot = 0.0f; int x; - if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, - &quatU, &quaternion_Type, &quatV)) - return EXPP_ReturnPyObjError(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types"); - + if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types"); + return NULL; + } tempQuat[0] = quatU->quat[0]; tempQuat[1] = -quatU->quat[1]; tempQuat[2] = -quatU->quat[2]; @@ -1132,14 +1158,14 @@ PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) double x, y, dot, sinT, angle, IsinT; int z; - if(!PyArg_ParseTuple(args, "O!O!f", &quaternion_Type, - &quatU, &quaternion_Type, &quatV, ¶m)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Slerp(): expected Quaternion types and float"); - - if(param > 1.0f || param < 0.0f) - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0"); + if(!PyArg_ParseTuple(args, "O!O!f", &quaternion_Type, &quatU, &quaternion_Type, &quatV, ¶m)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float"); + 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; + } //copy quats for(z = 0; z < 4; z++){ @@ -1198,39 +1224,42 @@ PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args) size = PySequence_Length(listObject); } else { // Single argument was not a sequence Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.Euler(): 3d numeric sequence expected\n"); + PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); + return NULL; } } else if (size == 0) { //returns a new empty 3d euler return newEulerObject(NULL, Py_NEW); } else { - listObject = EXPP_incr_ret(args); + Py_INCREF(args); + listObject = args; } if (size != 3) { // Invalid euler size Py_DECREF(listObject); - return EXPP_ReturnPyObjError(PyExc_AttributeError, - "Mathutils.Euler(): 3d numeric sequence expected\n"); + PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); + return NULL; } for (i=0; isize != 3 || vec2->size != 3 || vec3->size != 3 || - ray->size != 3 || ray_off->size != 3) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "only 3D vectors for all parameters\n" ) ); + if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) { + PyErr_SetString( PyExc_TypeError, "expected 5 vector types\n" ); + return NULL; + } + if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) { + PyErr_SetString( PyExc_TypeError, "only 3D vectors for all parameters\n"); + return NULL; + } VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); @@ -1275,7 +1303,7 @@ PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) det = Inpf(e1, pvec); if (det > -0.000001 && det < 0.000001) { - return EXPP_incr_ret( Py_None ); + Py_RETURN_NONE; } inv_det = 1.0f / det; @@ -1286,7 +1314,7 @@ PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) /* calculate U parameter and test bounds */ u = Inpf(tvec, pvec) * inv_det; if (clip && (u < 0.0f || u > 1.0f)) { - return EXPP_incr_ret( Py_None ); + Py_RETURN_NONE; } /* prepare to test the V parameter */ @@ -1296,7 +1324,7 @@ PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) v = Inpf(dir, qvec) * inv_det; if (clip && (v < 0.0f || u + v > 1.0f)) { - return EXPP_incr_ret( Py_None ); + Py_RETURN_NONE; } /* calculate t, ray intersects triangle */ @@ -1315,15 +1343,14 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) VectorObject *vec1, *vec2, *vec3, *vec4; float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3]; - if( !PyArg_ParseTuple - ( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 - , &vector_Type, &vec3, &vector_Type, &vec4 ) ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 4 vector types\n" ) ); - if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "vectors must be of the same size\n" ) ); - + if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) { + PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" ); + return NULL; + } + if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) { + PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); + return NULL; + } if( vec1->size == 3 || vec1->size == 2) { int result; @@ -1355,7 +1382,7 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) if (result == 0) { /* colinear */ - return EXPP_incr_ret( Py_None ); + Py_RETURN_NONE; } else { tuple = PyTuple_New( 2 ); @@ -1365,8 +1392,8 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) } } else { - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "2D/3D vectors only\n" ) ); + PyErr_SetString( PyExc_TypeError, "2D/3D vectors only\n" ); + return NULL; } } @@ -1382,18 +1409,18 @@ PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) VectorObject *vec4; float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3], n1[3], n2[3]; - if( !PyArg_ParseTuple - ( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 - , &vector_Type, &vec3, &vector_Type, &vec4 ) ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 4 vector types\n" ) ); - if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "vectors must be of the same size\n" ) ); - if( vec1->size != 3 ) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "only 3D vectors\n" ) ); - + if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) { + PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" ); + return NULL; + } + if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) { + PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); + return NULL; + } + if( vec1->size != 3 ) { + PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); + return NULL; + } VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -1426,17 +1453,18 @@ PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) VectorObject *vec1, *vec2, *vec3; float v1[3], v2[3], v3[3], e1[3], e2[3], n[3]; - if( !PyArg_ParseTuple - ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 - , &vector_Type, &vec3 ) ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 3 vector types\n" ) ); - if( vec1->size != vec2->size || vec1->size != vec3->size ) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "vectors must be of the same size\n" ) ); - if( vec1->size != 3 ) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "only 3D vectors\n" ) ); + if( !PyArg_ParseTuple( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3 ) ) { + PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" ); + return NULL; + } + if( vec1->size != vec2->size || vec1->size != vec3->size ) { + PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" ); + return NULL; + } + if( vec1->size != 3 ) { + PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); + return NULL; + } VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); @@ -1461,12 +1489,14 @@ PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) if( !PyArg_ParseTuple ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 - , &vector_Type, &vec3 ) ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 3 vector types\n" ) ); - if( vec1->size != vec2->size || vec1->size != vec3->size ) - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "vectors must be of the same size\n" ) ); + , &vector_Type, &vec3 ) ) { + PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n"); + return NULL; + } + if( vec1->size != vec2->size || vec1->size != vec3->size ) { + PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" ); + return NULL; + } if (vec1->size == 3) { VECCOPY(v1, vec1->vec); @@ -1488,8 +1518,8 @@ PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) return PyFloat_FromDouble( AreaF2Dfl(v1, v2, v3) ); } else { - return ( EXPP_ReturnPyObjError( PyExc_TypeError, - "only 2D,3D vectors are supported\n" ) ); + PyErr_SetString( PyExc_TypeError, "only 2D,3D vectors are supported\n" ); + return NULL; } } //#############################DEPRECATED################################ @@ -1581,9 +1611,10 @@ PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args) --warning; } - if(!PyArg_ParseTuple(args, "O!fs", &euler_Type, &Eul, &angle, &axis)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.RotateEuler(): expected euler type & float & string"); + if(!PyArg_ParseTuple(args, "O!fs", &euler_Type, &Eul, &angle, &axis)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.RotateEuler(): expected euler type & float & string"); + return NULL; + } Euler_Rotate(Eul, Py_BuildValue("fs", angle, axis)); Py_RETURN_NONE; @@ -1602,9 +1633,10 @@ PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args) } //get pyObjects - if(!PyArg_ParseTuple(args, "O!O!", &matrix_Type, &mat, &vector_Type, &vec)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.MatMultVec(): MatMultVec() expects a matrix and a vector object - in that order\n"); + if(!PyArg_ParseTuple(args, "O!O!", &matrix_Type, &mat, &vector_Type, &vec)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.MatMultVec(): MatMultVec() expects a matrix and a vector object - in that order\n"); + return NULL; + } return column_vector_multiplication(mat, vec); } @@ -1622,9 +1654,10 @@ PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args) } //get pyObjects - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec, &matrix_Type, &mat)) - return EXPP_ReturnPyObjError(PyExc_TypeError, - "Mathutils.VecMultMat(): VecMultMat() expects a vector and matrix object - in that order\n"); + if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec, &matrix_Type, &mat)) { + PyErr_SetString(PyExc_TypeError, "Mathutils.VecMultMat(): VecMultMat() expects a vector and matrix object - in that order\n"); + return NULL; + } return row_vector_multiplication(vec, mat); } diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index d3d3354d42f..abbf14463a6 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -83,17 +83,4 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); #define Py_WRAP 1024 #define Py_NEW 2048 - -/* Allow us to build with Py3k */ -#if (PY_VERSION_HEX >= 0x03000000) -#define PyString_FromString PyUnicode_FromString -#define intobjargproc ssizeobjargproc -#define intintobjargproc ssizessizeobjargproc -#define intargfunc ssizeargfunc -#define intintargfunc ssizessizeargfunc - - -#endif - - #endif /* EXPP_Mathutils_H */ diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index f65c4dff600..dd53cca9054 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -57,7 +57,7 @@ struct PyMethodDef Vector_methods[] = { {NULL, NULL, 0, NULL} }; -/*-----------------------------METHODS---------------------------- +/*-----------------------------METHODS---------------------------- */ /*----------------------------Vector.zero() ---------------------- set the vector data to 0,0,0 */ PyObject *Vector_Zero(VectorObject * self) From 8b69260f00c32a1ef53c4600684f3271667d800b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 12:48:49 +0000 Subject: [PATCH 013/444] hope this lets py2.3 build again --- source/blender/python/api2_2x/Mathutils.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index abbf14463a6..7406c5c4810 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -83,4 +83,17 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); #define Py_WRAP 1024 #define Py_NEW 2048 + +/* Mathutils is used by the BGE and Blender so have to define + * some things here for luddite mac users of py2.3 */ +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif +#ifndef Py_RETURN_FALSE +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#endif +#ifndef Py_RETURN_TRUE +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#endif + #endif /* EXPP_Mathutils_H */ From ca78b6ee8b7b3eacf2c0cb17fb2570f94dac91b8 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 21 Apr 2009 13:30:58 +0000 Subject: [PATCH 014/444] Bugfix #18519 MultiLayer save (F3) crashes when no rendering/layers exist, happens for opengl preview render. It now survives, saving empty file and prints error. Better solution for later: render profiles! --- .../imbuf/intern/openexr/openexr_api.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 3e618a483e3..9e077cbc809 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -570,13 +570,17 @@ void IMB_exr_write_channels(void *handle) FrameBuffer frameBuffer; ExrChannel *echan; - for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) - frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, - echan->xstride*sizeof(float), echan->ystride*sizeof(float))); - - data->ofile->setFrameBuffer (frameBuffer); - data->ofile->writePixels (data->height); - + if(data->channels.first) { + for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) + frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect, + echan->xstride*sizeof(float), echan->ystride*sizeof(float))); + + data->ofile->setFrameBuffer (frameBuffer); + data->ofile->writePixels (data->height); + } + else { + printf("Error: attempt to save MultiLayer without layers.\n"); + } } void IMB_exr_read_channels(void *handle) From aff2a11110c84fc84764c2108981411275a2dda2 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 21 Apr 2009 13:34:33 +0000 Subject: [PATCH 015/444] Fix for missing include using CMake --- source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index 322d7b79e6f..d061a449b7e 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -37,6 +37,7 @@ SET(INC ../../../../source/blender/makesdna ../../../../source/blender/blenkernel ../../../../source/blender/blenlib + ../../../../source/blender/blenloader ) BLENDERLIB(bf_oglrasterizer "${SRC}" "${INC}") From 4cf2863a8f5ece6176f40adb6681beb2d75b8c9e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 13:44:24 +0000 Subject: [PATCH 016/444] SHD_dynamic had gen_utils functions from Mathutils, removing --- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 88efd47fa66..9a8f2f13d65 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -51,13 +51,15 @@ static void node_dynamic_free_storage_cb(bNode *node); #ifndef DISABLE_PYTHON static PyObject *init_dynamicdict(void) { - PyObject *newscriptdict; + PyObject *newscriptdict, *item; PyGILState_STATE gilstate = PyGILState_Ensure(); newscriptdict= PyDict_New(); PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins()); - EXPP_dict_set_item_str(newscriptdict, "__name__", PyString_FromString("__main__")); + item= PyString_FromString("__main__"); + PyDict_SetItemString(newscriptdict, "__name__", item); + Py_DECREF(item); PyGILState_Release(gilstate); From 5d0fb28f74648e6bf07887bd442740fc45792347 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 21 Apr 2009 15:22:41 +0000 Subject: [PATCH 017/444] bugfix #18543 Using feature XRay + Transparent could crash on undo/redo, the view3d afterdraw was still storing data here whilst it shouldn't... Reason was that object got added twice actually... but only freed once. Also caused weird flashy display. Note to Brecht for merging: skip this one, I'll fix it in 2.5 too. --- source/blender/src/drawobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index c9fffa407ee..5fb60449a25 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -4738,7 +4738,7 @@ void draw_object(Base *base, int flag) /* don't do xray in particle mode, need the z-buffer */ if(!(G.f & G_PARTICLEEDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ - if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) { + if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { add_view3d_after(G.vd, base, V3D_XRAY, flag); return; } From 6c33cc9bae9a565ee2ea5247754c6a4b127795bf Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 21 Apr 2009 15:38:53 +0000 Subject: [PATCH 018/444] Bugfix #18550 "Copy constraints" should increase ipo user count. --- source/blender/blenkernel/intern/constraint.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index f93fc403404..6b6f4a58e79 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3551,6 +3551,8 @@ void copy_constraints (ListBase *dst, ListBase *src) /* make a new copy of the constraint's data */ con->data = MEM_dupallocN(con->data); + id_us_plus((ID *)con->ipo); + /* only do specific constraints if required */ if (cti && cti->copy_data) cti->copy_data(con, srccon); From a82a6bedc55fe676c11bf36f1017c0cbddcd9ca2 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 21 Apr 2009 16:58:25 +0000 Subject: [PATCH 019/444] Fix for bug #17457. This bug relates to files that have missing multires vertex data. The fix is, if the file was saved on the highest multires level, then mesh contains a copy of the vertices anyway, and we can just copy it back into multires. Otherwise, multires is removed from the mesh to avoid a crash. --- source/blender/blenkernel/intern/multires.c | 3 ++- source/blender/blenloader/intern/readfile.c | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 4d312632b1a..8112c64d79f 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -111,7 +111,8 @@ void multires_free(Multires *mr) lvl= lvl->next; } - MEM_freeN(mr->verts); + if(mr->verts) + MEM_freeN(mr->verts); BLI_freelistN(&mr->levels); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c88e06a9993..477f5a6cb59 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2876,6 +2876,18 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) lvl->map_mem= NULL; } } + + /* Gracefully handle corrupted mesh */ + if(mesh->mr && !mesh->mr->verts) { + /* If totals match, simply load the current mesh verts into multires */ + if(mesh->totvert == ((MultiresLevel*)mesh->mr->levels.last)->totvert) + mesh->mr->verts = MEM_dupallocN(mesh->mvert); + else { + /* Otherwise, we can't recover the data, silently remove multires */ + multires_free(mesh->mr); + mesh->mr = NULL; + } + } if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) { TFace *tf= mesh->tface; From 95b43536f6c1da49b8ee94c287e84686c6732a8f Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 21 Apr 2009 17:24:16 +0000 Subject: [PATCH 020/444] Some Makefile changes still laying around. --- Makefile | 19 +++++----- extern/Makefile | 7 ++-- po/Makefile | 44 +++++++++++++---------- source/Makefile | 5 ++- source/blender/blenkernel/intern/Makefile | 2 +- 5 files changed, 42 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index b983779fb31..42475dba31c 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*- +# vim: tabstop=8 # $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** @@ -31,12 +33,11 @@ # If the user wants to override some of the build # vars they can put it in the file user-def.mk which # will get included if it exists (please do not commit -# user-def.mk to cvs). - +# user-def.mk to the revision control server). sinclude user-def.mk -# To build without openAL, uncomment the following line, or set it as -# an environment variable, or put it uncommented in user-def.mk: +# To build without openAL, set it as an environment variable, +# or put it uncommented in user-def.mk: # export NAN_NO_OPENAL=true export NANBLENDERHOME=$(shell pwd) @@ -44,13 +45,9 @@ MAKEFLAGS=-I$(NANBLENDERHOME)/source --no-print-directory SOURCEDIR = ifeq ($(FREE_WINDOWS),true) - DIRS ?= dlltool extern intern source -endif - -DIRS ?= extern intern source - -ifneq ($(INTERNATIONAL),false) - DIRS += po + DIRS ?= dlltool extern intern source po +else + DIRS ?= extern intern source po endif include source/nan_subdirs.mk diff --git a/extern/Makefile b/extern/Makefile index 38bec4b73dd..29d7da5b822 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -49,9 +49,10 @@ ifeq ($(WITH_VERSE), true) DIRS += verse endif -ifneq ($(NAN_NO_KETSJI), true) - DIRS += bullet2 -endif +# Cloth requires it +#ifneq ($(NAN_NO_KETSJI), true) +DIRS += bullet2 +#endif ifeq ($(WITH_BINRELOC), true) DIRS += binreloc diff --git a/po/Makefile b/po/Makefile index 4bafba8a6e6..425efbc08b3 100644 --- a/po/Makefile +++ b/po/Makefile @@ -1,3 +1,5 @@ +# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*- +# vim: tabstop=8 # $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** @@ -9,47 +11,51 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # The Original Code is Copyright (C) 2002 by Stichting Blender Foundation, # Amsterdam, the Netherlands. # All rights reserved. # -# The Original Code is: revision 1.1 +# The Original Code is: revision 1.3 # -# Contributor(s): Wouter van Heyst +# Contributor(s): Wouter van Heyst, GSR # # ***** END GPL LICENSE BLOCK ***** # -# po Makefile for blender. Compiles the translations and places them +# po Makefile for blender. Compiles the translations in the place # where release can pick them up. +PO_FILES = $(wildcard *.po) + +LINGUAS = $(basename $(PO_FILES)) + SOURCEDIR = blender/po include nan_definitions.mk -LINGUAS = ar bg ca cs de el es fi fr hr it ja ko nl pl pt_BR ro ru sr sr@Latn sv uk zh_CN - ifeq ($(OS), darwin) -DIR = $(OCGDIR)/bin/blender.app/Contents/Resources/locale/$@/LC_MESSAGES/ + DIR = $(OCGDIR)/bin/blender.app/Contents/Resources/locale/ else -DIR = $(OCGDIR)/bin/.blender/locale/$@/LC_MESSAGES/ + DIR = $(OCGDIR)/bin/.blender/locale/ endif -all debug:: $(LINGUAS) +LINGUAS_DEST= $(foreach LINGUA, $(LINGUAS),$(DIR)$(LINGUA)/LC_MESSAGES/blender.mo) + +$(DIR)%/LC_MESSAGES/blender.mo: %.po + mkdir -p $(@D) + msgfmt -o $@ $< + @cmp $@ $(NANBLENDERHOME)/bin/.blender/locale/$(basename $<)/LC_MESSAGES/blender.mo \ + || ( echo Mismatch between generated and commited $(basename $<).mo catalog && \ + rm -f $@ && false ) + +all debug:: $(LINGUAS_DEST) +# Just trigger the deps clean:: -ifeq ($(OS), darwin) - rm -rf $(OCGDIR)/bin/blender.app/Contents/Resources/locale/ -else - rm -rf $(OCGDIR)/bin/.blender/locale/ -endif - -$(LINGUAS): - mkdir -p $(DIR) - msgfmt -o $(DIR)/blender.mo $@.po + rm -rf $(DIR) diff --git a/source/Makefile b/source/Makefile index d8dee601998..b190118bc38 100644 --- a/source/Makefile +++ b/source/Makefile @@ -83,7 +83,7 @@ GRPLIB += $(NAN_STRING)/lib/$(DEBUG_DIR)libstring.a GRPLIB += $(OCGDIR)/blender/render/$(DEBUG_DIR)librender.a GRPLIB += $(OCGDIR)/blender/radiosity/$(DEBUG_DIR)libradiosity.a GRPLIB += $(NAN_OPENNL)/lib/$(DEBUG_DIR)libopennl.a -GRPLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a +GRPLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a GRPLIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a # nlin: the reason that some libraries appear more than once below is @@ -154,6 +154,9 @@ ifneq ($(NAN_NO_KETSJI),true) COMLIB += $(NAN_BULLET2)/lib/libbullet2.a endif +# Cloth requires bullet2, gameegine does not matter anymore +#COMLIB += $(NAN_BULLET2)/lib/libbullet2.a + COMLIB += $(NAN_GUARDEDALLOC)/lib/libguardedalloc.a COMLIB += $(NAN_MEMUTIL)/lib/libmemutil.a COMLIB += $(NAN_BMFONT)/lib/$(DEBUG_DIR)libbmfont.a diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 226e416dad7..75f75b0c3c5 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -82,7 +82,7 @@ CPPFLAGS += -I../../gpu CPPFLAGS += -I.. # path to bullet2, for cloth -CPPFLAGS += -I../../../../extern/bullet2/src +CPPFLAGS += -I$(NAN_BULLET2)/include ifeq ($(WITH_FREETYPE2), true) CPPFLAGS += -DWITH_FREETYPE2 From c5756a9822f72579ddc1797dbe7612035a9b2bfe Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 21 Apr 2009 17:37:07 +0000 Subject: [PATCH 021/444] Compile warnings, typos and some clarifications. --- .../blender/blenkernel/bad_level_call_stubs/stubs.c | 5 +++-- source/blender/blenkernel/intern/image.c | 4 ++-- source/blender/imbuf/intern/rotate.c | 6 ++---- source/blender/include/BIF_editseq.h | 2 +- source/blender/include/blendef.h | 2 +- source/blender/src/editseq.c | 2 +- source/blender/src/header_info.c | 6 +++--- source/blender/src/meshtools.c | 12 ++++++------ source/creator/buildinfo.c | 10 +++++----- 9 files changed, 24 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 5f6472ce56e..341379de1d9 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -327,7 +327,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove) {} /* imagetexture.c stub */ void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) {} -void update_for_newframe() {} +void update_for_newframe(void) {} struct FileList; void BIF_filelist_freelib(struct FileList* filelist) {}; @@ -336,7 +336,8 @@ void BIF_filelist_freelib(struct FileList* filelist) {}; TimeMarker *get_frame_marker(int frame){return 0;}; /* editseq.c */ -Sequence *get_forground_frame_seq(int frame){return 0;}; +#include "BIF_editseq.h" // And fix the missing void there +Sequence *get_foreground_frame_seq(int frame){return 0;}; void clear_last_seq(Sequence *seq){}; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index e817c38618f..01d8ed4d41c 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -407,7 +407,7 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, sho unsigned char *rect= NULL; float *rect_float= NULL; int x, y; - int checkerwidth=21, dark=1; + int checkerwidth=32, dark=1; if (floatbuf) { ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0); @@ -1024,7 +1024,7 @@ static void stampdata(StampData *stamp_data, int do_prefix) } if (G.scene->r.stamp & R_STAMP_SEQSTRIP) { - Sequence *seq = get_forground_frame_seq(CFRA); + Sequence *seq = get_foreground_frame_seq(CFRA); if (seq) strcpy(text, seq->name+2); else strcpy(text, ""); diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c index c04987b3e71..732c06907df 100644 --- a/source/blender/imbuf/intern/rotate.c +++ b/source/blender/imbuf/intern/rotate.c @@ -30,6 +30,7 @@ */ #include "BLI_blenlib.h" +#include "BKE_utildefines.h" #include "imbuf.h" #include "imbuf_patch.h" @@ -94,7 +95,6 @@ void IMB_flipy(struct ImBuf * ibuf) void IMB_flipx(struct ImBuf * ibuf) { short x, y, xr, xl, yi; - unsigned int px; float px_f[4]; if (ibuf == NULL) return; @@ -105,9 +105,7 @@ void IMB_flipx(struct ImBuf * ibuf) if (ibuf->rect) { for(yi=y-1;yi>=0;yi--) { for(xr=x-1, xl=0; xr>=xl; xr--, xl++) { - px = ibuf->rect[(x*yi)+xr]; - ibuf->rect[(x*yi)+xr] = ibuf->rect[(x*yi)+xl]; - ibuf->rect[(x*yi)+xl] = px; + SWAP(unsigned int, ibuf->rect[(x*yi)+xr], ibuf->rect[(x*yi)+xl]); } } } diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h index be30a3eaaf3..54e99ca1828 100644 --- a/source/blender/include/BIF_editseq.h +++ b/source/blender/include/BIF_editseq.h @@ -41,7 +41,7 @@ void reload_sequence(void); void update_seq_ipo_rect(struct Sequence * seq); void update_seq_icu_rects(struct Sequence * seq); struct Sequence* get_last_seq(); -struct Sequence* get_forground_frame_seq( int frame ); +struct Sequence* get_foreground_frame_seq( int frame ); void set_last_seq(struct Sequence * seq); void clear_last_seq(); void del_seq(void); diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index dc05acc1735..8bde3da85c7 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -35,7 +35,7 @@ #define MAXFRAMEF 300000.0f #define MINFRAME 1 -#define MINFRAMEF 1.0 +#define MINFRAMEF 1.0f /* max length material array, 16 because of bits in matfrom */ #define MAXPICKBUF 10000 diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index 76e44e5c24f..e2211e56fca 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -174,7 +174,7 @@ void clear_last_seq() _last_seq_init = 0; } -Sequence *get_forground_frame_seq(int frame) +Sequence *get_foreground_frame_seq(int frame) { Editing *ed; Sequence *seq, *best_seq=NULL; diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 6e43b6073eb..612836c86e9 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -1929,7 +1929,7 @@ static uiBlock *info_timelinemenu(void *arg_unused) void do_info_render_bakemenu(void *arg, int event) { switch (event) { - case 6: + case (R_BAKE_TO_ACTIVE|R_BAKE_OSA): G.scene->r.bake_flag ^= event; break; default: @@ -1948,9 +1948,9 @@ static uiBlock *info_render_bakemenu(void *arg_unused) uiBlockSetButmFunc(block, do_info_render_bakemenu, NULL); if(G.scene->r.bake_flag & R_BAKE_TO_ACTIVE) { - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, (R_BAKE_TO_ACTIVE|R_BAKE_OSA), ""); } else { - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, (R_BAKE_TO_ACTIVE|R_BAKE_OSA), ""); } uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index 66a484eb903..db77d596025 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -650,9 +650,9 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f float fx, fy, fz; int vx, vy, vz; - if (isnan(co[0]) || !finite(co[0]) || - isnan(co[1]) || !finite(co[1]) || - isnan(co[2]) || !finite(co[2]) + if (!finite(co[0]) || + !finite(co[1]) || + !finite(co[2]) ) { return; } @@ -869,9 +869,9 @@ EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co) intptr_t poinval; /* ignore nan verts */ - if (isnan(co[0]) || !finite(co[0]) || - isnan(co[1]) || !finite(co[1]) || - isnan(co[2]) || !finite(co[2]) + if (!finite(co[0]) || + !finite(co[1]) || + !finite(co[2]) ) return NULL; diff --git a/source/creator/buildinfo.c b/source/creator/buildinfo.c index e25caa34f46..cef98915d79 100644 --- a/source/creator/buildinfo.c +++ b/source/creator/buildinfo.c @@ -33,11 +33,11 @@ #ifdef BUILD_DATE #ifndef WIN32 -char * build_date=BUILD_DATE; -char * build_time=BUILD_TIME; -char * build_rev=BUILD_REV; -char * build_platform=BUILD_PLATFORM; -char * build_type=BUILD_TYPE; +const char * build_date=BUILD_DATE; +const char * build_time=BUILD_TIME; +const char * build_rev=BUILD_REV; +const char * build_platform=BUILD_PLATFORM; +const char * build_type=BUILD_TYPE; #else #include "winbuildinfo.h" #endif From 41eb029bb9c2ab43c9feba901026ebd640be2c0a Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 21 Apr 2009 17:40:39 +0000 Subject: [PATCH 022/444] Old "divide by zero" bug and remove debug printf. --- .../nodes/intern/CMP_nodes/CMP_normalize.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c index 846aec490c2..15f3148b54c 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c @@ -55,6 +55,7 @@ static void do_normalize(bNode *node, float *out, float *src, float *min, float } } +/* The code below assumes all data is inside range +- this, and that input buffer is single channel */ #define BLENDER_ZMAX 10000.0f static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **in, bNodeStack **out) @@ -63,7 +64,7 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i /* stack order out: valbuf */ if(out[0]->hasoutput==0) return; - /* input no image? then only value operation */ + /* Input has no image buffer? Then pass the value */ if(in[0]->data==NULL) { QUATCOPY(out[0]->vec, in[0]->vec); } @@ -78,18 +79,20 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */ for (val = cbuf->rect; tot; tot--, val++) { - if ((*val > max) && (*val < BLENDER_ZMAX)) { + if ((*val > max) && (*val <= BLENDER_ZMAX)) { max = *val; } - if (*val < min) { + if ((*val < min) && (*val >= -BLENDER_ZMAX)) { min = *val; } } - mult = 1.0f/(max-min); - - printf("min %f max %f\n", min, max); - - composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL); + /* In the rare case of flat buffer, which would cause a divide by 0, just pass the input to the output */ + if ((max-min) != 0.0f) { + mult = 1.0f/(max-min); + composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL); + } else { + memcpy(stackbuf->rect, cbuf->rect, sizeof(float) * cbuf->x * cbuf->y); + } out[0]->data= stackbuf; } From 2db9f14ccd1dfd5608375c326155ed1b9b2e5222 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 21 Apr 2009 17:58:28 +0000 Subject: [PATCH 023/444] Documentation. --- source/blender/include/BIF_butspace.h | 86 ++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h index f0b37814947..c3f7574ec77 100644 --- a/source/blender/include/BIF_butspace.h +++ b/source/blender/include/BIF_butspace.h @@ -134,7 +134,89 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev); #define X4CLM2 77 #define X4CLM3 165 #define X4CLM4 232 - + +#if 0 +/* start buttons grid doc/reclacement version +/* With this system rows can easily have 1 to 4 buttons + or create perfectly aligned 1 to 4 columns layouts + + < - - - PANEL_XMAX - - - >| + < - - - PANELX - - - > + + .-- XSPACE side padding --. + | | + |.- All CLM1 | + || X2CLM2 -. X3CLM3 | + || | | | + +v|-------------|----|-------v+ + <-/ | | | + | [ But1 ] | 1 button of BUTW1 size + <- -/ | | + | [ But1 ]=[ But2 ] | 2 buttons of BUTW2 size + <- -/ | + v | [ But1 ]=[ But2 ]#[ But3 ] | 3 buttons of BUTW3 size + | | | v + ^ | [But1]#[But2]=[But3]#[But4] | | 4 buttons of BUTW3 size + | <- ^ ^ -\ | ^ + | +-------|------|-------|------+ | + | | | | | + '- YSPACE '---.--' '- X4CLM4 '- BUTH + (row to row) | + Padding based in XSPACE (= normal, # +1 pix to make all match) + + Calls like uiBlockBeginAlign/uiBlockEndAlign will make the button + to button space disappear if needed, forming a compact group, in some themes + + TODO: Figure relations, meaning and usage of + PANELY, PANEL_YMAX, PANELW, PANELH + */ +#define PANELX 320 +#define PANELY 0 +#define PANELW 318 +#define PANELH 204 + +#define XSPACE 10 +#define YSPACE 6 +#define PANEL_XMAX (PANELX - XSPACE) +#define PANEL_YMAX 210 + +/* The widths follow 300, 150, 100 and 75, which is nice (discarding spacing) + sadly spacers and integer rounding make 3 and 4 column complex cases + so they better be manually set and checked following the comments */ +#define BUTW1 (PANELX - (2 * XSPACE)) +#define BUTW2 ((BUTW1 / 2) - XSPACE) +/* Manual calc so BUTW3 + XSPACE + BUTW3 + (XSPACE+1) + BUTW3 = BUTW1 + Could be something like ((BUTW1/3)-(1+(2*XSPACE)) if starting with 300 */ +#define BUTW3 93 +/* This time BUTW4 + (XSPACE+1) + BUTW4 + XSPACE + BUTW4 + (XSPACE+1) + BUTW4 = BUTW1 + That would be ((BUTW1/4)-(2+(3*XSPACE)) if starting with 300 */ +#define BUTW4 67 +/* NOTE: Again, BUTW3 and BUTW4 values and formulas include manual tuning, + retune if base BUTW1 stops being 300 pixels. You have been warned */ +#define ICONBUTW 20 +#define BUTH 22 + +/* X axis start positions of column presets + First number declares how many columns total + Second number declares the exact column it controls + So X3CLM2 means X start position of 2nd button for a row of 3 buttons */ +#define X1CLM1 XSPACE + +#define X2CLM1 X1CLM1 +#define X2CLM2 (X2CLM1 + BUTW2 + XSPACE) + +#define X3CLM1 X1CLM1 +#define X3CLM2 (X3CLM1 + BUTW3 + XSPACE) +/* By substracting from end we already get the extra 1 pix */ +#define X3CLM3 (PANEL_XMAX - BUTW3) + +#define X4CLM1 X1CLM1 +/* Extra pix to reach the BUTW1 total size */ +#define X4CLM2 (X4CLM1 + BUTW4 + XSPACE + 1) +#define X4CLM3 (X4CLM2 + BUTW4 + XSPACE) +/* By substracting from end we already get the other extra 1 pix */ +#define X4CLM4 (PANEL_XMAX - BUTW4) +/* end buttons grid doc/replacement version */ +#endif /* if 0 */ #endif - From 094b3e81f68483aeca7c33875467c3f43dee0b0d Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 21 Apr 2009 18:41:45 +0000 Subject: [PATCH 024/444] Balance comment markers. --- source/blender/include/BIF_butspace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h index c3f7574ec77..94bf7d65832 100644 --- a/source/blender/include/BIF_butspace.h +++ b/source/blender/include/BIF_butspace.h @@ -137,7 +137,7 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev); #if 0 /* start buttons grid doc/reclacement version -/* With this system rows can easily have 1 to 4 buttons + With this system rows can easily have 1 to 4 buttons or create perfectly aligned 1 to 4 columns layouts < - - - PANEL_XMAX - - - >| From 221f589f519e9adff986281320ca681f0b1b2b7a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 21 Apr 2009 21:33:03 +0000 Subject: [PATCH 025/444] BGE bug #18521 fixed: Dupligroups + Bullet Softbodies are broken. --- source/gameengine/Ketsji/KX_Scene.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index f57a38d290d..6917305522e 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -717,12 +717,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) // set the replica's relative scale with the rootnode's scale replica->NodeSetRelativeScale(newscale); - MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation(); - replica->NodeSetLocalOrientation(newori); MT_Point3 offset(group->dupli_ofs); MT_Point3 newpos = groupobj->NodeGetWorldPosition() + newscale*(groupobj->NodeGetWorldOrientation() * (gameobj->NodeGetWorldPosition()-offset)); replica->NodeSetLocalPosition(newpos); + // set the orientation after position for softbody! + MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation(); + replica->NodeSetLocalOrientation(newori); replica->GetSGNode()->UpdateWorldData(0); replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox()); From 0145a93f2403063c22a14260e200174efb822fec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Apr 2009 23:15:18 +0000 Subject: [PATCH 026/444] Patch from Mitchell Stokes for KX_Light to use attrdef's Added type access to the SCA_PropertyActuator, added missing function in library docs. --- source/blender/python/api2_2x/doc/Library.py | 9 +- .../GameLogic/SCA_PropertyActuator.cpp | 1 + .../gameengine/GameLogic/SCA_RandomSensor.cpp | 2 + source/gameengine/Ketsji/KX_Light.cpp | 247 +++++++----------- source/gameengine/Ketsji/KX_Light.h | 7 + source/gameengine/Ketsji/KX_MeshProxy.cpp | 2 +- 6 files changed, 116 insertions(+), 152 deletions(-) diff --git a/source/blender/python/api2_2x/doc/Library.py b/source/blender/python/api2_2x/doc/Library.py index c99739d939b..68b5f2858fb 100644 --- a/source/blender/python/api2_2x/doc/Library.py +++ b/source/blender/python/api2_2x/doc/Library.py @@ -58,7 +58,7 @@ def Close (): Close the currently open library file, if any. """ -def getName (): +def GetName (): """ Get the filename of the currently open library file. @rtype: string @@ -111,4 +111,9 @@ def Update (): down your script and make you look like a lousy programmer. Enough warnings :)? """ - +def LinkedLibs(): + """ + Return a list of all libs used in the the open .blend file (direct and indirect). + @rtype: list of strings + @return: a list of blendfile names. + """ diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index beb7a09a137..4facd8df27a 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -272,6 +272,7 @@ PyMethodDef SCA_PropertyActuator::Methods[] = { PyAttributeDef SCA_PropertyActuator::Attributes[] = { KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty), KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt), + KX_PYATTRIBUTE_INT_RW("type", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */ { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 494b7a3694e..582cff4cde7 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -154,9 +154,11 @@ PyParentObject SCA_RandomSensor::Parents[] = { }; PyMethodDef SCA_RandomSensor::Methods[] = { + //Deprecated functions -----> {"setSeed", (PyCFunction) SCA_RandomSensor::sPySetSeed, METH_VARARGS, (PY_METHODCHAR)SetSeed_doc}, {"getSeed", (PyCFunction) SCA_RandomSensor::sPyGetSeed, METH_NOARGS, (PY_METHODCHAR)GetSeed_doc}, {"getLastDraw", (PyCFunction) SCA_RandomSensor::sPyGetLastDraw, METH_NOARGS, (PY_METHODCHAR)GetLastDraw_doc}, + //<----- Deprecated {NULL,NULL} //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index a1eb08e17bd..c5189907714 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -173,161 +173,15 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) GPU_lamp_shadow_buffer_unbind(lamp); } -PyObject* KX_LightObject::py_getattro(PyObject *attr) -{ - char *attr_str= PyString_AsString(attr); - - if (!strcmp(attr_str, "layer")) - return PyInt_FromLong(m_lightobj.m_layer); - - if (!strcmp(attr_str, "energy")) - return PyFloat_FromDouble(m_lightobj.m_energy); - - if (!strcmp(attr_str, "distance")) - return PyFloat_FromDouble(m_lightobj.m_distance); - - if (!strcmp(attr_str, "colour") || !strcmp(attr_str, "color")) - return Py_BuildValue("[fff]", m_lightobj.m_red, m_lightobj.m_green, m_lightobj.m_blue); - - if (!strcmp(attr_str, "lin_attenuation")) - return PyFloat_FromDouble(m_lightobj.m_att1); - - if (!strcmp(attr_str, "quad_attenuation")) - return PyFloat_FromDouble(m_lightobj.m_att2); - - if (!strcmp(attr_str, "spotsize")) - return PyFloat_FromDouble(m_lightobj.m_spotsize); - - if (!strcmp(attr_str, "spotblend")) - return PyFloat_FromDouble(m_lightobj.m_spotblend); - - if (!strcmp(attr_str, "SPOT")) - return PyInt_FromLong(RAS_LightObject::LIGHT_SPOT); - - if (!strcmp(attr_str, "SUN")) - return PyInt_FromLong(RAS_LightObject::LIGHT_SUN); - - if (!strcmp(attr_str, "NORMAL")) - return PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL); - - if (!strcmp(attr_str, "type")) - return PyInt_FromLong(m_lightobj.m_type); - - py_getattro_up(KX_GameObject); -} +/* ------------------------------------------------------------------------- */ +/* Python Integration Hooks */ +/* ------------------------------------------------------------------------- */ PyObject* KX_LightObject::py_getattro_dict() { py_getattro_dict_up(KX_GameObject); } -int KX_LightObject::py_setattro(PyObject *attr, PyObject *pyvalue) -{ - char *attr_str= PyString_AsString(attr); - - if (PyInt_Check(pyvalue)) - { - int value = PyInt_AsLong(pyvalue); - if (!strcmp(attr_str, "layer")) - { - m_lightobj.m_layer = value; - return PY_SET_ATTR_SUCCESS; - } - - if (!strcmp(attr_str, "type")) - { - if (value >= RAS_LightObject::LIGHT_SPOT && value <= RAS_LightObject::LIGHT_NORMAL) - m_lightobj.m_type = (RAS_LightObject::LightType) value; - return PY_SET_ATTR_SUCCESS; - } - } - - if (PyFloat_Check(pyvalue) || PyInt_Check(pyvalue)) - { - float value = PyFloat_AsDouble(pyvalue); - if (!strcmp(attr_str, "energy")) - { - m_lightobj.m_energy = value; - return PY_SET_ATTR_SUCCESS; - } - - if (!strcmp(attr_str, "distance")) - { - m_lightobj.m_distance = value; - return PY_SET_ATTR_SUCCESS; - } - - if (!strcmp(attr_str, "lin_attenuation")) - { - m_lightobj.m_att1 = value; - return PY_SET_ATTR_SUCCESS; - } - - if (!strcmp(attr_str, "quad_attenuation")) - { - m_lightobj.m_att2 = value; - return PY_SET_ATTR_SUCCESS; - } - - if (!strcmp(attr_str, "spotsize")) - { - m_lightobj.m_spotsize = value; - return PY_SET_ATTR_SUCCESS; - } - - if (!strcmp(attr_str, "spotblend")) - { - m_lightobj.m_spotblend = value; - return PY_SET_ATTR_SUCCESS; - } - } - - if (PySequence_Check(pyvalue)) - { - if (!strcmp(attr_str, "colour") || !strcmp(attr_str, "color")) - { - MT_Vector3 color; - if (PyVecTo(pyvalue, color)) - { - m_lightobj.m_red = color[0]; - m_lightobj.m_green = color[1]; - m_lightobj.m_blue = color[2]; - return PY_SET_ATTR_SUCCESS; - } - return PY_SET_ATTR_FAIL; - } - } - - if (!strcmp(attr_str, "SPOT") || !strcmp(attr_str, "SUN") || !strcmp(attr_str, "NORMAL")) - { - PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr_str); - return PY_SET_ATTR_FAIL; - } - - return KX_GameObject::py_setattro(attr, pyvalue); -} - -PyMethodDef KX_LightObject::Methods[] = { - {NULL,NULL} //Sentinel -}; - -PyAttributeDef KX_LightObject::Attributes[] = { - KX_PYATTRIBUTE_DUMMY("layer"), - KX_PYATTRIBUTE_DUMMY("energy"), - KX_PYATTRIBUTE_DUMMY("distance"), - KX_PYATTRIBUTE_DUMMY("colour"), - KX_PYATTRIBUTE_DUMMY("color"), - KX_PYATTRIBUTE_DUMMY("lin_attenuation"), - KX_PYATTRIBUTE_DUMMY("quad_attenuation"), - KX_PYATTRIBUTE_DUMMY("spotsize"), - KX_PYATTRIBUTE_DUMMY("spotblend"), - KX_PYATTRIBUTE_DUMMY("SPOT"), - KX_PYATTRIBUTE_DUMMY("SUN"), - KX_PYATTRIBUTE_DUMMY("NORMAL"), - KX_PYATTRIBUTE_DUMMY("type"), - { NULL } //Sentinel -}; - PyTypeObject KX_LightObject::Type = { PyObject_HEAD_INIT(NULL) 0, @@ -356,3 +210,98 @@ PyParentObject KX_LightObject::Parents[] = { &CValue::Type, NULL }; + +PyMethodDef KX_LightObject::Methods[] = { + {NULL,NULL} //Sentinel +}; + +PyAttributeDef KX_LightObject::Attributes[] = { + KX_PYATTRIBUTE_INT_RW("layer", 1, 20, true, KX_LightObject, m_lightobj.m_layer), + KX_PYATTRIBUTE_FLOAT_RW("energy", 0, 10, KX_LightObject, m_lightobj.m_energy), + KX_PYATTRIBUTE_FLOAT_RW("distance", 0.01, 5000, KX_LightObject, m_lightobj.m_distance), + KX_PYATTRIBUTE_RW_FUNCTION("color", KX_LightObject, pyattr_get_color, pyattr_set_color), + KX_PYATTRIBUTE_RW_FUNCTION("colour", KX_LightObject, pyattr_get_color, pyattr_set_color), + KX_PYATTRIBUTE_FLOAT_RW("lin_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att1), + KX_PYATTRIBUTE_FLOAT_RW("quat_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att2), + KX_PYATTRIBUTE_FLOAT_RW("spotsize", 1, 180, KX_LightObject, m_lightobj.m_spotsize), + KX_PYATTRIBUTE_FLOAT_RW("spotblend", 0, 1, KX_LightObject, m_lightobj.m_spotblend), + KX_PYATTRIBUTE_RO_FUNCTION("SPOT", KX_LightObject, pyattr_get_typeconst), + KX_PYATTRIBUTE_RO_FUNCTION("SUN", KX_LightObject, pyattr_get_typeconst), + KX_PYATTRIBUTE_RO_FUNCTION("NORMAL", KX_LightObject, pyattr_get_typeconst), + KX_PYATTRIBUTE_RW_FUNCTION("type", KX_LightObject, pyattr_get_type, pyattr_set_type), + { NULL } //Sentinel +}; + +PyObject* KX_LightObject::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject* self = static_cast(self_v); + return Py_BuildValue("[fff]", self->m_lightobj.m_red, self->m_lightobj.m_green, self->m_lightobj.m_blue); +} + +int KX_LightObject::pyattr_set_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_LightObject* self = static_cast(self_v); + + MT_Vector3 color; + if (PyVecTo(value, color)) + { + self->m_lightobj.m_red = color[0]; + self->m_lightobj.m_green = color[1]; + self->m_lightobj.m_blue = color[2]; + return 0; + } + return 1; +} + +PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + PyObject* retvalue; + + const char* type = attrdef->m_name; + + if(strcmp(type, "SPOT")) { + retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SPOT); + } else if (strcmp(type, "SUN")) { + retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SUN); + } else if (strcmp(type, "NORMAL")) { + retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL); + } + + return retvalue; +} + +PyObject* KX_LightObject::pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject* self = static_cast(self_v); + return PyInt_FromLong(self->m_lightobj.m_type); +} + +int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value) +{ + KX_LightObject* self = static_cast(self_v); + int val = PyInt_AsLong(value); + switch(val) { + case 0: + self->m_lightobj.m_type = self->m_lightobj.LIGHT_SPOT; + break; + case 1: + self->m_lightobj.m_type = self->m_lightobj.LIGHT_SUN; + break; + default: + self->m_lightobj.m_type = self->m_lightobj.LIGHT_NORMAL; + break; + } + + return PY_SET_ATTR_SUCCESS; +} + + +PyObject* KX_LightObject::py_getattro(PyObject *attr) +{ + py_getattro_up(KX_GameObject); +} + +int KX_LightObject::py_setattro(PyObject *attr, PyObject *value) +{ + py_setattro_up(KX_GameObject); +} diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index e5d48b6f975..35f25515e3b 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -66,6 +66,13 @@ public: virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *pyvalue); + /* attributes */ + static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value); + static PyObject* pyattr_get_typeconst(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value); + virtual bool IsLight(void) { return true; } }; diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index cefa2ba4488..452cb9ad19b 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -267,7 +267,7 @@ KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh, "Reinstance the physics mesh.") { //this needs to be reviewed, it is dependend on Sumo/Solid. Who is using this ? - Py_RETURN_NONE;//(KX_ReInstanceShapeFromMesh(m_meshobj)) ? Py_RETURN_TRUE : Py_RETURN_FALSE; + (KX_ReInstanceShapeFromMesh(m_meshobj)) ? Py_RETURN_TRUE : Py_RETURN_FALSE; } PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) From 88c58d6b2d5a3ad74e4a06b71fe8071593cd7bfb Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 22 Apr 2009 06:30:32 +0000 Subject: [PATCH 027/444] BGE * the ternary form refused to compile properly with msvc, rewrite a bit. --- source/gameengine/Ketsji/KX_MeshProxy.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 452cb9ad19b..65b163106c9 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -266,8 +266,12 @@ PyObject* KX_MeshProxy::PyGetPolygon(PyObject* args, PyObject* kwds) KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh, "Reinstance the physics mesh.") { +#if 0 //this needs to be reviewed, it is dependend on Sumo/Solid. Who is using this ? - (KX_ReInstanceShapeFromMesh(m_meshobj)) ? Py_RETURN_TRUE : Py_RETURN_FALSE; + if(KX_ReInstanceShapeFromMesh(m_meshobj)) + Py_RETURN_TRUE; +#endif + Py_RETURN_FALSE; } PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) From 95038048a2a10ea8703b1a94fc7fe1b0567ef559 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Apr 2009 09:08:57 +0000 Subject: [PATCH 028/444] [#18577] LightWave (.lwo) Exporter Object Names are Incorrect patch from Philip Alldredge (cilcoder), slightly modified --- release/scripts/lightwave_export.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/release/scripts/lightwave_export.py b/release/scripts/lightwave_export.py index 458e61f3a28..9235af12f7e 100644 --- a/release/scripts/lightwave_export.py +++ b/release/scripts/lightwave_export.py @@ -95,12 +95,16 @@ def write(filename): icon = "" #generate_icon() meshes = [] + mesh_object_name_lookup = {} # for name lookups only + for obj in objects: mesh = BPyMesh.getMeshFromObject(obj, None, True, False, scn) if mesh: mesh.transform(obj.matrixWorld) meshes.append(mesh) - + mesh_object_name_lookup[mesh] = obj.name + del obj + material_names = get_used_material_names(meshes) tags = generate_tags(material_names) surfs = generate_surfs(material_names) @@ -111,7 +115,7 @@ def write(filename): layer_index = 0 for mesh in meshes: - layr = generate_layr(obj.name, layer_index) + layr = generate_layr(mesh_object_name_lookup[mesh], layer_index) pnts = generate_pnts(mesh) bbox = generate_bbox(mesh) pols = generate_pols(mesh) @@ -149,7 +153,9 @@ def write(filename): layer_index += 1 mesh.verts = None # save some ram - + + del mesh_object_name_lookup + for surf in surfs: chunks.append(surf) From 785b784e0903f4cc04889a0790f15f6b01b7860b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Apr 2009 09:47:57 +0000 Subject: [PATCH 029/444] BGE Python API improved how attribute errors are set so each classes py_getattro function dosnt need to set an error if the attribute doesn't exist. Now py_base_getattro sets an error on a NULL return value when no errors are set to avoid setting errors at multiple levels. --- .../gameengine/Expressions/PyObjectPlus.cpp | 26 ++++++++++++++----- source/gameengine/Expressions/PyObjectPlus.h | 10 +++---- source/gameengine/Ketsji/KX_GameObject.cpp | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 96753d56d94..30495fc2a45 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -146,9 +146,23 @@ PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) PyObject *ret= self_plus->py_getattro(attr); - if(ret==NULL && (strcmp(PyString_AsString(attr), "__dict__")==0)) - ret= self_plus->py_getattro_dict(); - + /* Attribute not found, was this a __dict__ lookup?, otherwise set an error if none is set */ + if(ret==NULL) { + char *attr_str= PyString_AsString(attr); + + if (strcmp(attr_str, "__dict__")==0) + { + /* the error string will probably not + * be set but just incase clear it */ + PyErr_Clear(); + ret= self_plus->py_getattro_dict(); + } + else if (!PyErr_Occurred()) { + /* We looked for an attribute but it wasnt found + * since py_getattro didnt set the error, set it here */ + PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", self->ob_type->tp_name, attr_str); + } + } return ret; } @@ -183,8 +197,7 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr) { PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, "attribute \"%s\" not found", PyString_AsString(attr)); - return NULL; + return NULL; /* py_base_getattro sets the error, this way we can avoid setting the error at many levels */ } else { /* Copied from py_getattro_up */ if (PyCObject_Check(descr)) { @@ -192,8 +205,7 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr) } else if (descr->ob_type->tp_descr_get) { return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); } else { - fprintf(stderr, "Unknown attribute type (PyObjectPlus::py_getattro)"); - return descr; + return NULL; } /* end py_getattro_up copy */ } diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index b0ddfa04e32..a3b3952a6d1 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -114,6 +114,9 @@ typedef struct { // This defines the py_getattro_up macro // which allows attribute and method calls // to be properly passed up the hierarchy. + // + // Note, PyDict_GetItem() WONT set an exception! + // let the py_base_getattro function do this. #define py_getattro_up(Parent) \ \ @@ -125,14 +128,11 @@ typedef struct { } else if (descr->ob_type->tp_descr_get) { \ return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \ } else { \ - fprintf(stderr, "unknown attribute type"); \ - return descr; \ + return NULL; \ } \ } else { \ - PyErr_Clear(); \ return Parent::py_getattro(attr); \ - } \ - return NULL; + } #define py_getattro_dict_up(Parent) \ return py_getattr_dict(Parent::py_getattro_dict(), Type.tp_dict); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 1f4c9c2e9d5..eb20cfa1131 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1655,7 +1655,7 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE PyObject *meshes= PyList_New(self->m_meshes.size()); int i; - for(i=0; i < self->m_meshes.size(); i++) + for(i=0; i < (int)self->m_meshes.size(); i++) { KX_MeshProxy* meshproxy = new KX_MeshProxy(self->m_meshes[i]); PyList_SET_ITEM(meshes, i, meshproxy->GetProxy()); From c09b1a985c29e59736eef619e2dae1a1dcf2d73a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 22 Apr 2009 11:54:43 +0000 Subject: [PATCH 030/444] bugfix #18187 Using "Key Alpha" didn't work when using MBlur render. The accumulation code was assuming regular alpha then. Now it corrects for it. Still it's a bit of a weak spot in Blender's render system. I will look in the future to make this a real post process; converting all RGBA buffers in the system, including for all passes, to "key alpha". Combined with that our compositor should become alpha type aware too. Everything in Blender assumes premul alpha, which still just will work best in general... --- .../blender/render/intern/source/pipeline.c | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 5c3c954aa8e..96edb4ee73c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1639,6 +1639,42 @@ static void do_render_3d(Render *re) RE_Database_Free(re); } +/* called by blur loop, accumulate RGBA key alpha */ +static void addblur_rect_key(RenderResult *rr, float *rectf, float *rectf1, float blurfac) +{ + float mfac= 1.0f - blurfac; + int a, b, stride= 4*rr->rectx; + int len= stride*sizeof(float); + + for(a=0; arecty; a++) { + if(blurfac==1.0f) { + memcpy(rectf, rectf1, len); + } + else { + float *rf= rectf, *rf1= rectf1; + + for( b= rr->rectx; b>0; b--, rf+=4, rf1+=4) { + if(rf1[3]<0.01f) + rf[3]= mfac*rf[3]; + else if(rf[3]<0.01f) { + rf[0]= rf1[0]; + rf[1]= rf1[1]; + rf[2]= rf1[2]; + rf[3]= blurfac*rf1[3]; + } + else { + rf[0]= mfac*rf[0] + blurfac*rf1[0]; + rf[1]= mfac*rf[1] + blurfac*rf1[1]; + rf[2]= mfac*rf[2] + blurfac*rf1[2]; + rf[3]= mfac*rf[3] + blurfac*rf1[3]; + } + } + } + rectf+= stride; + rectf1+= stride; + } +} + /* called by blur loop, accumulate renderlayers */ static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float blurfac, int channels) { @@ -1662,8 +1698,9 @@ static void addblur_rect(RenderResult *rr, float *rectf, float *rectf1, float bl } } + /* called by blur loop, accumulate renderlayers */ -static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac) +static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float blurfac, int key_alpha) { RenderLayer *rl, *rl1; RenderPass *rpass, *rpass1; @@ -1672,8 +1709,12 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b for(rl= rr->layers.first; rl && rl1; rl= rl->next, rl1= rl1->next) { /* combined */ - if(rl->rectf && rl1->rectf) - addblur_rect(rr, rl->rectf, rl1->rectf, blurfac, 4); + if(rl->rectf && rl1->rectf) { + if(key_alpha) + addblur_rect_key(rr, rl->rectf, rl1->rectf, blurfac); + else + addblur_rect(rr, rl->rectf, rl1->rectf, blurfac, 4); + } /* passes are allocated in sync */ rpass1= rl1->passes.first; @@ -1703,7 +1744,7 @@ static void do_render_blur_3d(Render *re) blurfac= 1.0f/(float)(re->r.osa-blur); - merge_renderresult_blur(rres, re->result, blurfac); + merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY); if(re->test_break()) break; } From a8592d09d0173bab0e3eb66a315146e164cf14a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Apr 2009 12:16:41 +0000 Subject: [PATCH 031/444] BGE C++ API Some functions used ProcessReplica(replica); others replica->ProcessReplica() Use the second method everywhere so the PyObjectPlus's ProcessReplica() can be called from its subclasses. Note that PyObjectPlus's ProcessReplica isnt used yet. --- .../gameengine/Converter/BL_ArmatureObject.cpp | 11 ++++++----- .../gameengine/Converter/BL_ArmatureObject.h | 2 +- .../Converter/BL_DeformableGameObject.cpp | 14 +++++--------- .../Converter/BL_DeformableGameObject.h | 2 +- source/gameengine/Expressions/PyObjectPlus.cpp | 8 ++++++++ source/gameengine/Expressions/PyObjectPlus.h | 6 ++++++ source/gameengine/Ketsji/KX_Camera.cpp | 7 +------ source/gameengine/Ketsji/KX_Camera.h | 9 --------- source/gameengine/Ketsji/KX_GameObject.cpp | 18 +++++++++--------- source/gameengine/Ketsji/KX_GameObject.h | 4 +--- source/gameengine/Ketsji/KX_Light.cpp | 2 +- 11 files changed, 39 insertions(+), 44 deletions(-) diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index d2001212f7d..04e2c55e7dd 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -74,16 +74,17 @@ CValue* BL_ArmatureObject::GetReplica() // this will copy properties and so on... CValue::AddDataToReplica(replica); - ProcessReplica(replica); + replica->ProcessReplica(); return replica; } -void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica) +void BL_ArmatureObject::ProcessReplica() { - KX_GameObject::ProcessReplica(replica); + bPose *pose= m_pose; + KX_GameObject::ProcessReplica(); - replica->m_pose = NULL; - game_copy_pose(&replica->m_pose, m_pose); + m_pose = NULL; + game_copy_pose(&m_pose, pose); } BL_ArmatureObject::~BL_ArmatureObject() diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index d68e37d9e37..d5402cfd126 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -45,7 +45,7 @@ class BL_ArmatureObject : public KX_GameObject public: double GetLastFrame (); short GetActivePriority(); - virtual void ProcessReplica(BL_ArmatureObject *replica); + virtual void ProcessReplica(); class BL_ActionActuator * GetActiveAction(); BL_ArmatureObject( diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp index e2610d2b405..618744dc1f3 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.cpp +++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp @@ -41,16 +41,12 @@ BL_DeformableGameObject::~BL_DeformableGameObject() delete m_pDeformer; // __NLA : Temporary until we decide where to put this } -void BL_DeformableGameObject::ProcessReplica(KX_GameObject* replica) +void BL_DeformableGameObject::ProcessReplica() { - BL_MeshDeformer *deformer; - KX_GameObject::ProcessReplica(replica); - - if (m_pDeformer) { - deformer = (BL_MeshDeformer*)m_pDeformer->GetReplica(replica); - ((BL_DeformableGameObject*)replica)->m_pDeformer = deformer; - } + KX_GameObject::ProcessReplica(); + if (m_pDeformer) + m_pDeformer= (BL_MeshDeformer*)m_pDeformer->GetReplica(this); } CValue* BL_DeformableGameObject::GetReplica() @@ -61,7 +57,7 @@ CValue* BL_DeformableGameObject::GetReplica() // this will copy properties and so on... CValue::AddDataToReplica(replica); - ProcessReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index 126a1fcb1e7..dbc89bd2a20 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -62,7 +62,7 @@ public: m_pDeformer->Relink (map); KX_GameObject::Relink(map); }; - void ProcessReplica(KX_GameObject* replica); + void ProcessReplica(); BL_DeformableGameObject(Object* blendobj, void* sgReplicationInfo, SG_Callbacks callbacks) : KX_GameObject(sgReplicationInfo,callbacks), diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 30495fc2a45..57a61ac37ae 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -810,6 +810,14 @@ PyObject *PyObjectPlus::PyisA(PyObject *value) // Python wrapper for isA return NULL; } + +void PyObjectPlus::ProcessReplica() +{ + /* Clear the proxy, will be created again if needed with GetProxy() + * otherwise the PyObject will point to the wrong reference */ + m_proxy= NULL; +} + /* Utility function called by the macro py_getattro_up() * for getting ob.__dict__() values from our PyObject * this is used by python for doing dir() on an object, so its good diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index a3b3952a6d1..52e59f7730c 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -450,6 +450,12 @@ public: static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp); static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns); + + /** + * Makes sure any internal data owned by this class is deep copied. + */ + virtual void ProcessReplica(); + }; PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index f84ce23b7dd..e1784a4cd37 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -72,15 +72,10 @@ CValue* KX_Camera::GetReplica() // this will copy properties and so on... CValue::AddDataToReplica(replica); - ProcessReplica(replica); + replica->ProcessReplica(); return replica; } - -void KX_Camera::ProcessReplica(KX_Camera* replica) -{ - KX_GameObject::ProcessReplica(replica); -} MT_Transform KX_Camera::GetWorldToCamera() const { diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 6f818cb2c57..d570fac213a 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -146,15 +146,6 @@ public: virtual CValue* GetReplica( ); - - /** - * Inherited from CValue -- Makes sure any internal - * data owned by this class is deep copied. Called internally - */ - virtual void - ProcessReplica( - KX_Camera* replica - ); MT_Transform GetWorldToCamera() const; MT_Transform GetCameraToWorld() const; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index eb20cfa1131..fe7f96d9fac 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -331,16 +331,16 @@ void KX_GameObject::RemoveParent(KX_Scene *scene) } } -void KX_GameObject::ProcessReplica(KX_GameObject* replica) +void KX_GameObject::ProcessReplica() { - replica->m_pPhysicsController1 = NULL; - replica->m_pGraphicController = NULL; - replica->m_pSGNode = NULL; - replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info); - replica->m_pClient_info->m_gameobject = replica; - replica->m_state = 0; + m_pPhysicsController1 = NULL; + m_pGraphicController = NULL; + m_pSGNode = NULL; + m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info); + m_pClient_info->m_gameobject = this; + m_state = 0; if(m_attr_dict) - replica->m_attr_dict= PyDict_Copy(m_attr_dict); + m_attr_dict= PyDict_Copy(m_attr_dict); } @@ -352,7 +352,7 @@ CValue* KX_GameObject::GetReplica() // this will copy properties and so on... CValue::AddDataToReplica(replica); - ProcessReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index e81429dff5a..479a3c1b574 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -279,9 +279,7 @@ public: * data owned by this class is deep copied. Called internally */ virtual void - ProcessReplica( - KX_GameObject* replica - ); + ProcessReplica(); /** * Return the linear velocity of the game object. diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index c5189907714..a426953602b 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -85,7 +85,7 @@ CValue* KX_LightObject::GetReplica() // this will copy properties and so on... CValue::AddDataToReplica(replica); - ProcessReplica(replica); + replica->ProcessReplica(); replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr(); m_rendertools->AddLight(&replica->m_lightobj); From 5553d2c0142539c754575ce471c2676e0d5dff34 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Apr 2009 14:42:00 +0000 Subject: [PATCH 032/444] BGE C++ API PyObjectPlus::ProcessReplica() is now called when any of its subclasses are replicated. This is important because PyObjectPlus::ProcessReplica() NULL's the 'm_proxy' python pointer I added recently. Without this a replicated subclass of PyObjectPlus could have an invalid pointer (crashing the BGE). This change also means CValue::AddDataToReplica() can be moved into CValue::ProcessReplica() since ProcessReplica is always called. --- .../Converter/BL_ActionActuator.cpp | 9 ++-- .../Converter/BL_ArmatureObject.cpp | 4 -- .../Converter/BL_DeformableGameObject.cpp | 4 -- .../Converter/BL_ModifierDeformer.cpp | 1 + .../Converter/BL_ShapeActionActuator.cpp | 4 +- .../gameengine/Converter/BL_SkinDeformer.cpp | 2 + source/gameengine/Expressions/BoolValue.cpp | 2 +- source/gameengine/Expressions/EmptyValue.cpp | 2 +- source/gameengine/Expressions/FloatValue.cpp | 4 +- source/gameengine/Expressions/IntValue.cpp | 2 +- source/gameengine/Expressions/ListValue.cpp | 2 +- source/gameengine/Expressions/StringValue.cpp | 2 +- source/gameengine/Expressions/Value.cpp | 50 ++++++++----------- source/gameengine/Expressions/Value.h | 6 +-- source/gameengine/Expressions/VectorValue.cpp | 2 +- .../GameLogic/SCA_2DFilterActuator.cpp | 2 - .../GameLogic/SCA_ANDController.cpp | 2 +- .../GameLogic/SCA_ActuatorSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_AlwaysSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_DelaySensor.cpp | 2 +- .../GameLogic/SCA_ExpressionController.cpp | 2 +- source/gameengine/GameLogic/SCA_IActuator.cpp | 1 + .../GameLogic/SCA_JoystickSensor.cpp | 2 +- .../GameLogic/SCA_KeyboardSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_MouseSensor.cpp | 2 +- .../GameLogic/SCA_NANDController.cpp | 2 +- .../GameLogic/SCA_NORController.cpp | 2 +- .../gameengine/GameLogic/SCA_ORController.cpp | 2 +- .../GameLogic/SCA_PropertyActuator.cpp | 5 -- .../GameLogic/SCA_PropertySensor.cpp | 2 +- .../GameLogic/SCA_PythonController.cpp | 2 +- .../GameLogic/SCA_RandomActuator.cpp | 2 - .../gameengine/GameLogic/SCA_RandomSensor.cpp | 2 +- .../GameLogic/SCA_XNORController.cpp | 2 +- .../GameLogic/SCA_XORController.cpp | 2 +- .../KXNetwork/KX_NetworkMessageActuator.cpp | 3 -- .../KXNetwork/KX_NetworkMessageSensor.cpp | 4 +- source/gameengine/Ketsji/KX_CDActuator.cpp | 3 -- source/gameengine/Ketsji/KX_Camera.cpp | 1 - .../gameengine/Ketsji/KX_CameraActuator.cpp | 2 - .../gameengine/Ketsji/KX_ConstraintActuator.h | 2 - source/gameengine/Ketsji/KX_GameActuator.cpp | 2 - source/gameengine/Ketsji/KX_GameObject.cpp | 3 +- source/gameengine/Ketsji/KX_IpoActuator.h | 2 - source/gameengine/Ketsji/KX_Light.cpp | 3 -- .../gameengine/Ketsji/KX_MouseFocusSensor.h | 2 +- source/gameengine/Ketsji/KX_NearSensor.cpp | 3 +- .../gameengine/Ketsji/KX_ObjectActuator.cpp | 3 -- .../gameengine/Ketsji/KX_ParentActuator.cpp | 2 - source/gameengine/Ketsji/KX_RadarSensor.cpp | 3 +- source/gameengine/Ketsji/KX_RaySensor.cpp | 3 +- .../Ketsji/KX_SCA_AddObjectActuator.cpp | 1 - .../Ketsji/KX_SCA_DynamicActuator.cpp | 4 -- .../Ketsji/KX_SCA_EndObjectActuator.cpp | 2 - .../Ketsji/KX_SCA_ReplaceMeshActuator.cpp | 3 -- source/gameengine/Ketsji/KX_SceneActuator.cpp | 3 -- source/gameengine/Ketsji/KX_SoundActuator.cpp | 2 - source/gameengine/Ketsji/KX_StateActuator.cpp | 2 - source/gameengine/Ketsji/KX_TouchSensor.cpp | 3 +- source/gameengine/Ketsji/KX_TrackToActuator.h | 2 - .../Ketsji/KX_VisibilityActuator.cpp | 2 - 61 files changed, 63 insertions(+), 140 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 3002005ae3f..e06008ff891 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -66,9 +66,9 @@ BL_ActionActuator::~BL_ActionActuator() game_free_pose(m_blendpose); } -void BL_ActionActuator::ProcessReplica(){ -// bPose *oldpose = m_pose; -// bPose *oldbpose = m_blendpose; +void BL_ActionActuator::ProcessReplica() +{ + SCA_IActuator::ProcessReplica(); m_pose = NULL; m_blendpose = NULL; @@ -84,9 +84,6 @@ void BL_ActionActuator::SetBlendTime (float newtime){ CValue* BL_ActionActuator::GetReplica() { BL_ActionActuator* replica = new BL_ActionActuator(*this);//m_float,GetName()); replica->ProcessReplica(); - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; } diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 04e2c55e7dd..b00b493193d 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -70,10 +70,6 @@ BL_ArmatureObject::BL_ArmatureObject( CValue* BL_ArmatureObject::GetReplica() { BL_ArmatureObject* replica = new BL_ArmatureObject(*this); - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp index 618744dc1f3..241ff8d2aaf 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.cpp +++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp @@ -53,10 +53,6 @@ CValue* BL_DeformableGameObject::GetReplica() { BL_DeformableGameObject* replica = new BL_DeformableGameObject(*this);//m_float,GetName()); - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index 6113f88e331..79ee6be47f0 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -87,6 +87,7 @@ RAS_Deformer *BL_ModifierDeformer::GetReplica(class KX_GameObject* replica) void BL_ModifierDeformer::ProcessReplica() { + /* Note! - This is not inherited from PyObjectPlus */ BL_ShapeDeformer::ProcessReplica(); m_dm = NULL; m_lastModifierUpdate = -1; diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index a447ffb8aa9..60d26b9a99f 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -61,6 +61,7 @@ BL_ShapeActionActuator::~BL_ShapeActionActuator() void BL_ShapeActionActuator::ProcessReplica() { + SCA_IActuator::ProcessReplica(); m_localtime=m_startframe; m_lastUpdate=-1; } @@ -74,9 +75,6 @@ CValue* BL_ShapeActionActuator::GetReplica() { BL_ShapeActionActuator* replica = new BL_ShapeActionActuator(*this);//m_float,GetName()); replica->ProcessReplica(); - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; } diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index ae3e1a10005..3267dbce410 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -156,6 +156,8 @@ RAS_Deformer *BL_SkinDeformer::GetReplica(class KX_GameObject* replica) BL_SkinDeformer *result; result = new BL_SkinDeformer(*this); + /* Not inherited from PyObjectPlus so this isnt needed */ + /* Just call a dummy function below, will be optimized out */ result->ProcessReplica(); return result; } diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp index 13c870b68e5..4e0a71e5a19 100644 --- a/source/gameengine/Expressions/BoolValue.cpp +++ b/source/gameengine/Expressions/BoolValue.cpp @@ -201,7 +201,7 @@ const STR_String& CBoolValue::GetText() CValue* CBoolValue::GetReplica() { CBoolValue* replica = new CBoolValue(*this); - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Expressions/EmptyValue.cpp b/source/gameengine/Expressions/EmptyValue.cpp index f72ddc47096..5d1273b5301 100644 --- a/source/gameengine/Expressions/EmptyValue.cpp +++ b/source/gameengine/Expressions/EmptyValue.cpp @@ -121,7 +121,7 @@ const STR_String & CEmptyValue::GetText() CValue* CEmptyValue::GetReplica() { CEmptyValue* replica = new CEmptyValue(*this); - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp index 212a55fe457..a31d3b9a528 100644 --- a/source/gameengine/Expressions/FloatValue.cpp +++ b/source/gameengine/Expressions/FloatValue.cpp @@ -307,8 +307,8 @@ const STR_String & CFloatValue::GetText() CValue* CFloatValue::GetReplica() { CFloatValue* replica = new CFloatValue(*this); - replica->m_pstrRep = NULL; - CValue::AddDataToReplica(replica); + replica->m_pstrRep = NULL; /* should be in CFloatValue::ProcessReplica() but its not defined, no matter */ + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index 4e86f7bf789..74ec9865fec 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -311,7 +311,7 @@ const STR_String & CIntValue::GetText() CValue* CIntValue::GetReplica() { CIntValue* replica = new CIntValue(*this); - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->m_pstrRep = NULL; return replica; diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 7c31a29f4ac..6c92e805745 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -324,7 +324,7 @@ const STR_String & CListValue::GetText() CValue* CListValue::GetReplica() { CListValue* replica = new CListValue(*this); - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->m_bReleaseContents=true; // for copy, complete array is copied for now... // copy all values diff --git a/source/gameengine/Expressions/StringValue.cpp b/source/gameengine/Expressions/StringValue.cpp index 2b3c62c411e..857aa97b420 100644 --- a/source/gameengine/Expressions/StringValue.cpp +++ b/source/gameengine/Expressions/StringValue.cpp @@ -133,7 +133,7 @@ bool CStringValue::IsEqual(const STR_String & other) CValue* CStringValue::GetReplica() { CStringValue* replica = new CStringValue(*this); - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; }; diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 106bd1256a6..b5aca518e88 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -439,27 +439,6 @@ int CValue::GetPropertyCount() } - - - -void CValue::CloneProperties(CValue *replica) -{ - - if (m_pNamedPropertyArray) - { - replica->m_pNamedPropertyArray=NULL; - std::map::iterator it; - for (it= m_pNamedPropertyArray->begin(); (it != m_pNamedPropertyArray->end()); it++) - { - CValue *val = (*it).second->GetReplica(); - replica->SetProperty((*it).first,val); - val->Release(); - } - } - - -} - double* CValue::GetVector3(bool bGetTransformedVec) { assertd(false); // don;t get vector from me @@ -534,23 +513,34 @@ void CValue::DisableRefCount() -void CValue::AddDataToReplica(CValue *replica) +void CValue::ProcessReplica() /* was AddDataToReplica in 2.48 */ { - replica->m_refcount = 1; - + m_refcount = 1; + #ifdef _DEBUG //gRefCountValue++; #endif - replica->m_ValFlags.RefCountDisabled = false; + PyObjectPlus::ProcessReplica(); - replica->ReplicaSetName(GetName()); + m_ValFlags.RefCountDisabled = false; - //copy all props - CloneProperties(replica); + ReplicaSetName(GetName()); + + /* copy all props */ + if (m_pNamedPropertyArray) + { + std::map *pOldArray = m_pNamedPropertyArray; + m_pNamedPropertyArray=NULL; + std::map::iterator it; + for (it= pOldArray->begin(); (it != pOldArray->end()); it++) + { + CValue *val = (*it).second->GetReplica(); + SetProperty((*it).first,val); + val->Release(); + } + } } - - CValue* CValue::FindIdentifier(const STR_String& identifiername) { diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 88186fa95c0..cc791351d8a 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -281,7 +281,6 @@ public: virtual CValue* GetProperty(int inIndex); // Get property number virtual int GetPropertyCount(); // Get the amount of properties assiocated with this value - virtual void CloneProperties(CValue* replica); virtual CValue* FindIdentifier(const STR_String& identifiername); /** Set the wireframe color of this value depending on the CSG * operator type @@ -300,6 +299,7 @@ public: * @attention this particular function should never be called. Why not abstract? */ virtual void SetValue(CValue* newval); virtual CValue* GetReplica() =0; + virtual void ProcessReplica(); //virtual CValue* Copy() = 0; @@ -328,10 +328,10 @@ public: virtual void SetCustomFlag2(bool bCustomFlag) { m_ValFlags.CustomFlag2 = bCustomFlag;}; virtual bool IsCustomFlag2() { return m_ValFlags.CustomFlag2;}; - + protected: virtual void DisableRefCount(); // Disable reference counting for this value - virtual void AddDataToReplica(CValue* replica); + //virtual void AddDataToReplica(CValue* replica); virtual ~CValue(); private: // Member variables diff --git a/source/gameengine/Expressions/VectorValue.cpp b/source/gameengine/Expressions/VectorValue.cpp index 497a50b90e7..e8e1d45c356 100644 --- a/source/gameengine/Expressions/VectorValue.cpp +++ b/source/gameengine/Expressions/VectorValue.cpp @@ -204,7 +204,7 @@ const STR_String & CVectorValue::GetText() CValue* CVectorValue::GetReplica() { CVectorValue* replica = new CVectorValue(*this); - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; }; diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index 9bf03bf39cc..ed834587414 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -64,8 +64,6 @@ CValue* SCA_2DFilterActuator::GetReplica() { SCA_2DFilterActuator* replica = new SCA_2DFilterActuator(*this); replica->ProcessReplica(); - CValue::AddDataToReplica(replica); - return replica; } diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index e4642750942..ed2372200e9 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -94,7 +94,7 @@ CValue* SCA_ANDController::GetReplica() { CValue* replica = new SCA_ANDController(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index 4c85c4f8e5e..928060d7394 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -60,7 +60,7 @@ CValue* SCA_ActuatorSensor::GetReplica() { SCA_ActuatorSensor* replica = new SCA_ActuatorSensor(*this); // m_range_expr must be recalculated on replica! - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->Init(); return replica; diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index 874883c89b1..941f3b55b44 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -72,7 +72,7 @@ CValue* SCA_AlwaysSensor::GetReplica() { CValue* replica = new SCA_AlwaysSensor(*this);//m_float,GetName()); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index 0e4a00e2745..15e805a657c 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -77,7 +77,7 @@ CValue* SCA_DelaySensor::GetReplica() { CValue* replica = new SCA_DelaySensor(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index 352a39a6fea..e6bccef08d4 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -70,7 +70,7 @@ CValue* SCA_ExpressionController::GetReplica() replica->m_exprText = m_exprText; replica->m_exprCache = NULL; // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index 309f3108418..3d4ad3aec3a 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -100,6 +100,7 @@ bool SCA_IActuator::Update() void SCA_IActuator::ProcessReplica() { + SCA_ILogicBrick::ProcessReplica(); m_events.clear(); } diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index a8c6f87ebdd..11b31c67edd 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -87,7 +87,7 @@ CValue* SCA_JoystickSensor::GetReplica() { SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->Init(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index 2048731f73c..5dcdb222713 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -85,7 +85,7 @@ CValue* SCA_KeyboardSensor::GetReplica() { SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->Init(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index 0bae676d19d..65942327e68 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -111,7 +111,7 @@ CValue* SCA_MouseSensor::GetReplica() { SCA_MouseSensor* replica = new SCA_MouseSensor(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->Init(); return replica; diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index dedf32df3c9..ab5c39dc039 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -94,7 +94,7 @@ CValue* SCA_NANDController::GetReplica() { CValue* replica = new SCA_NANDController(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index 8cd575ffef3..918e6a348ae 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -94,7 +94,7 @@ CValue* SCA_NORController::GetReplica() { CValue* replica = new SCA_NORController(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index a12246e9a73..034c3ee29cd 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -60,7 +60,7 @@ CValue* SCA_ORController::GetReplica() { CValue* replica = new SCA_ORController(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index 4facd8df27a..f3ca63066c9 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -186,11 +186,6 @@ GetReplica() { SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this); replica->ProcessReplica(); - - // this will copy properties and so on... - - CValue::AddDataToReplica(replica); - return replica; }; diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index c56dd3a12f4..7953698c6ef 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -111,7 +111,7 @@ CValue* SCA_PropertySensor::GetReplica() { SCA_PropertySensor* replica = new SCA_PropertySensor(*this); // m_range_expr must be recalculated on replica! - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->Init(); replica->m_range_expr = NULL; diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index b8052555528..ab4b5600d3f 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -110,7 +110,7 @@ CValue* SCA_PythonController::GetReplica() */ // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index b9df198f7da..91110425f7f 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -78,8 +78,6 @@ CValue* SCA_RandomActuator::GetReplica() SCA_RandomActuator* replica = new SCA_RandomActuator(*this); // replication just copy the m_base pointer => common random generator replica->ProcessReplica(); - CValue::AddDataToReplica(replica); - return replica; } diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 582cff4cde7..70a23124929 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -76,7 +76,7 @@ CValue* SCA_RandomSensor::GetReplica() CValue* replica = new SCA_RandomSensor(*this); // replication copies m_basegenerator pointer => share same generator // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index 145afa6aec5..13d50100d6c 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -98,7 +98,7 @@ CValue* SCA_XNORController::GetReplica() { CValue* replica = new SCA_XNORController(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 4dfba3a56ac..6613742a080 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -98,7 +98,7 @@ CValue* SCA_XORController::GetReplica() { CValue* replica = new SCA_XORController(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp index 9c36a899505..712f64d5f8f 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp @@ -93,9 +93,6 @@ CValue* KX_NetworkMessageActuator::GetReplica() new KX_NetworkMessageActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - return replica; } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index b1b9c0e1fc9..d770465e1ea 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -79,9 +79,7 @@ CValue* KX_NetworkMessageSensor::GetReplica() { CValue* replica = new KX_NetworkMessageSensor(*this); if (replica == NULL) return NULL; - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index 6e318cdcfa3..a0b2c73901f 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -74,9 +74,6 @@ CValue* KX_CDActuator::GetReplica() { KX_CDActuator* replica = new KX_CDActuator(*this); replica->ProcessReplica(); - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index e1784a4cd37..e536d1f1e7e 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -71,7 +71,6 @@ CValue* KX_Camera::GetReplica() KX_Camera* replica = new KX_Camera(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); replica->ProcessReplica(); return replica; diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 2ef7abfd172..38a68752958 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -82,8 +82,6 @@ GetReplica( ) { KX_CameraActuator* replica = new KX_CameraActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 84512c0ecf2..40607b44947 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -132,8 +132,6 @@ protected: virtual CValue* GetReplica() { KX_ConstraintActuator* replica = new KX_ConstraintActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 0a411396ff8..514fb74f6bf 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -73,8 +73,6 @@ CValue* KX_GameActuator::GetReplica() { KX_GameActuator* replica = new KX_GameActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fe7f96d9fac..8bd1e008336 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -333,6 +333,8 @@ void KX_GameObject::RemoveParent(KX_Scene *scene) void KX_GameObject::ProcessReplica() { + SCA_IObject::ProcessReplica(); + m_pPhysicsController1 = NULL; m_pGraphicController = NULL; m_pSGNode = NULL; @@ -351,7 +353,6 @@ CValue* KX_GameObject::GetReplica() KX_GameObject* replica = new KX_GameObject(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); replica->ProcessReplica(); return replica; diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index fb3b0eb1dd2..9ea597def1e 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -128,8 +128,6 @@ public: virtual CValue* GetReplica() { KX_IpoActuator* replica = new KX_IpoActuator(*this);//m_float,GetName()); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index a426953602b..7bc982111fe 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -82,9 +82,6 @@ CValue* KX_LightObject::GetReplica() KX_LightObject* replica = new KX_LightObject(*this); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - replica->ProcessReplica(); replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr(); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 5a9618f52b2..350fda198db 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -63,7 +63,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor virtual CValue* GetReplica() { CValue* replica = new KX_MouseFocusSensor(*this); // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; }; /** diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index ce519e1752c..23c525a1b52 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -111,8 +111,7 @@ CValue* KX_NearSensor::GetReplica() KX_NearSensor* replica = new KX_NearSensor(*this); replica->m_colliders = new CListValue(); replica->Init(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR); diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index ed5539709e4..b90967d610c 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -253,9 +253,6 @@ CValue* KX_ObjectActuator::GetReplica() KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName()); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - return replica; } diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 79e82670486..afc16ba994c 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -73,8 +73,6 @@ CValue* KX_ParentActuator::GetReplica() KX_ParentActuator* replica = new KX_ParentActuator(*this); // replication just copy the m_base pointer => common random generator replica->ProcessReplica(); - CValue::AddDataToReplica(replica); - return replica; } diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index d06728c1d4d..d9b8b6fec5b 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -82,8 +82,7 @@ CValue* KX_RadarSensor::GetReplica() KX_RadarSensor* replica = new KX_RadarSensor(*this); replica->m_colliders = new CListValue(); replica->Init(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::RADAR); diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index bee644b6a30..ea9356a49d1 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -88,8 +88,7 @@ KX_RaySensor::~KX_RaySensor() CValue* KX_RaySensor::GetReplica() { KX_RaySensor* replica = new KX_RaySensor(*this); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); replica->Init(); return replica; diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index b5aa7a2f4c2..dd9d63f5cd9 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -125,7 +125,6 @@ CValue* KX_SCA_AddObjectActuator::GetReplica() // this will copy properties and so on... replica->ProcessReplica(); - CValue::AddDataToReplica(replica); return replica; } diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index dd3250f5b61..4bc42686d78 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -215,10 +215,6 @@ CValue* KX_SCA_DynamicActuator::GetReplica() return NULL; replica->ProcessReplica(); - - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - return replica; }; diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp index c0dc6ea6b55..a0b411dd3a9 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -82,8 +82,6 @@ CValue* KX_SCA_EndObjectActuator::GetReplica() if (replica == NULL) return NULL; replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index b7135a5503a..8b87253d0a3 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -217,9 +217,6 @@ CValue* KX_SCA_ReplaceMeshActuator::GetReplica() replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - return replica; }; diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index c525aeb1e3f..6f622939dc4 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -76,9 +76,6 @@ CValue* KX_SceneActuator::GetReplica() { KX_SceneActuator* replica = new KX_SceneActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); - return replica; } diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 4103da4ad93..db3d92ffd79 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -90,8 +90,6 @@ CValue* KX_SoundActuator::GetReplica() m_soundScene->AddObject(soundobj); } - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index 16512dc6699..71ffa16cb54 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -62,8 +62,6 @@ KX_StateActuator::GetReplica( { KX_StateActuator* replica = new KX_StateActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; } diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 8995a0c198a..cddd018ef33 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -144,8 +144,7 @@ CValue* KX_TouchSensor::GetReplica() KX_TouchSensor* replica = new KX_TouchSensor(*this); replica->m_colliders = new CListValue(); replica->Init(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); + replica->ProcessReplica(); return replica; } diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index a17147c0842..c4cc2b1f062 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -61,8 +61,6 @@ class KX_TrackToActuator : public SCA_IActuator virtual CValue* GetReplica() { KX_TrackToActuator* replica = new KX_TrackToActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; }; diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index 9b1849511fe..ed12a88ad6a 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -64,8 +64,6 @@ KX_VisibilityActuator::GetReplica( { KX_VisibilityActuator* replica = new KX_VisibilityActuator(*this); replica->ProcessReplica(); - // this will copy properties and so on... - CValue::AddDataToReplica(replica); return replica; } From 076d1910f58661926393cca2a6f06d7091a5bce5 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 22 Apr 2009 16:26:22 +0000 Subject: [PATCH 033/444] BGE: some more cleanup in GetReplica/ProcessReplica of deformers: make them consistent with the other classes. --- .../Converter/BL_DeformableGameObject.cpp | 2 +- source/gameengine/Converter/BL_MeshDeformer.h | 3 +- .../Converter/BL_ModifierDeformer.cpp | 2 +- .../Converter/BL_ModifierDeformer.h | 2 +- .../gameengine/Converter/BL_ShapeDeformer.cpp | 7 +---- .../gameengine/Converter/BL_ShapeDeformer.h | 3 +- .../gameengine/Converter/BL_SkinDeformer.cpp | 11 ++----- source/gameengine/Converter/BL_SkinDeformer.h | 3 +- .../Ketsji/KX_ConvertPhysicsObjects.cpp | 31 +++++++++++++------ source/gameengine/Rasterizer/RAS_Deformer.h | 3 +- 10 files changed, 34 insertions(+), 33 deletions(-) diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp index 241ff8d2aaf..a9d5b643fd4 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.cpp +++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp @@ -46,7 +46,7 @@ void BL_DeformableGameObject::ProcessReplica() KX_GameObject::ProcessReplica(); if (m_pDeformer) - m_pDeformer= (BL_MeshDeformer*)m_pDeformer->GetReplica(this); + m_pDeformer= (BL_MeshDeformer*)m_pDeformer->GetReplica(); } CValue* BL_DeformableGameObject::GetReplica() diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 8de59c1cdf3..34944421b28 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -64,7 +64,8 @@ public: virtual void SetSimulatedTime(double time){}; virtual bool Apply(class RAS_IPolyMaterial *mat); virtual bool Update(void){ return false; }; - virtual RAS_Deformer* GetReplica(class KX_GameObject* replica){return NULL;}; + virtual RAS_Deformer* GetReplica(){return NULL;}; + virtual void ProcessReplica() { }; struct Mesh* GetMesh() { return m_bmesh; }; // virtual void InitDeform(double time){}; diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index 79ee6be47f0..09dbe966d0b 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -76,7 +76,7 @@ BL_ModifierDeformer::~BL_ModifierDeformer() } }; -RAS_Deformer *BL_ModifierDeformer::GetReplica(class KX_GameObject* replica) +RAS_Deformer *BL_ModifierDeformer::GetReplica() { BL_ModifierDeformer *result; diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h index 0caaabf8055..465c287a88b 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.h +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -73,7 +73,7 @@ public: }; virtual void ProcessReplica(); - virtual RAS_Deformer *GetReplica(class KX_GameObject* replica); + virtual RAS_Deformer *GetReplica(); virtual ~BL_ModifierDeformer(); virtual bool UseVertexArray() { diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index 499732c7f70..bf5eb5cbcb3 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -68,7 +68,7 @@ BL_ShapeDeformer::~BL_ShapeDeformer() { }; -RAS_Deformer *BL_ShapeDeformer::GetReplica(class KX_GameObject* replica) +RAS_Deformer *BL_ShapeDeformer::GetReplica() { BL_ShapeDeformer *result; @@ -77,11 +77,6 @@ RAS_Deformer *BL_ShapeDeformer::GetReplica(class KX_GameObject* replica) return result; } -void BL_ShapeDeformer::ProcessReplica() -{ - BL_SkinDeformer::ProcessReplica(); -} - bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma) { IpoCurve *icu; diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index 901a1d82295..1ec7bfdf74a 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -66,8 +66,7 @@ public: { }; - virtual void ProcessReplica(); - virtual RAS_Deformer *GetReplica(class KX_GameObject* replica); + virtual RAS_Deformer *GetReplica(); virtual ~BL_ShapeDeformer(); bool Update (void); diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 3267dbce410..d40776a645d 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -108,7 +108,7 @@ void BL_SkinDeformer::Relink(GEN_Map*map) void **h_obj = (*map)[m_armobj]; if (h_obj) - SetArmature( (BL_ArmatureObject*)(*h_obj) ); + m_armobj = (BL_ArmatureObject*)(*h_obj); else m_armobj=NULL; } @@ -151,21 +151,16 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) return true; } -RAS_Deformer *BL_SkinDeformer::GetReplica(class KX_GameObject* replica) +RAS_Deformer *BL_SkinDeformer::GetReplica() { BL_SkinDeformer *result; result = new BL_SkinDeformer(*this); - /* Not inherited from PyObjectPlus so this isnt needed */ - /* Just call a dummy function below, will be optimized out */ + /* there is m_armobj that must be fixed but we cannot do it now, it will be done in Relink */ result->ProcessReplica(); return result; } -void BL_SkinDeformer::ProcessReplica() -{ -} - //void where_is_pose (Object *ob); //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); bool BL_SkinDeformer::Update(void) diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index c93188b0c5a..ee240588851 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -67,8 +67,7 @@ public: bool recalc_normal, BL_ArmatureObject* arma = NULL); - virtual void ProcessReplica(); - virtual RAS_Deformer *GetReplica(class KX_GameObject* replica); + virtual RAS_Deformer *GetReplica(); virtual ~BL_SkinDeformer(); bool Update (void); bool Apply (class RAS_IPolyMaterial *polymat); diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 08e2ea30414..f4f8ec9f91b 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -34,7 +34,7 @@ // defines USE_ODE to choose physics engine #include "KX_ConvertPhysicsObject.h" -#include "KX_GameObject.h" +#include "BL_DeformableGameObject.h" #include "RAS_MeshObject.h" #include "KX_Scene.h" #include "SYS_System.h" @@ -670,11 +670,11 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, class KX_SoftBodyDeformer : public RAS_Deformer { - class RAS_MeshObject* m_pMeshObject; - class KX_GameObject* m_gameobj; + class RAS_MeshObject* m_pMeshObject; + class BL_DeformableGameObject* m_gameobj; public: - KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,KX_GameObject* gameobj) + KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,BL_DeformableGameObject* gameobj) :m_pMeshObject(pMeshObject), m_gameobj(gameobj) { @@ -687,7 +687,15 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, }; virtual void Relink(GEN_Map*map) { - //printf("relink\n"); + void **h_obj = (*map)[m_gameobj]; + + if (h_obj) { + m_gameobj = (BL_DeformableGameObject*)(*h_obj); + m_pMeshObject = m_gameobj->GetMesh(0); + } else { + m_gameobj = NULL; + m_pMeshObject = NULL; + } } virtual bool Apply(class RAS_IPolyMaterial *polymat) { @@ -751,12 +759,16 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, //printf("update\n"); return true;//?? } - virtual RAS_Deformer *GetReplica(class KX_GameObject* replica) + virtual RAS_Deformer *GetReplica() { - KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(replica->GetMesh(0),replica); + KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this); + deformer->ProcessReplica(); return deformer; } - + virtual void ProcessReplica() + { + // we have two pointers to deal with but we cannot do it now, will be done in Relink + } virtual bool SkipVertexTransform() { return true; @@ -1187,9 +1199,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, if (softBody && gameobj->GetMesh(0))//only the first mesh, if any { //should be a mesh then, so add a soft body deformer - KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),gameobj); + KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj); gameobj->SetDeformer(softbodyDeformer); - } } diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index dc5a49a0f99..5a6bab4c82d 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -44,7 +44,8 @@ public: virtual void Relink(GEN_Map*map)=0; virtual bool Apply(class RAS_IPolyMaterial *polymat)=0; virtual bool Update(void)=0; - virtual RAS_Deformer *GetReplica(class KX_GameObject* replica)=0; + virtual RAS_Deformer *GetReplica()=0; + virtual void ProcessReplica()=0; virtual bool SkipVertexTransform() { return false; From f6d27e73eee3cfdbe090bb1d34372d976ba079bb Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 22 Apr 2009 16:58:04 +0000 Subject: [PATCH 034/444] BGE: some more cleanup, remove useless ReplicaSetName(), move code to ProcessReplica. --- source/gameengine/Expressions/Value.cpp | 2 -- source/gameengine/Expressions/Value.h | 9 ++++----- source/gameengine/GameLogic/SCA_ILogicBrick.cpp | 8 -------- source/gameengine/GameLogic/SCA_ILogicBrick.h | 1 - source/gameengine/Ketsji/KX_GameObject.cpp | 15 --------------- source/gameengine/Ketsji/KX_GameObject.h | 8 -------- source/gameengine/Ketsji/KX_MeshProxy.cpp | 1 - source/gameengine/Ketsji/KX_MeshProxy.h | 1 - source/gameengine/Ketsji/KX_PolyProxy.cpp | 2 -- source/gameengine/Ketsji/KX_PolyProxy.h | 1 - source/gameengine/Ketsji/KX_VertexProxy.cpp | 2 -- source/gameengine/Ketsji/KX_VertexProxy.h | 1 - 12 files changed, 4 insertions(+), 47 deletions(-) diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index b5aca518e88..b86fbe0b163 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -524,8 +524,6 @@ void CValue::ProcessReplica() /* was AddDataToReplica in 2.48 */ m_ValFlags.RefCountDisabled = false; - ReplicaSetName(GetName()); - /* copy all props */ if (m_pNamedPropertyArray) { diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index cc791351d8a..065fe62d978 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -294,7 +294,6 @@ public: virtual STR_String GetName() = 0; // Retrieve the name of the value virtual void SetName(STR_String name) = 0; // Set the name of the value - virtual void ReplicaSetName(STR_String name) = 0; /** Sets the value to this cvalue. * @attention this particular function should never be called. Why not abstract? */ virtual void SetValue(CValue* newval); @@ -410,10 +409,10 @@ public: if (name.Length()) m_pstrNewName = new STR_String(name); } - virtual void ReplicaSetName(STR_String name) { - m_pstrNewName=NULL; - if (name.Length()) - m_pstrNewName = new STR_String(name); + virtual void ProcessReplica() { + CValue::ProcessReplica(); + if (m_pstrNewName) + m_pstrNewName = new STR_String(*m_pstrNewName); } virtual STR_String GetName() { diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 02a25916299..ec3651ddd1f 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -143,14 +143,6 @@ void SCA_ILogicBrick::SetName(STR_String name) } - -void SCA_ILogicBrick::ReplicaSetName(STR_String name) -{ - m_name = name; -} - - - bool SCA_ILogicBrick::IsActive() { return m_bActive; diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index f2353741d39..b8c6772fe8d 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -72,7 +72,6 @@ public: virtual double GetNumber(); virtual STR_String GetName(); virtual void SetName(STR_String name); - virtual void ReplicaSetName(STR_String name); bool IsActive(); void SetActive(bool active) ; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 8bd1e008336..ecc887eb567 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -199,26 +199,11 @@ void KX_GameObject::SetName(STR_String name) m_name = name; }; // Set the name of the value - - -void KX_GameObject::ReplicaSetName(STR_String name) -{ -} - - - - - - KX_IPhysicsController* KX_GameObject::GetPhysicsController() { return m_pPhysicsController1; } - - - - KX_GameObject* KX_GameObject::GetParent() { KX_GameObject* result = NULL; diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 479a3c1b574..2ca4fc6a63f 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -257,14 +257,6 @@ public: STR_String name ); - /** - * Inherited from CValue -- does nothing. - */ - void - ReplicaSetName( - STR_String name - ); - /** * Inherited from CValue -- return a new copy of this * instance allocated on the heap. Ownership of the new diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 65b163106c9..75e46da072e 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -138,7 +138,6 @@ double KX_MeshProxy::GetNumber() { return -1;} STR_String KX_MeshProxy::GetName() { return m_meshobj->GetName();} void KX_MeshProxy::SetName(STR_String name) { }; CValue* KX_MeshProxy::GetReplica() { return NULL;} -void KX_MeshProxy::ReplicaSetName(STR_String name) {}; // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index ce9e8fc39c5..f775c963c1e 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -53,7 +53,6 @@ public: virtual RAS_MeshObject* GetMesh() { return m_meshobj; } virtual STR_String GetName(); virtual void SetName(STR_String name); // Set the name of the value - virtual void ReplicaSetName(STR_String name); virtual CValue* GetReplica(); // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index fefea232e99..0ab55a86078 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -183,8 +183,6 @@ double KX_PolyProxy::GetNumber() { return -1;} STR_String KX_PolyProxy::GetName() { return sPolyName;} void KX_PolyProxy::SetName(STR_String) { }; CValue* KX_PolyProxy::GetReplica() { return NULL;} -void KX_PolyProxy::ReplicaSetName(STR_String) {}; - // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index 88a06850ee0..223193ec519 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -48,7 +48,6 @@ public: double GetNumber(); STR_String GetName(); void SetName(STR_String name); // Set the name of the value - void ReplicaSetName(STR_String name); CValue* GetReplica(); diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index e5078bfa18b..6b2507b8b31 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -340,8 +340,6 @@ double KX_VertexProxy::GetNumber() { return -1;} STR_String KX_VertexProxy::GetName() { return sVertexName;} void KX_VertexProxy::SetName(STR_String) { }; CValue* KX_VertexProxy::GetReplica() { return NULL;} -void KX_VertexProxy::ReplicaSetName(STR_String) {}; - // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 50fe6b27704..81dd0d222a7 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -49,7 +49,6 @@ public: double GetNumber(); STR_String GetName(); void SetName(STR_String name); // Set the name of the value - void ReplicaSetName(STR_String name); CValue* GetReplica(); From 971cabc2d687c86b8ff1e7a5a57474d85450b170 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 22 Apr 2009 17:06:47 +0000 Subject: [PATCH 035/444] Bugfix #18058 Ray-transparent didn't pass on thread number to shading code, giving "blothes" in render, when using node materials. This also rewinds Campbells commit of feb 21, which tackled the error, but not the cause. --- source/blender/blenkernel/intern/node.c | 9 ++------- source/blender/render/intern/source/rayshade.c | 11 ++++++----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index e4e5883b2d8..413c2fc20f5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1982,9 +1982,9 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack) } } +/* notes below are ancient! (ton) */ /* stack indices make sure all nodes only write in allocated data, for making it thread safe */ /* only root tree gets the stack, to enable instances to have own stack entries */ -/* only two threads now! */ /* per tree (and per group) unique indices are created */ /* the index_ext we need to be able to map from groups to the group-node own stack */ @@ -1999,14 +1999,9 @@ static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread) ListBase *lb= &ntree->threadstack[thread]; bNodeThreadStack *nts; - /* for material shading this is called quite a lot (perhaps too much locking unlocking) - * however without locking we get bug #18058 - Campbell */ - BLI_lock_thread(LOCK_CUSTOM1); - for(nts=lb->first; nts; nts=nts->next) { if(!nts->used) { nts->used= 1; - BLI_unlock_thread(LOCK_CUSTOM1); return nts; } } @@ -2014,7 +2009,7 @@ static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread) nts->stack= MEM_dupallocN(ntree->stack); nts->used= 1; BLI_addtail(lb, nts); - BLI_unlock_thread(LOCK_CUSTOM1); + return nts; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 46a7a1c556c..c6dd8d6890e 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1273,7 +1273,7 @@ static void addAlphaLight(float *shadfac, float *col, float alpha, float filter) shadfac[3]= (1.0f-alpha)*shadfac[3]; } -static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) +static void ray_trace_shadow_tra(Isect *is, int thread, int depth, int traflag) { /* ray to lamp, find first face that intersects, check alpha properties, if it has col[3]>0.0f continue. so exit when alpha is full */ @@ -1291,6 +1291,7 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) shi.depth= 1; /* only used to indicate tracing */ shi.mask= 1; + shi.thread= thread; /*shi.osatex= 0; shi.thread= shi.sample= 0; @@ -1315,7 +1316,7 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) is->oborig= RAY_OBJECT_SET(&R, shi.obi); is->faceorig= (RayFace*)shi.vlr; - ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA); + ray_trace_shadow_tra(is, thread, depth-1, traflag | RAY_TRA); } } } @@ -1943,7 +1944,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * isec->col[0]= isec->col[1]= isec->col[2]= 1.0f; isec->col[3]= 1.0f; - ray_trace_shadow_tra(isec, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(isec, shi->thread, DEPTH_SHADOW_TRA, 0); shadfac[0] += isec->col[0]; shadfac[1] += isec->col[1]; shadfac[2] += isec->col[2]; @@ -2041,7 +2042,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa isec->col[0]= isec->col[1]= isec->col[2]= 1.0f; isec->col[3]= 1.0f; - ray_trace_shadow_tra(isec, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(isec, shi->thread, DEPTH_SHADOW_TRA, 0); shadfac[0] += isec->col[0]; shadfac[1] += isec->col[1]; shadfac[2] += isec->col[2]; @@ -2122,7 +2123,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) isec.col[0]= isec.col[1]= isec.col[2]= 1.0f; isec.col[3]= 1.0f; - ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(&isec, shi->thread, DEPTH_SHADOW_TRA, 0); QUATCOPY(shadfac, isec.col); } else if(RE_ray_tree_intersect(R.raytree, &isec)) shadfac[3]= 0.0f; From b22819f686539f75438938ed45751e7dc3405a0c Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 22 Apr 2009 17:35:37 +0000 Subject: [PATCH 036/444] Bugfix #18039 Armature modifier didn't set amd->prevCos temp variable to NULL after freeing. Saving this in file will cause error or crash on reading. Quite weird how it survived so long? --- source/blender/blenkernel/intern/modifier.c | 4 +++- source/blender/blenloader/intern/readfile.c | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7977e7b0160..f7620f5b88c 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -8846,8 +8846,10 @@ void modifier_freeTemporaryData(ModifierData *md) if(md->type == eModifierType_Armature) { ArmatureModifierData *amd= (ArmatureModifierData*)md; - if(amd->prevCos) + if(amd->prevCos) { MEM_freeN(amd->prevCos); + amd->prevCos= NULL; + } } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 477f5a6cb59..ce154755651 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3176,6 +3176,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->emCache = smd->mCache = 0; } + else if (md->type==eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData*) md; + + amd->prevCos= NULL; + } else if (md->type==eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData*) md; From 48f483d14f1ff6dd9e5b4c87cb8d75ac862f3157 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 22 Apr 2009 18:20:41 +0000 Subject: [PATCH 037/444] BGE: some more cleanup, implement proper GetReplica/ProcessReplica workflow for touch/near/radar sensor. Remove duplicated code. --- source/gameengine/Ketsji/KX_NearSensor.cpp | 56 ++++++++------------- source/gameengine/Ketsji/KX_NearSensor.h | 1 + source/gameengine/Ketsji/KX_RadarSensor.cpp | 28 ++--------- source/gameengine/Ketsji/KX_RadarSensor.h | 1 + source/gameengine/Ketsji/KX_TouchSensor.cpp | 9 +++- source/gameengine/Ketsji/KX_TouchSensor.h | 1 + 6 files changed, 35 insertions(+), 61 deletions(-) diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index 23c525a1b52..2f1a3af78fa 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -109,51 +109,35 @@ void KX_NearSensor::UnregisterSumo(KX_TouchEventManager* touchman) CValue* KX_NearSensor::GetReplica() { KX_NearSensor* replica = new KX_NearSensor(*this); - replica->m_colliders = new CListValue(); - replica->Init(); replica->ProcessReplica(); - - replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR); - - if (replica->m_physCtrl) - { - replica->m_physCtrl = replica->m_physCtrl->GetReplica(); - if (replica->m_physCtrl) - { - //static_cast(m_eventmgr)->GetPhysicsEnvironment()->addSensor(replica->m_physCtrl); - replica->m_physCtrl->SetMargin(m_Margin); - replica->m_physCtrl->setNewClientInfo(replica->m_client_info); - } - - } - //Wrong: the parent object could be a child, this code works only if it is a root parent. - //Anyway, at this stage, the parent object is already synchronized, nothing to do. - //bool parentUpdated = false; - //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL, parentUpdated); - replica->SynchronizeTransform(); - return replica; } - +void KX_NearSensor::ProcessReplica() +{ + KX_TouchSensor::ProcessReplica(); + + m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR); + + if (m_physCtrl) + { + m_physCtrl = m_physCtrl->GetReplica(); + if (m_physCtrl) + { + //static_cast(m_eventmgr)->GetPhysicsEnvironment()->addSensor(replica->m_physCtrl); + m_physCtrl->SetMargin(m_Margin); + m_physCtrl->setNewClientInfo(m_client_info); + } + + } +} void KX_NearSensor::ReParent(SCA_IObject* parent) { m_client_info->m_gameobject = static_cast(parent); m_client_info->m_sensors.push_back(this); - - -/* KX_ClientObjectInfo *client_info = gameobj->getClientInfo(); - client_info->m_gameobject = gameobj; - client_info->m_auxilary_info = NULL; - - client_info->m_sensors.push_back(this); - SCA_ISensor::ReParent(parent); -*/ - //Not needed, was done in GetReplica() already - //bool parentUpdated = false; - //((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated); - //SynchronizeTransform(); + //Synchronize here with the actual parent. + SynchronizeTransform(); SCA_ISensor::ReParent(parent); } diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 144f75f4772..5b65312472a 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -70,6 +70,7 @@ public: virtual ~KX_NearSensor(); virtual void SynchronizeTransform(); virtual CValue* GetReplica(); + virtual void ProcessReplica(); virtual bool Evaluate(CValue* event); virtual void ReParent(SCA_IObject* parent); diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index d9b8b6fec5b..bf4b0f67e03 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -80,33 +80,15 @@ KX_RadarSensor::~KX_RadarSensor() CValue* KX_RadarSensor::GetReplica() { KX_RadarSensor* replica = new KX_RadarSensor(*this); - replica->m_colliders = new CListValue(); - replica->Init(); replica->ProcessReplica(); - - replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::RADAR); - - if (replica->m_physCtrl) - { - replica->m_physCtrl = replica->m_physCtrl->GetReplica(); - if (replica->m_physCtrl) - { - replica->m_physCtrl->setNewClientInfo(replica->m_client_info); - } - } - - //todo: make sure replication works fine! - //>m_sumoObj = new SM_Object(DT_NewCone(m_coneradius, m_coneheight),NULL,NULL,NULL); - //replica->m_sumoObj->setMargin(m_Margin); - //replica->m_sumoObj->setClientObject(replica->m_client_info); - //Wrong: see KX_TouchSensor - //bool parentUpdated = false; - //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated); - replica->SynchronizeTransform(); - return replica; } +void KX_RadarSensor::ProcessReplica() +{ + KX_NearSensor::ProcessReplica(); + m_client_info->m_type = KX_ClientObjectInfo::RADAR; +} /** * Transforms the collision object. A cone is not correctly centered diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 8389a2a29eb..b4268797f85 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -76,6 +76,7 @@ public: virtual ~KX_RadarSensor(); virtual void SynchronizeTransform(); virtual CValue* GetReplica(); + virtual void ProcessReplica(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index cddd018ef33..2addfc31ff3 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -142,12 +142,17 @@ KX_TouchSensor::~KX_TouchSensor() CValue* KX_TouchSensor::GetReplica() { KX_TouchSensor* replica = new KX_TouchSensor(*this); - replica->m_colliders = new CListValue(); - replica->Init(); replica->ProcessReplica(); return replica; } +void KX_TouchSensor::ProcessReplica() +{ + SCA_ISensor::ProcessReplica(); + m_colliders = new CListValue(); + Init(); +} + void KX_TouchSensor::ReParent(SCA_IObject* parent) { KX_GameObject *gameobj = static_cast(parent); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 4bcc313b65b..056b5701937 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -84,6 +84,7 @@ public: virtual ~KX_TouchSensor(); virtual CValue* GetReplica(); + virtual void ProcessReplica(); virtual void SynchronizeTransform(); virtual bool Evaluate(CValue* event); virtual void Init(); From f06802050d00cde6eeda93bb074599a1b8c8e7b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Apr 2009 19:04:00 +0000 Subject: [PATCH 038/444] [#18587] bugfix #18425 (Window.EditMode() ignores undo information) from Lorenzo Pierfederici (lento) --- source/blender/python/api2_2x/Window.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c index 40f6d52d8da..fe7cee5b0e1 100644 --- a/source/blender/python/api2_2x/Window.c +++ b/source/blender/python/api2_2x/Window.c @@ -954,9 +954,11 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args ) enter_editmode(0); } } else if( G.obedit ) { - if( undo_str_len > 63 ) - undo_str[63] = '\0'; /* 64 is max */ - BIF_undo_push( undo_str ); /* This checks user undo settings */ + if( do_undo ) { + if( undo_str_len > 63 ) + undo_str[63] = '\0'; /* 64 is max */ + BIF_undo_push( undo_str ); /* This checks user undo settings */ + } exit_editmode( EM_FREEDATA ); //update armatures From fd108f101988ad119b8a5ed4e83cd64227fc1e96 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Apr 2009 20:43:41 +0000 Subject: [PATCH 039/444] [#18586] [bug] Ray sensor doesn't return a hit object Supporting len(GameOb) to see how many properties it has backfired since it can then evaluate as false. --- source/gameengine/Ketsji/KX_GameObject.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index ecc887eb567..bf6a81c8493 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1192,21 +1192,6 @@ PyObject* KX_GameObject::PyGetPosition() return PyObjectFrom(NodeGetWorldPosition()); } - -Py_ssize_t KX_GameObject::Map_Len(PyObject* self_v) -{ - KX_GameObject* self= static_castBGE_PROXY_REF(self_v); - - if (self==NULL) /* not sure what to do here */ - return 0; - - Py_ssize_t len= self->GetPropertyCount(); - if(self->m_attr_dict) - len += PyDict_Size(self->m_attr_dict); - return len; -} - - PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) { KX_GameObject* self= static_castBGE_PROXY_REF(self_v); @@ -1329,9 +1314,9 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) return 0; /* success */ } - +/* Cant set the len otherwise it can evaluate as false */ PyMappingMethods KX_GameObject::Mapping = { - (lenfunc)KX_GameObject::Map_Len, /*inquiry mp_length */ + (lenfunc)NULL , /*inquiry mp_length */ (binaryfunc)KX_GameObject::Map_GetItem, /*binaryfunc mp_subscript */ (objobjargproc)KX_GameObject::Map_SetItem, /*objobjargproc mp_ass_subscript */ }; From 90508ed125c8dc81425e74c1e19e3510e1f7799c Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 22 Apr 2009 22:12:36 +0000 Subject: [PATCH 040/444] BGE bug #17670: Python controlled mist doesnt work in textured mode. --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 6 +----- source/gameengine/Ketsji/KX_PythonInit.cpp | 12 ++++++++++++ source/gameengine/Rasterizer/RAS_IRasterizer.h | 1 + .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 4 ++++ .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 4cfe3339631..a9206c1bb8f 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1000,7 +1000,7 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi) wi->getAmbientColorBlue() ); - if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) + if (m_drawingmode >= RAS_IRasterizer::KX_SOLID) { if (wi->hasMist()) { @@ -1012,10 +1012,6 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi) wi->getMistColorBlue() ); } - else - { - m_rasterizer->DisableFog(); - } } } } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 873e49be6bb..8edc71aeec7 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -632,6 +632,17 @@ static PyObject* gPySetMistColor(PyObject*, PyObject* value) Py_RETURN_NONE; } +static PyObject* gPyDisableMist(PyObject*) +{ + + if (!gp_Rasterizer) { + PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available"); + return NULL; + } + gp_Rasterizer->DisableFog(); + + Py_RETURN_NONE; +} static PyObject* gPySetMistStart(PyObject*, PyObject* args) @@ -900,6 +911,7 @@ static struct PyMethodDef rasterizer_methods[] = { METH_VARARGS, "setMousePosition(int x,int y)"}, {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"}, {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"}, + {"disableMist",(PyCFunction)gPyDisableMist,METH_NOARGS,"turn off mist"}, {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"}, {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index cfeda06e670..96472b112d6 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -280,6 +280,7 @@ public: /** */ virtual void DisableFog()=0; + virtual bool IsFogEnabled()=0; virtual void SetBackColor(float red, float green, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 50f56db0645..bf50cde2280 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -210,6 +210,10 @@ void RAS_OpenGLRasterizer::DisableFog() m_fogenabled = false; } +bool RAS_OpenGLRasterizer::IsFogEnabled() +{ + return m_fogenabled; +} void RAS_OpenGLRasterizer::DisplayFog() diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 83a9f759a8b..6013946fadf 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -190,6 +190,7 @@ public: void DisableFog(); virtual void DisplayFog(); + virtual bool IsFogEnabled(); virtual void SetBackColor( float red, From 1ca6768051a74a370bf16f877a5ffc1691545ae6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 22 Apr 2009 22:38:23 +0000 Subject: [PATCH 041/444] Fix for bug #18509: mesh deform modifier not working on load, with cage on hidden layer. --- source/blender/blenkernel/intern/modifier.c | 92 ++++++++++++--------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f7620f5b88c..10bcb2e09f2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6054,8 +6054,6 @@ static void surfaceModifier_deformVerts( float (*vertexCos)[3], int numVerts) { SurfaceModifierData *surmd = (SurfaceModifierData*) md; - DerivedMesh *dm = NULL; - float current_time = 0; unsigned int numverts = 0, i = 0; if(surmd->dm) @@ -6258,6 +6256,48 @@ static int is_last_displist(Object *ob) return 0; } + +static DerivedMesh *get_original_dm(Object *ob, float (*vertexCos)[3], int orco) +{ + DerivedMesh *dm= NULL; + + if(ob->type==OB_MESH) { + dm = CDDM_from_mesh((Mesh*)(ob->data), ob); + + if(vertexCos) { + CDDM_apply_vert_coords(dm, vertexCos); + //CDDM_calc_normals(dm); + } + + if(orco) + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); + } + else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) { + Object *tmpobj; + Curve *tmpcu; + + if(is_last_displist(ob)) { + /* copies object and modifiers (but not the data) */ + tmpobj= copy_object(ob); + tmpcu = (Curve *)tmpobj->data; + tmpcu->id.us--; + + /* copies the data */ + tmpobj->data = copy_curve((Curve *) ob->data); + + makeDispListCurveTypes(tmpobj, 1); + nurbs_to_mesh(tmpobj); + + dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj); + //CDDM_calc_normals(dm); + + free_libblock_us(&G.main->object, tmpobj); + } + } + + return dm; +} + /* saves the current emitter state for a particle system and calculates particles */ static void particleSystemModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, @@ -6285,43 +6325,13 @@ static void particleSystemModifier_deformVerts( if(!psys_check_enabled(ob, psys)) return; - if(dm==0){ - if(ob->type==OB_MESH){ - dm = CDDM_from_mesh((Mesh*)(ob->data), ob); + if(dm==0) { + dm= get_original_dm(ob, vertexCos, 1); - CDDM_apply_vert_coords(dm, vertexCos); - //CDDM_calc_normals(dm); - - DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); + if(!dm) + return; - needsFree=1; - } - else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)){ - Object *tmpobj; - Curve *tmpcu; - - if(is_last_displist(ob)){ - /* copies object and modifiers (but not the data) */ - tmpobj= copy_object( ob ); - tmpcu = (Curve *)tmpobj->data; - tmpcu->id.us--; - - /* copies the data */ - tmpobj->data = copy_curve( (Curve *) ob->data ); - - makeDispListCurveTypes( tmpobj, 1 ); - nurbs_to_mesh( tmpobj ); - - dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj); - //CDDM_calc_normals(dm); - - free_libblock_us( &G.main->object, tmpobj ); - - needsFree=1; - } - else return; - } - else return; + needsFree= 1; } /* clear old dm */ @@ -7658,6 +7668,14 @@ static void meshdeformModifier_do( } else cagedm= mmd->object->derivedFinal; + + /* if we don't have one computed, use derivedmesh from data + * without any modifiers */ + if(!cagedm) { + cagedm= get_original_dm(mmd->object, NULL, 0); + if(cagedm) + cagedm->needsFree= 1; + } if(!cagedm) return; From d568794a9873eed10a9d240c1e1a1ba52aba929c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 22 Apr 2009 23:01:40 +0000 Subject: [PATCH 042/444] Fix for bug #14410: multires + vertex colors crash rendering or baking while in editmode. --- source/blender/blenkernel/intern/multires.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 8112c64d79f..ee9255df837 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -966,9 +966,9 @@ void multires_update_levels(Mesh *me, const int render) multires_update_colors(me, em); } -static void check_colors(Mesh *me) +static void check_colors(Mesh *me, const int render) { - CustomData *src= G.obedit ? &G.editMesh->fdata : &me->fdata; + CustomData *src= (!render && G.obedit)? &G.editMesh->fdata : &me->fdata; const char col= CustomData_has_layer(src, CD_MCOL); /* Check if vertex colors have been deleted or added */ @@ -1110,7 +1110,7 @@ void multires_add_level(Object *ob, Mesh *me, const char subdiv_type) lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel"); if(me->pv) mesh_pmv_off(ob, me); - check_colors(me); + check_colors(me, 0); multires_update_levels(me, 0); ++me->mr->level_count; @@ -1276,7 +1276,7 @@ void multires_set_level(Object *ob, Mesh *me, const int render) { if(me->pv) mesh_pmv_off(ob, me); - check_colors(me); + check_colors(me, render); multires_update_levels(me, render); me->mr->current= me->mr->newlvl; From 6a270ecb9435fd695988de5c685c65cac5a43c79 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 23 Apr 2009 00:32:33 +0000 Subject: [PATCH 043/444] BGE Python API CListValue fixes - Disable changing CValueLists that the BGE uses internally (scene.objects.append(1) would crash when drawing) - val=clist+list would modify clist in place, now return a new value. - clist.append([....]), was working like extend. - clist.append(val) didnt work for most CValue types like KX_GameObjects. Other changes - "isValid" was always returning True. - Set all errors for invalid proxy access to PyExc_SystemError (was using a mix of error types) - Added PyObjectPlus::InvalidateProxy() to manually invalidate, though if python ever gains access again, it will make a new valid proxy. This is so removing an object from a scene can invalidate the object even if its stored elsewhere in a CValueList for eg. --- source/gameengine/Expressions/ListValue.cpp | 153 ++++++++++-------- .../gameengine/Expressions/PyObjectPlus.cpp | 25 ++- source/gameengine/Expressions/PyObjectPlus.h | 2 + source/gameengine/Expressions/Value.cpp | 28 ++-- source/gameengine/Expressions/Value.h | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 10 +- source/gameengine/Ketsji/KX_MeshProxy.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 10 +- source/gameengine/Ketsji/KX_SceneActuator.cpp | 4 +- 9 files changed, 146 insertions(+), 90 deletions(-) diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 6c92e805745..c78963142d1 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -39,8 +39,10 @@ Py_ssize_t listvalue_bufferlen(PyObject* self) PyObject* listvalue_buffer_item(PyObject* self, Py_ssize_t index) { CListValue *list= static_cast(BGE_PROXY_REF(self)); + CValue *cval; + if (list==NULL) { - PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = CList[i], "BGE_PROXY_ERROR_MSG); return NULL; } @@ -49,24 +51,25 @@ PyObject* listvalue_buffer_item(PyObject* self, Py_ssize_t index) if (index < 0) index = count+index; - if (index >= 0 && index < count) - { - PyObject* pyobj = list->GetValue(index)->ConvertValueToPython(); - if (pyobj) - return pyobj; - else - return list->GetValue(index)->GetProxy(); - + if (index < 0 || index >= count) { + PyErr_SetString(PyExc_IndexError, "CList[i]: Python ListIndex out of range in CValueList"); + return NULL; } - PyErr_SetString(PyExc_IndexError, "list[i]: Python ListIndex out of range in CValueList"); - return NULL; + + cval= list->GetValue(index); + + PyObject* pyobj = cval->ConvertValueToPython(); + if (pyobj) + return pyobj; + else + return cval->GetProxy(); } PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) { CListValue *list= static_cast(BGE_PROXY_REF(self)); if (list==NULL) { - PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "value = CList[i], "BGE_PROXY_ERROR_MSG); return NULL; } @@ -85,7 +88,7 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) } PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */ - PyErr_Format(PyExc_KeyError, "list[key]: '%s' key not in list", PyString_AsString(pyindex_str)); + PyErr_Format(PyExc_KeyError, "CList[key]: '%s' key not in list", PyString_AsString(pyindex_str)); Py_DECREF(pyindex_str); return NULL; } @@ -96,7 +99,7 @@ PyObject* listvalue_buffer_slice(PyObject* self,Py_ssize_t ilow, Py_ssize_t ihig { CListValue *list= static_cast(BGE_PROXY_REF(self)); if (list==NULL) { - PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = CList[i:j], "BGE_PROXY_ERROR_MSG); return NULL; } @@ -127,73 +130,79 @@ PyObject* listvalue_buffer_slice(PyObject* self,Py_ssize_t ilow, Py_ssize_t ihig } - -static PyObject * -listvalue_buffer_concat(PyObject * self, PyObject * other) +/* clist + list, return a list that python owns */ +static PyObject *listvalue_buffer_concat(PyObject * self, PyObject * other) { CListValue *listval= static_cast(BGE_PROXY_REF(self)); + int i, numitems, numitems_orig; + if (listval==NULL) { - PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG); return NULL; } + numitems_orig= listval->GetCount(); + // for now, we support CListValue concatenated with items // and CListValue concatenated to Python Lists // and CListValue concatenated with another CListValue - listval->AddRef(); - if (other->ob_type == &PyList_Type) + /* Shallow copy, dont use listval->GetReplica(), it will screw up with KX_GameObjects */ + CListValue* listval_new = new CListValue(); + + if (PyList_Check(other)) { + CValue* listitemval; bool error = false; - - int i; - int numitems = PyList_Size(other); + + numitems = PyList_Size(other); + + /* copy the first part of the list */ + listval_new->Resize(numitems_orig + numitems); + for (i=0;iSetValue(i, listval->GetValue(i)->AddRef()); + for (i=0;iConvertPythonToValue(listitem); - if (listitemval) - { - listval->Add(listitemval); - } else - { - error = true; + listitemval = listval->ConvertPythonToValue(PyList_GetItem(other,i), "cList + pyList: CListValue, "); + + if (listitemval) { + listval_new->SetValue(i+numitems_orig, listitemval); + } else { + error= true; + break; } } - + if (error) { - PyErr_SetString(PyExc_SystemError, "list.append(val): couldn't add one or more items to this CValueList"); + listval_new->Resize(numitems_orig+i); /* resize so we dont try release NULL pointers */ + listval_new->Release(); + return NULL; /* ConvertPythonToValue above sets the error */ + } + + } + else if (PyObject_TypeCheck(other, &CListValue::Type)) { + // add items from otherlist to this list + CListValue* otherval = static_cast(BGE_PROXY_REF(other)); + if(otherval==NULL) { + listval_new->Release(); + PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG); return NULL; } - - } else - { - if (other->ob_type == &CListValue::Type) - { - // add items from otherlist to this list - CListValue* otherval = (CListValue*) other; - - - for (int i=0;iGetCount();i++) - { - otherval->Add(listval->GetValue(i)->AddRef()); - } - } - else - { - CValue* objval = listval->ConvertPythonToValue(other); - if (objval) - { - listval->Add(objval); - } else - { - PyErr_SetString(PyExc_SystemError, "list.append(i): couldn't add item to this CValueList"); - return NULL; - } - } + + numitems = otherval->GetCount(); + + /* copy the first part of the list */ + listval_new->Resize(numitems_orig + numitems); /* resize so we dont try release NULL pointers */ + for (i=0;iSetValue(i, listval->GetValue(i)->AddRef()); + + /* now copy the other part of the list */ + for (i=0;iSetValue(i+numitems_orig, otherval->GetValue(i)->AddRef()); + } - - return self; + return listval_new->NewProxy(true); /* python owns this list */ } @@ -437,14 +446,24 @@ void CListValue::MergeList(CListValue *otherlist) { SetValue(i+numelements,otherlist->GetValue(i)->AddRef()); } - } - PyObject* CListValue::Pyappend(PyObject* value) { - return listvalue_buffer_concat(m_proxy, value); /* m_proxy is the same as self */ + CValue* objval = ConvertPythonToValue(value, "CList.append(i): CValueList, "); + + if (!objval) /* ConvertPythonToValue sets the error */ + return NULL; + + if (!BGE_PROXY_PYOWNS(m_proxy)) { + PyErr_SetString(PyExc_TypeError, "CList.append(i): this CValueList is used internally for the game engine and can't be modified"); + return NULL; + } + + Add(objval); + + Py_RETURN_NONE; } @@ -482,7 +501,7 @@ PyObject* CListValue::Pyindex(PyObject *value) { PyObject* result = NULL; - CValue* checkobj = ConvertPythonToValue(value); + CValue* checkobj = ConvertPythonToValue(value, "val = cList[i]: CValueList, "); if (checkobj==NULL) return NULL; /* ConvertPythonToValue sets the error */ @@ -499,7 +518,7 @@ PyObject* CListValue::Pyindex(PyObject *value) checkobj->Release(); if (result==NULL) { - PyErr_SetString(PyExc_ValueError, "list.index(x): x not in CListValue"); + PyErr_SetString(PyExc_ValueError, "CList.index(x): x not in CListValue"); } return result; @@ -511,7 +530,7 @@ PyObject* CListValue::Pycount(PyObject* value) { int numfound = 0; - CValue* checkobj = ConvertPythonToValue(value); + CValue* checkobj = ConvertPythonToValue(value, "cList.count(val): CValueList, "); if (checkobj==NULL) { /* in this case just return that there are no items in the list */ PyErr_Clear(); diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 57a61ac37ae..54f076741cc 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -138,9 +138,9 @@ PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) PyObjectPlus *self_plus= BGE_PROXY_REF(self); if(self_plus==NULL) { if(!strcmp("isValid", PyString_AsString(attr))) { - Py_RETURN_TRUE; + Py_RETURN_FALSE; } - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; } @@ -171,7 +171,7 @@ int PyObjectPlus::py_base_setattro(PyObject *self, PyObject *attr, PyObject *val { PyObjectPlus *self_plus= BGE_PROXY_REF(self); if(self_plus==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return -1; } @@ -186,7 +186,7 @@ PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the ent PyObjectPlus *self_plus= BGE_PROXY_REF(self); if(self_plus==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; } @@ -818,6 +818,23 @@ void PyObjectPlus::ProcessReplica() m_proxy= NULL; } +/* Sometimes we might want to manually invalidate a BGE type even if + * it hasnt been released by the BGE, say for example when an object + * is removed from a scene, accessing it may cause problems. + * + * In this case the current proxy is made invalid, disowned, + * and will raise an error on access. However if python can get access + * to this class again it will make a new proxy and work as expected. + */ +void PyObjectPlus::InvalidateProxy() // check typename of each parent +{ + if(m_proxy) { + BGE_PROXY_REF(m_proxy)=NULL; + Py_DECREF(m_proxy); + m_proxy= NULL; + } +} + /* Utility function called by the macro py_getattro_up() * for getting ob.__dict__() values from our PyObject * this is used by python for doing dir() on an object, so its good diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 52e59f7730c..257851ef4b3 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -451,6 +451,8 @@ public: static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp); static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns); + void InvalidateProxy(); + /** * Makes sure any internal data owned by this class is deep copied. */ diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index b86fbe0b163..6e8f2ba1061 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -604,7 +604,7 @@ PyObject* CValue::py_getattro_dict() { py_getattro_dict_up(PyObjectPlus); } -CValue* CValue::ConvertPythonToValue(PyObject* pyobj) +CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) { CValue* vallie = NULL; @@ -620,7 +620,7 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj) for (i=0;iAdd(listitemval); @@ -657,13 +657,22 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj) { vallie = new CStringValue(PyString_AsString(pyobj),""); } else - if (pyobj->ob_type==&CValue::Type || pyobj->ob_type==&CListValue::Type) + if (BGE_PROXY_CHECK_TYPE(pyobj)) /* Note, dont let these get assigned to GameObject props, must check elsewhere */ { - vallie = ((CValue*) pyobj)->AddRef(); + if (BGE_PROXY_REF(pyobj) && (BGE_PROXY_REF(pyobj))->isA(&CValue::Type)) + { + vallie = (static_cast(BGE_PROXY_REF(pyobj)))->AddRef(); + } else { + + if(BGE_PROXY_REF(pyobj)) /* this is not a CValue */ + PyErr_Format(PyExc_TypeError, "%sgame engine python type cannot be used as a property", error_prefix); + else /* PyObjectPlus_Proxy has been removed, cant use */ + PyErr_Format(PyExc_SystemError, "%s"BGE_PROXY_ERROR_MSG, error_prefix); + } } else { /* return an error value from the caller */ - PyErr_SetString(PyExc_TypeError, "This python type could not be converted to a to a game engine property"); + PyErr_Format(PyExc_TypeError, "%scould convert python value to a game engine property", error_prefix); } return vallie; @@ -682,10 +691,11 @@ int CValue::py_delattro(PyObject *attr) int CValue::py_setattro(PyObject *attr, PyObject* pyobj) { char *attr_str= PyString_AsString(attr); - CValue* oldprop = GetProperty(attr_str); - - CValue* vallie = ConvertPythonToValue(pyobj); - if (vallie) + CValue* oldprop = GetProperty(attr_str); + CValue* vallie; + + /* Dissallow python to assign GameObjects, Scenes etc as values */ + if ((BGE_PROXY_CHECK_TYPE(pyobj)==0) && (vallie = ConvertPythonToValue(pyobj, "cvalue.attr = value: "))) { if (oldprop) oldprop->SetValue(vallie); diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 065fe62d978..97ce9cddcea 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -230,7 +230,7 @@ public: return NULL; } - virtual CValue* ConvertPythonToValue(PyObject* pyobj); + virtual CValue* ConvertPythonToValue(PyObject* pyobj, const char *error_prefix); virtual int py_delattro(PyObject *attr); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index bf6a81c8493..7629f9d8f1a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1200,7 +1200,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) PyObject* pyconvert; if (self==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; } @@ -1234,7 +1234,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) PyErr_Clear(); if (self==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return -1; } @@ -1261,9 +1261,9 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) int set= 0; /* as CValue */ - if(attr_str) + if(attr_str && BGE_PROXY_CHECK_TYPE(val)==0) /* dont allow GameObjects for eg to be assigned to CValue props */ { - CValue* vallie = self->ConvertPythonToValue(val); + CValue* vallie = self->ConvertPythonToValue(val, ""); /* error unused */ if(vallie) { @@ -2643,7 +2643,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py /* sets the error */ if (*object==NULL) { - PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); + PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); return false; } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 75e46da072e..009364a3d7b 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -348,7 +348,7 @@ bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **object, bool py_none /* sets the error */ if (*object==NULL) { - PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); + PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); return false; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 6917305522e..0c26a6a7b3b 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -891,7 +891,15 @@ void KX_Scene::RemoveObject(class CValue* gameobj) { KX_GameObject* newobj = (KX_GameObject*) gameobj; - // first disconnect child from parent + /* Invalidate the python reference, since the object may exist in script lists + * its possible that it wont be automatically invalidated, so do it manually here, + * + * if for some reason the object is added back into the scene python can always get a new Proxy + */ + gameobj->InvalidateProxy(); + + + // disconnect child from parent SG_Node* node = newobj->GetSGNode(); if (node) diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 6f622939dc4..7d2bea25d2c 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -316,7 +316,7 @@ int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_ if(camOb==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return 1; } @@ -435,7 +435,7 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* args) new_camera = static_castBGE_PROXY_REF(cam); if(new_camera==NULL) { - PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; } From e8f5c7500592bad6c59f2cbf1e8ffc9d78330230 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 23 Apr 2009 00:47:45 +0000 Subject: [PATCH 044/444] patch from Mitchell Stokes, comments only - KX_PYATTRIBUTE_TODO for missing attributes --- source/gameengine/Converter/BL_ActionActuator.cpp | 1 + source/gameengine/GameLogic/SCA_ILogicBrick.cpp | 1 + source/gameengine/GameLogic/SCA_ISensor.cpp | 3 +++ source/gameengine/GameLogic/SCA_JoystickSensor.cpp | 2 +- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 3 +++ source/gameengine/Ketsji/KX_ConstraintWrapper.cpp | 1 + source/gameengine/Ketsji/KX_GameActuator.cpp | 1 + source/gameengine/Ketsji/KX_ObjectActuator.cpp | 11 +++++++++++ source/gameengine/Ketsji/KX_ParentActuator.cpp | 1 + source/gameengine/Ketsji/KX_PolyProxy.cpp | 1 + source/gameengine/Ketsji/KX_SceneActuator.cpp | 2 ++ source/gameengine/Ketsji/KX_VertexProxy.cpp | 1 + 12 files changed, 27 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index e06008ff891..3ad55f5ee12 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -1010,6 +1010,7 @@ PyAttributeDef BL_ActionActuator::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("continue", BL_ActionActuator, m_end_reset), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime), KX_PYATTRIBUTE_SHORT_RW_CHECK("type",0,100,false,BL_ActionActuator,m_playtype,CheckType), + //KX_PYATTRIBUTE_TODO("channel"), { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index ec3651ddd1f..8439dbac268 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -249,6 +249,7 @@ PyMethodDef SCA_ILogicBrick::Methods[] = { PyAttributeDef SCA_ILogicBrick::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("owner", SCA_ILogicBrick, pyattr_get_owner), KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Ueber_Priority), + //KX_PYATTRIBUTE_TODO("name"), {NULL} //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index dde970962b6..b556c14831e 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -456,6 +456,9 @@ PyAttributeDef SCA_ISensor::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("level",SCA_ISensor,m_level), KX_PYATTRIBUTE_RO_FUNCTION("triggered", SCA_ISensor, pyattr_get_triggered), KX_PYATTRIBUTE_RO_FUNCTION("positive", SCA_ISensor, pyattr_get_positive), + //KX_PYATTRIBUTE_TODO("links"), + //KX_PYATTRIBUTE_TODO("posTicks"), + //KX_PYATTRIBUTE_TODO("negTicks"), { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 11b31c67edd..b9d99177259 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -330,7 +330,7 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_JoystickSensor, pyattr_get_num_buttons), KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_JoystickSensor, pyattr_get_num_hats), KX_PYATTRIBUTE_RO_FUNCTION("connected", SCA_JoystickSensor, pyattr_get_connected), - + //KX_PYATTRIBUTE_TODO("events"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 7378113bc31..9f11ea11819 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -771,6 +771,9 @@ PyMethodDef KX_BlenderMaterial::Methods[] = }; PyAttributeDef KX_BlenderMaterial::Attributes[] = { + //KX_PYATTRIBUTE_TODO("shader"), + //KX_PYATTRIBUTE_TODO("materialIndex"), + //KX_PYATTRIBUTE_TODO("blending"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index c537c9abe01..0e6678b8572 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -131,5 +131,6 @@ PyMethodDef KX_ConstraintWrapper::Methods[] = { }; PyAttributeDef KX_ConstraintWrapper::Attributes[] = { + //KX_PYATTRIBUTE_TODO("constraintId"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 514fb74f6bf..a46318d0468 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -248,6 +248,7 @@ PyMethodDef KX_GameActuator::Methods[] = PyAttributeDef KX_GameActuator::Attributes[] = { KX_PYATTRIBUTE_STRING_RW("file",0,100,false,KX_GameActuator,m_filename), + //KX_PYATTRIBUTE_TODO("mode"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index b90967d610c..86ae082523f 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -330,6 +330,17 @@ PyMethodDef KX_ObjectActuator::Methods[] = { }; PyAttributeDef KX_ObjectActuator::Attributes[] = { + //KX_PYATTRIBUTE_TODO("force"), + //KX_PYATTRIBUTE_TODO("torque"), + //KX_PYATTRIBUTE_TODO("dLoc"), + //KX_PYATTRIBUTE_TODO("dRot"), + //KX_PYATTRIBUTE_TODO("linV"), + //KX_PYATTRIBUTE_TODO("angV"), + //KX_PYATTRIBUTE_TODO("damping"), + //KX_PYATTRIBUTE_TODO("forceLimitX"), + //KX_PYATTRIBUTE_TODO("forceLimitY"), + //KX_PYATTRIBUTE_TODO("forceLimitZ"), + //KX_PYATTRIBUTE_TODO("pid"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index afc16ba994c..ffd7185f235 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -173,6 +173,7 @@ PyMethodDef KX_ParentActuator::Methods[] = { PyAttributeDef KX_ParentActuator::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object), + //KX_PYATTRIBUTE_TODO("mode"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index 0ab55a86078..33e215387b7 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -79,6 +79,7 @@ PyMethodDef KX_PolyProxy::Methods[] = { PyAttributeDef KX_PolyProxy::Attributes[] = { /* All dummy's so they come up in a dir() */ + //KX_PYATTRIBUTE_TODO("DummyProps"), KX_PYATTRIBUTE_DUMMY("matname"), KX_PYATTRIBUTE_DUMMY("texture"), KX_PYATTRIBUTE_DUMMY("material"), diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 7d2bea25d2c..4447ff48766 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -270,6 +270,8 @@ PyMethodDef KX_SceneActuator::Methods[] = PyAttributeDef KX_SceneActuator::Attributes[] = { KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName), KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera), + //KX_PYATTRIBUTE_TODO("useRestart"), + //KX_PYATTRIBUTE_TODO("mode"), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 6b2507b8b31..629fadff86a 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -79,6 +79,7 @@ PyMethodDef KX_VertexProxy::Methods[] = { }; PyAttributeDef KX_VertexProxy::Attributes[] = { + //KX_PYATTRIBUTE_TODO("DummyProps"), KX_PYATTRIBUTE_DUMMY("x"), KX_PYATTRIBUTE_DUMMY("y"), From 7ac233be8abc405cc997f032c9ab146c2ab8ea89 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 23 Apr 2009 00:49:38 +0000 Subject: [PATCH 045/444] BGE Rasterizer methods to handle Screen Space - (getScreenPosition, getScreenVect, getScreenRay) getScreenPosition(obj): - Gets the position of an object projected on screen space. getScreenVect(x, y): - Gets the vector from the camera position in the screen coordinate direction. getScreenRay(x, y, dist, property): - Look towards a screen coordinate (x,y) and find first object hit within dist that matches prop. - The ray is a call to KX_GameObject->rayCastTo from the KX_Camera object. Patch [#18589] test files can be found there. Patch reviewed by Campbell --- source/gameengine/Ketsji/KX_PythonInit.cpp | 127 +++++++++++++++++++++ source/gameengine/PyDoc/KX_GameObject.py | 2 +- source/gameengine/PyDoc/Rasterizer.py | 43 +++++++ 3 files changed, 171 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 8edc71aeec7..bf3b64f1ecf 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -484,6 +484,127 @@ static struct PyMethodDef game_methods[] = { }; +static PyObject* gPyGetScreenPosition(PyObject*, PyObject* value) +{ + MT_Vector3 vect; + KX_GameObject *obj = NULL; + + if (!PyVecTo(value, vect)) + { + if(ConvertPythonToGameObject(value, &obj, true, "")) + { + PyErr_Clear(); + vect = MT_Vector3(obj->NodeGetWorldPosition()); + } + else + { + PyErr_SetString(PyExc_TypeError, "Error in getScreenPosition. Expected a Vector3 or a KX_GameObject or a string for a name of a KX_GameObject"); + return NULL; + } + } + + GLdouble modelMatrix[16]; + GLdouble projMatrix[16]; + GLint viewport[4]; + GLdouble win[3]; + + glGetIntegerv(GL_VIEWPORT, viewport); + glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + + gluProject(vect[0], vect[1], vect[2], modelMatrix, projMatrix, viewport, &win[0], &win[1], &win[2]); + + vect[0] = win[0] / (viewport[0] + viewport[2]); + vect[1] = win[1] / (viewport[1] + viewport[3]); + + PyObject* ret = PyTuple_New(2); + if(ret){ + PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(vect[0])); + PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(vect[1])); + return ret; + } + + return NULL; +} + +static PyObject* gPyGetScreenVect(PyObject*, PyObject* args) +{ + double x,y; + if (!PyArg_ParseTuple(args,"dd:getScreenVect",&x,&y)) + return NULL; + + MT_Vector3 vect; + MT_Point3 campos, screenpos; + + GLdouble modelMatrix[16]; + GLdouble projMatrix[16]; + GLint viewport[4]; + GLdouble win[3]; + + glGetIntegerv(GL_VIEWPORT, viewport); + glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + + vect[0] = x * viewport[2]; + vect[1] = y * viewport[3]; + + vect[0] += viewport[0]; + vect[1] += viewport[1]; + + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vect[2]); + gluUnProject(vect[0], vect[1], vect[2], modelMatrix, projMatrix, viewport, &win[0], &win[1], &win[2]); + + campos = gp_Rasterizer->GetCameraPosition(); + screenpos = MT_Point3(win[0], win[1], win[2]); + vect = campos-screenpos; + + vect.normalize(); + return PyObjectFrom(vect); +} + +static PyObject* gPyGetScreenRay(PyObject* self, PyObject* args) +{ + KX_Camera* cam; + MT_Vector3 vect; + double x,y,dist; + char *propName = NULL; + + if (!PyArg_ParseTuple(args,"ddd|s:getScreenRay",&x,&y,&dist,&propName)) + return NULL; + + PyObject* argValue = PyTuple_New(2); + if (argValue) { + PyTuple_SET_ITEM(argValue, 0, PyFloat_FromDouble(x)); + PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(y)); + } + + if(!PyVecTo(gPyGetScreenVect(self,argValue), vect)) + { + Py_DECREF(argValue); + PyErr_SetString(PyExc_TypeError, + "Error in getScreenRay. Invalid 2D coordinate. Expected a normalized 2D screen coordinate and an optional property argument"); + return NULL; + } + Py_DECREF(argValue); + + cam = gp_KetsjiScene->GetActiveCamera(); + dist *= -1.0; + + argValue = (propName?PyTuple_New(3):PyTuple_New(2)); + if (argValue) { + PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect)); + PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist)); + if (propName) + PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName)); + + PyObject* ret= cam->PyrayCastTo(argValue,NULL); + Py_DECREF(argValue); + return ret; + } + + return NULL; +} + static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args) { return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetHeight() : 0)); @@ -897,6 +1018,12 @@ static PyObject* gPyDrawLine(PyObject*, PyObject* args) } static struct PyMethodDef rasterizer_methods[] = { + {"getScreenPosition",(PyCFunction) gPyGetScreenPosition, + METH_O, "getScreenPosition doc"}, + {"getScreenVect",(PyCFunction) gPyGetScreenVect, + METH_VARARGS, "getScreenVect doc"}, + {"getScreenRay",(PyCFunction) gPyGetScreenRay, + METH_VARARGS, "getScreenRay doc"}, {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, METH_VARARGS, "getWindowWidth doc"}, {"getWindowHeight",(PyCFunction) gPyGetWindowHeight, diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 21ddf439924..abdd4c3eda1 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -82,7 +82,7 @@ class KX_GameObject: # (SCA_IObject) @ivar isValid: Retuerns fails when the object has been removed from the scene and can no longer be used. @type isValid: bool """ - def endObject(visible): + def endObject(): """ Delete this object, can be used inpace of the EndObject Actuator. The actual removal of the object from the scene is delayed. diff --git a/source/gameengine/PyDoc/Rasterizer.py b/source/gameengine/PyDoc/Rasterizer.py index 6a67cdcc71b..3a2d6408ac9 100644 --- a/source/gameengine/PyDoc/Rasterizer.py +++ b/source/gameengine/PyDoc/Rasterizer.py @@ -44,6 +44,49 @@ Example Uses an L{SCA_MouseSensor}, and two L{KX_ObjectActuator}s to implement M """ +def getScreenPosition(arg): + """ + Gets the position of an object projected on screen space. + + Example: + # For an object in the middle of the screen, coord = [0.5,0.5] + coord = Rasterizer.getScreenPosition(object) + + @param arg: L{KX_GameObject}, object name or list [x, y, z] + @rtype: list [x, y] + @return: the object's position in screen coordinates. + """ +def getScreenVect(x, y): + """ + Gets the vector from the camera position in the screen coordinate direction. + + Example: + # Gets the vector of the camera front direction: + m_vect = Rasterizer.getScreenVect(0.5,0.5) + + @type x: float + @type y: float + @rtype: 3d vector + @return: the vector from a screen coordinate. + """ +def getScreenRay(x, y, dist, property): + """ + Look towards a screen coordinate (x,y) and find first object hit within dist that matches prop. + The ray is similar to KX_GameObject->rayCastTo. + + Example: + # Gets an object with a property "wall" in front of the camera within a distance of 100: + target = Rasterizer.getScreenRay(0.5,0.5,100,"wall") + + @type x: float + @type y: float + @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other + @type dist: float + @param prop: property name that object must have; can be omitted => detect any object + @type prop: string + @rtype: L{KX_GameObject} + @return: the first object hit or None if no object or object does not match prop + """ def getWindowWidth(): """ Gets the width of the window (in pixels) From 327881c838eccb54b579bee0832b91b415022b01 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 23 Apr 2009 00:56:05 +0000 Subject: [PATCH 046/444] [#18574] small bug - warning for sce.link() depreciated displays even when sce.objects.link() is used Remove the warning since the func will sstay in 2.4x --- source/blender/python/api2_2x/Scene.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 6d10205c0e3..cfdfa5d3456 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -844,12 +844,15 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args ) Scene *scene = self->scene; BPy_Object *bpy_obj; Object *object = NULL; + +#if 0 static char warning = 1; if( warning ) { printf("scene.link(ob) deprecated!\n\tuse scene.objects.link(ob) instead\n"); --warning; } +#endif SCENE_DEL_CHECK_PY(self); From 073abf70478965df98d0af61554d0e132dc5ade8 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 23 Apr 2009 02:27:11 +0000 Subject: [PATCH 047/444] BGE Dome update: * Enviroment Map implemented (replacing truncated mode 2). - Now it's possible to pre-bake animated (or static) EnvMaps to use with Cube Map textures. * Enabling 2DFilter in Dome mode - no GL_DEPTH_BUFFER supported though. * Tweaking GameSettings menu (centralizing buttons) --- source/blender/src/buttons_scene.c | 38 +++-- source/gameengine/Ketsji/KX_Dome.cpp | 168 ++++++++++++++++--- source/gameengine/Ketsji/KX_Dome.h | 3 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 4 +- 4 files changed, 168 insertions(+), 45 deletions(-) diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index f026e5f4034..577486135b4 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1772,7 +1772,7 @@ static uiBlock *framing_render_menu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "framing_options", UI_EMBOSS, UI_HELV, curarea->win); /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", -5, -10, 295, 300, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "", -5, -10, 295, 305, NULL, 0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Framing:", xco, yco, 68,19, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); @@ -1787,16 +1787,17 @@ static uiBlock *framing_render_menu(void *arg_unused) uiDefButF(block, COL, 0, "", 0, yco - 58 + 18, 33, 58, &G.scene->framing.col[0], 0, 0, 0, randomcolorindex, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, 0, "R ", xco,yco,243,18, &G.scene->framing.col[0], 0.0, 1.0, randomcolorindex, 0, "Set the red component of the bars"); + uiDefButF(block, NUMSLI, 0, "R ", xco,yco,240,18, &G.scene->framing.col[0], 0.0, 1.0, randomcolorindex, 0, "Set the red component of the bars"); yco -= 20; - uiDefButF(block, NUMSLI, 0, "G ", xco,yco,243,18, &G.scene->framing.col[1], 0.0, 1.0, randomcolorindex, 0, "Set the green component of the bars"); + uiDefButF(block, NUMSLI, 0, "G ", xco,yco,240,18, &G.scene->framing.col[1], 0.0, 1.0, randomcolorindex, 0, "Set the green component of the bars"); yco -= 20; - uiDefButF(block, NUMSLI, 0, "B ", xco,yco,243,18, &G.scene->framing.col[2], 0.0, 1.0, randomcolorindex, 0, "Set the blue component of the bars"); + uiDefButF(block, NUMSLI, 0, "B ", xco,yco,240,18, &G.scene->framing.col[2], 0.0, 1.0, randomcolorindex, 0, "Set the blue component of the bars"); uiBlockEndAlign(block); xco = 0; uiDefBut(block, LABEL, 0, "Fullscreen:", xco, yco-=30, 100, 19, 0, 0.0, 0.0, 0, 0, ""); - uiDefButS(block, TOG, 0, "Fullscreen", xco+70, yco, 68, 19, &G.scene->r.fullscreen, 0.0, 0.0, 0, 0, "Starts player in a new fullscreen display"); + uiDefButS(block, TOG, 0, "Fullscreen", xco+74, yco, 68, 19, &G.scene->r.fullscreen, 0.0, 0.0, 0, 0, "Starts player in a new fullscreen display"); + xco = 3; uiBlockBeginAlign(block); uiDefButS(block, NUM, 0, "X:", xco+40, yco-=27, 100, 19, &G.scene->r.xplay, 10.0, 2000.0, 0, 0, "Displays current X screen/window resolution. Click to change."); uiDefButS(block, NUM, 0, "Y:", xco+140, yco, 100, 19, &G.scene->r.yplay, 10.0, 2000.0, 0, 0, "Displays current Y screen/window resolution. Click to change."); @@ -1816,26 +1817,29 @@ static uiBlock *framing_render_menu(void *arg_unused) * RAS_STEREO_VINTERLACE 7 * RAS_STEREO_DOME 8 */ + + xco = 8; uiBlockBeginAlign(block); uiDefButS(block, ROW, 0, "No Stereo", xco, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 1.0, 0, 0, "Disables stereo"); - uiDefButS(block, ROW, 0, "Pageflip", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 2.0, 0, 0, "Enables hardware pageflip stereo method"); - uiDefButS(block, ROW, 0, "Syncdouble", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 3.0, 0, 0, "Enables syncdoubling stereo method"); - uiDefButS(block, ROW, 0, "Anaglyph", xco-=180, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 5.0, 0, 0, "Enables anaglyph (Red-Blue) stereo method"); - uiDefButS(block, ROW, 0, "Side by Side", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 6.0, 0, 0, "Enables side by side left and right images"); - uiDefButS(block, ROW, 0, "V Interlace", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 7.0, 0, 0, "Enables interlaced vertical strips for autostereo display"); + uiDefButS(block, ROW, 0, "Pageflip", xco+90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 2.0, 0, 0, "Enables hardware pageflip stereo method"); + uiDefButS(block, ROW, 0, "Syncdouble", xco+180, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 3.0, 0, 0, "Enables syncdoubling stereo method"); + uiDefButS(block, ROW, 0, "Anaglyph", xco, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 5.0, 0, 0, "Enables anaglyph (Red-Blue) stereo method"); + uiDefButS(block, ROW, 0, "Side by Side", xco+90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 6.0, 0, 0, "Enables side by side left and right images"); + uiDefButS(block, ROW, 0, "V Interlace", xco+180, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 7.0, 0, 0, "Enables interlaced vertical strips for autostereo display"); uiBlockEndAlign(block); + xco = 8; uiBlockBeginAlign(block); - uiDefButS(block, ROW, 0, "Dome", xco-=180, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 8.0, 0, 0, "Enables dome camera"); - uiDefButS(block, NUM, 0, "Ang:", xco+=90, yco, 88, 19, &G.scene->r.domeangle, 90.0, 250.0, 0, 0, "Angle (Aperture) of the Dome - it only works in mode 1"); - uiDefButS(block, NUM, 0, "Mode:", xco+=90, yco, 88, 19, &G.scene->r.domemode, 1.0, 3.0, 0, 0, "Dome mode - 1 fisheye, 2 truncated, 3 spherical panoramic"); + uiDefButS(block, ROW, 0, "Dome", xco, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 8.0, 0, 0, "Enables dome camera"); + uiDefButS(block, NUM, 0, "Ang:", xco+90, yco, 88, 19, &G.scene->r.domeangle, 90.0, 250.0, 0, 0, "Angle (Aperture) of the Dome - it only works in mode 1"); + uiDefButS(block, NUM, 0, "Mode:", xco+180, yco, 88, 19, &G.scene->r.domemode, 1.0, 3.0, 0, 0, "1 fisheye, 2 environment map, 3 spherical panoramic"); - uiDefButF(block, NUM, 0, "Size:", xco-=180, yco-=21, 88, 19, &G.scene->r.domesize, 0.5, 3.5, 0, 0, "Size adjustments"); - uiDefButS(block, NUM, 0, "Tes:", xco+=90, yco, 88, 19, &G.scene->r.domeres, 1.0, 8.0, 0, 0, "Tesselation level - 1 to 8"); - uiDefButF(block, NUM, 0, "Res:", xco+=90, yco, 88, 19, &G.scene->r.domeresbuf, 0.1, 1.0, 0, 0, "Buffer Resolution - decrease it to increase speed"); + uiDefButF(block, NUM, 0, "Size:", xco, yco-=21, 88, 19, &G.scene->r.domesize, 0.5, 3.5, 0, 0, "Size adjustments"); + uiDefButS(block, NUM, 0, "Tes:", xco+90, yco, 88, 19, &G.scene->r.domeres, 1.0, 8.0, 0, 0, "Tesselation level - 1 to 8"); + uiDefButF(block, NUM, 0, "Res:", xco+180, yco, 88, 19, &G.scene->r.domeresbuf, 0.1, 1.0, 0, 0, "Buffer Resolution - decrease it to increase speed"); - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Warp Data: ", xco-180,yco-=21,268, 19, &G.scene->r.dometext, "Custom Warp Mesh data file"); + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Warp Data: ", xco,yco-=21,268, 19, &G.scene->r.dometext, "Custom Warp Mesh data file"); uiBlockEndAlign(block); uiBlockSetDirection(block, UI_TOP); diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 321370f9f3f..bcff00af76c 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -107,15 +107,9 @@ KX_Dome::KX_Dome ( CreateMeshDome250(); m_numfaces = 5; } break; - case DOME_TRUNCATED: - cubetop.resize(1); - cubebottom.resize(1); - cubeleft.resize(2); - cuberight.resize(2); - - m_angle = 180; - CreateMeshDome180(); - m_numfaces = 4; + case DOME_ENVMAP: + m_angle = 360; + m_numfaces = 6; break; case DOME_PANORAM_SPH: cubeleft.resize(2); @@ -240,7 +234,7 @@ bool KX_Dome::CreateDL(){ dlistId = glGenLists((GLsizei) m_numimages); if (dlistId != 0) { - if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED){ + if(m_mode == DOME_FISHEYE){ glNewList(dlistId, GL_COMPILE); GLDrawTriangles(cubetop, nfacestop); glEndList(); @@ -386,7 +380,7 @@ void KX_Dome::GLDrawWarpQuads(void) } glEnd(); } else{ - printf("Error: Warp Mode unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n"); + printf("Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode); } } @@ -1415,7 +1409,7 @@ Uses 6 cameras for angles up to 360 MT_Scalar c = cos(deg45); MT_Scalar s = sin(deg45); - if ((m_mode == DOME_FISHEYE && m_angle <= 180)|| m_mode == DOME_TRUNCATED){ + if ((m_mode == DOME_FISHEYE && m_angle <= 180)){ m_locRot[0] = MT_Matrix3x3( // 90º - Top c, -s, 0.0, @@ -1437,7 +1431,7 @@ Uses 6 cameras for angles up to 360 0.0, 1.0, 0.0, s, 0.0, c); - } else if ((m_mode == DOME_FISHEYE && m_angle > 180)){ + } else if ((m_mode == DOME_FISHEYE && m_angle > 180) || m_mode == DOME_ENVMAP){ m_locRot[0] = MT_Matrix3x3( // 90º - Top 1.0, 0.0, 0.0, @@ -1464,7 +1458,7 @@ Uses 6 cameras for angles up to 360 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); - m_locRot[5] = MT_Matrix3x3( // 180º - Back - NOT USING + m_locRot[5] = MT_Matrix3x3( // 180º - Back - USED for ENVMAP only -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,-1.0); @@ -1531,8 +1525,8 @@ void KX_Dome::Draw(void) case DOME_FISHEYE: DrawDomeFisheye(); break; - case DOME_TRUNCATED: - DrawDomeFisheye(); + case DOME_ENVMAP: + DrawEnvMap(); break; case DOME_PANORAM_SPH: DrawPanorama(); @@ -1547,6 +1541,138 @@ void KX_Dome::Draw(void) } } +void KX_Dome::DrawEnvMap(void) +{ + int i,j; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = m_viewport.GetRight(); + int can_height = m_viewport.GetTop(); + + float ortho_width, ortho_height; + + if (warp.usemesh) + glOrtho((-1.0), 1.0, (-0.66), 0.66, -20.0, 10.0); //stretch the image to reduce resolution lost + + else { + if (can_width/3 <= can_height/2){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_height = 2.0f / 3; + ortho_width = (float)can_width/can_height * ortho_height; + } + + ortho_width /= m_size; + ortho_height /= m_size; + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + } + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0,0.0,1.0, 0.0,0.0,0.0, 0.0,1.0,0.0); + + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_TEXTURE_2D); + glColor3f(1.0,1.0,1.0); + + float uv_ratio = (float)(m_buffersize-1) / m_imagesize; + double onebythree = 1.0f / 3; + + // domefacesId[0] => (top) + glBindTexture(GL_TEXTURE_2D, domefacesId[0]); + glBegin(GL_QUADS); + glTexCoord2f(uv_ratio,uv_ratio); + glVertex3f( onebythree, 0.0f, 3.0f); + glTexCoord2f(0.0,uv_ratio); + glVertex3f(-onebythree, 0.0f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-onebythree,-2 * onebythree, 3.0f); + glTexCoord2f(uv_ratio,0.0); + glVertex3f(onebythree,-2 * onebythree, 3.0f); + glEnd(); + + // domefacesId[1] => (bottom) + glBindTexture(GL_TEXTURE_2D, domefacesId[1]); + glBegin(GL_QUADS); + glTexCoord2f(uv_ratio,uv_ratio); + glVertex3f(-onebythree, 0.0f, 3.0f); + glTexCoord2f(0.0,uv_ratio); + glVertex3f(-1.0f, 0.0f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-1.0f,-2 * onebythree, 3.0f); + glTexCoord2f(uv_ratio,0.0); + glVertex3f(-onebythree,-2 * onebythree, 3.0f); + glEnd(); + + // domefacesId[2] => -90º (left) + glBindTexture(GL_TEXTURE_2D, domefacesId[2]); + glBegin(GL_QUADS); + glTexCoord2f(uv_ratio,uv_ratio); + glVertex3f(-onebythree, 2 * onebythree, 3.0f); + glTexCoord2f(0.0,uv_ratio); + glVertex3f(-1.0f, 2 * onebythree, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-1.0f, 0.0f, 3.0f); + glTexCoord2f(uv_ratio,0.0); + glVertex3f(-onebythree, 0.0f, 3.0f); + glEnd(); + + // domefacesId[3] => 90º (right) + glBindTexture(GL_TEXTURE_2D, domefacesId[3]); + glBegin(GL_QUADS); + glTexCoord2f(uv_ratio,uv_ratio); + glVertex3f( 1.0f, 2 * onebythree, 3.0f); + glTexCoord2f(0.0,uv_ratio); + glVertex3f( onebythree, 2 * onebythree, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f( onebythree, 0.0f, 3.0f); + glTexCoord2f(uv_ratio,0.0); + glVertex3f(1.0f, 0.0f, 3.0f); + glEnd(); + + // domefacesId[4] => 0º (front) + glBindTexture(GL_TEXTURE_2D, domefacesId[4]); + glBegin(GL_QUADS); + glTexCoord2f(uv_ratio,uv_ratio); + glVertex3f( 1.0f, 0.0f, 3.0f); + glTexCoord2f(0.0,uv_ratio); + glVertex3f( onebythree, 0.0f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f( onebythree,-2 * onebythree, 3.0f); + glTexCoord2f(uv_ratio,0.0); + glVertex3f(1.0f, -2 * onebythree, 3.0f); + glEnd(); + + // domefacesId[5] => 180º (back) + glBindTexture(GL_TEXTURE_2D, domefacesId[5]); + glBegin(GL_QUADS); + glTexCoord2f(uv_ratio,uv_ratio); + glVertex3f( onebythree, 2 * onebythree, 3.0f); + glTexCoord2f(0.0,uv_ratio); + glVertex3f(-onebythree, 2 * onebythree, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-onebythree, 0.0f, 3.0f); + glTexCoord2f(uv_ratio,0.0); + glVertex3f(onebythree, 0.0f, 3.0f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} + void KX_Dome::DrawDomeFisheye(void) { int i,j; @@ -1565,15 +1691,7 @@ void KX_Dome::DrawDomeFisheye(void) if (warp.usemesh) glOrtho((-1.0), 1.0, (-1.0), 1.0, -20.0, 10.0); //stretch the image to reduce resolution lost - else if(m_mode == DOME_TRUNCATED){ - ortho_width = 1.0; - ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; - - ortho_width /= m_size; - ortho_height /= m_size; - - glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0); - } else { + else { if (can_width < can_height){ ortho_width = 1.0; ortho_height = (float)can_height/can_width; diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index de3360cd897..762b09e6429 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -42,7 +42,7 @@ Developed as part of a Research and Development project for SAT - La Soci //Dome modes: limit hardcoded in buttons_scene.c #define DOME_FISHEYE 1 -#define DOME_TRUNCATED 2 +#define DOME_ENVMAP 2 #define DOME_PANORAM_SPH 3 #define DOME_NUM_MODES 4 @@ -131,6 +131,7 @@ public: void GLDrawWarpQuads(void); void Draw(void); void DrawDomeFisheye(void); + void DrawEnvMap(void); void DrawPanorama(void); void DrawDomeWarped(void); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index a9206c1bb8f..ef43d6b176c 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -353,7 +353,6 @@ void KX_KetsjiEngine::RenderDome() m_dome->BindImages(i); } -// m_dome->Dome_PostRender(scene, cam, stereomode); m_canvas->EndFrame();//XXX do we really need that? m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); @@ -381,7 +380,8 @@ void KX_KetsjiEngine::RenderDome() m_dome->Draw(); - //run 2dfilters + // run the 2dfilters and motion blur once for all the scenes + PostRenderFrame(); EndFrame(); } From ad8e98bccd01ef7ae0e0499473a7032b105ebc70 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 23 Apr 2009 06:07:51 +0000 Subject: [PATCH 048/444] == SEQUENCER == This fixes [#18079] Sequencer color correction does not apply on float image if "make float" is not applied and closes [#18582] bug fix #18079 by removing ibuf->rect on image load if ibuf->rect_float is used. (Don't know, why the OpenEXR loader does that, but I fix this on sequencer side for now...) --- source/blender/src/sequence.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index ca4cf4df614..d056f345249 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1761,6 +1761,11 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, if (!se->ibuf) { se->ibuf= IMB_loadiffname( name, IB_rect); + /* we don't need both (speed reasons)! */ + if (se->ibuf->rect_float && se->ibuf->rect) { + imb_freerectImBuf(se->ibuf); + } + copy_to_ibuf_still(seq, se); } @@ -1791,6 +1796,12 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, if(seq->anim) { IMB_anim_set_preseek(seq->anim, seq->anim_preseek); se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs); + /* we don't need both (speed reasons)! */ + if (se->ibuf->rect_float + && se->ibuf->rect) { + imb_freerectImBuf(se->ibuf); + } + } copy_to_ibuf_still(seq, se); } From 960581fcc9b0ce937753bed6e6f41209b2359b14 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 23 Apr 2009 07:40:01 +0000 Subject: [PATCH 049/444] == Sequencer == Fixes: [#18489] Adding (add filter) nested strips causes Blender VSE to segfault on frame render. [#18209] 3 VSE crash bugs with .blends (all left click and move mouse over Metastrip/Blend Mode related) ... and a new segfault I introduced with my last commit. Also: memcache limiter refcounts are tested now in critical places, printing an error message, since doing refcounting right is, well, hard. --- source/blender/src/sequence.c | 96 ++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 24 deletions(-) diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index d056f345249..cd42c3d4085 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1672,6 +1672,41 @@ static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown) } +static void check_limiter_refcount(const char * func, TStripElem *se) +{ + if (se && se->ibuf) { + int refcount = IMB_cache_limiter_get_refcount(se->ibuf); + if (refcount != 1) { + /* can happen on complex pipelines */ + if (refcount > 1 && (G.f & G_DEBUG) == 0) { + return; + } + + fprintf(stderr, + "sequencer: (ibuf) %s: " + "suspicious memcache " + "limiter refcount: %d\n", func, refcount); + } + } +} + +static void check_limiter_refcount_comp(const char * func, TStripElem *se) +{ + if (se && se->ibuf_comp) { + int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp); + if (refcount != 1) { + /* can happen on complex pipelines */ + if (refcount > 1 && (G.f & G_DEBUG) == 0) { + return; + } + fprintf(stderr, + "sequencer: (ibuf comp) %s: " + "suspicious memcache " + "limiter refcount: %d\n", func, refcount); + } + } +} + static TStripElem* do_build_seq_array_recursively( ListBase *seqbasep, int cfra, int chanshown); @@ -1686,18 +1721,23 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, if(seq->type == SEQ_META) { TStripElem * meta_se = 0; + int use_preprocess = FALSE; use_limiter = FALSE; if (!build_proxy_run && se->ibuf == 0) { se->ibuf = seq_proxy_fetch(seq, cfra); if (se->ibuf) { use_limiter = TRUE; + use_preprocess = TRUE; } } if(!se->ibuf && seq->seqbase.first) { meta_se = do_build_seq_array_recursively( &seq->seqbase, seq->start + se->nr, 0); + + check_limiter_refcount("do_build_seq_ibuf: for META", + meta_se); } se->ok = STRIPELEM_OK; @@ -1719,14 +1759,17 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, se->ibuf = i; use_limiter = TRUE; + use_preprocess = TRUE; } + } else if (se->ibuf) { + use_limiter = TRUE; } if (meta_se) { free_metastrip_imbufs( &seq->seqbase, seq->start + se->nr, 0); } - if (use_limiter) { + if (use_preprocess) { input_preprocess(seq, se, cfra); } } else if(seq->type & SEQ_EFFECT) { @@ -1762,7 +1805,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, se->ibuf= IMB_loadiffname( name, IB_rect); /* we don't need both (speed reasons)! */ - if (se->ibuf->rect_float && se->ibuf->rect) { + if (se->ibuf && + se->ibuf->rect_float && se->ibuf->rect) { imb_freerectImBuf(se->ibuf); } @@ -1797,7 +1841,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, IMB_anim_set_preseek(seq->anim, seq->anim_preseek); se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs); /* we don't need both (speed reasons)! */ - if (se->ibuf->rect_float + if (se->ibuf + && se->ibuf->rect_float && se->ibuf->rect) { imb_freerectImBuf(se->ibuf); } @@ -1972,6 +2017,7 @@ static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) if (se->se3 && se->se3->ibuf) { IMB_cache_limiter_unref(se->se3->ibuf); } + check_limiter_refcount("do_effect_seq_recursively", se); } static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra) @@ -1987,6 +2033,7 @@ static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra) do_build_seq_ibuf(seq, se, cfra, FALSE); } } + check_limiter_refcount("do_build_seq_recursively_impl", se); return se; } @@ -2098,6 +2145,8 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) if (se2 && se2->ibuf) IMB_cache_limiter_unref(se2->ibuf); + check_limiter_refcount("do_handle_speed_effect", se); + return se; } @@ -2115,21 +2164,18 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) { + TStripElem* se; if (seq->type == SEQ_SPEED) { - return do_handle_speed_effect(seq, cfra); + se = do_handle_speed_effect(seq, cfra); } else { - return do_build_seq_recursively_impl(seq, cfra); + se = do_build_seq_recursively_impl(seq, cfra); } + + check_limiter_refcount("do_build_seq_recursively", se); + + return se; } -/* Bug: 18209 - * when dragging the mouse over a metastrip, on mouse-up for some unknown - * reason in some cases the metastrips TStripElem->ibuf->rect is NULL, - * This should be fixed but I had a look and couldnt work out why its - * happening so for now workaround with a NULL check - campbell */ - -#define SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND - static TStripElem* do_build_seq_array_recursively( ListBase *seqbasep, int cfra, int chanshown) { @@ -2191,6 +2237,9 @@ static TStripElem* do_build_seq_array_recursively( se->ibuf_comp = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); } break; } @@ -2221,6 +2270,9 @@ static TStripElem* do_build_seq_array_recursively( se->ibuf_comp = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); } break; case 1: @@ -2239,6 +2291,9 @@ static TStripElem* do_build_seq_array_recursively( se->ibuf = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf); + IMB_cache_limiter_ref(se->ibuf); + IMB_cache_limiter_touch(se->ibuf); } if (i == 0) { se->ibuf_comp = se->ibuf; @@ -2297,13 +2352,6 @@ static TStripElem* do_build_seq_array_recursively( IMB_rect_from_float(se2->ibuf); } -#ifdef SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND - if (se2->ibuf->rect==NULL && se2->ibuf->rect_float==NULL) { - printf("ERROR: sequencer se2->ibuf missing buffer\n"); - } else if (se1->ibuf && se1->ibuf->rect==NULL && se1->ibuf->rect_float==NULL) { - printf("ERROR: sequencer se1->ibuf missing buffer\n"); - } else { -#endif /* bad hack, to fix crazy input ordering of those two effects */ @@ -2325,10 +2373,6 @@ static TStripElem* do_build_seq_array_recursively( se2->ibuf_comp); } -#ifdef SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND - } -#endif - IMB_cache_limiter_insert(se2->ibuf_comp); IMB_cache_limiter_ref(se2->ibuf_comp); IMB_cache_limiter_touch(se2->ibuf_comp); @@ -2383,6 +2427,8 @@ static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) return 0; } + check_limiter_refcount_comp("give_ibuf_seq_impl", se); + return se->ibuf_comp; } @@ -2400,6 +2446,8 @@ ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, return 0; } + check_limiter_refcount("give_ibuf_seq_direct", se); + if (se->ibuf) { IMB_cache_limiter_unref(se->ibuf); } From 09c341c3bdc28dd4f62b31158ab891a5bcc6004d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 23 Apr 2009 09:59:19 +0000 Subject: [PATCH 050/444] Make: removing hidden directories from .app failed. --- source/darwin/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/darwin/Makefile b/source/darwin/Makefile index f7b513fc214..e2c6f754831 100644 --- a/source/darwin/Makefile +++ b/source/darwin/Makefile @@ -50,7 +50,7 @@ ifeq ($(APPLICATION), blender) @cp -R $(NANBLENDERHOME)/bin/.blender $(DIR)/bin/$(APPLICATION).app/Contents/MacOS @cp -R $(NANBLENDERHOME)/release/scripts $(DIR)/bin/$(APPLICATION).app/Contents/MacOS/.blender/ endif - @echo "---> removing CVS directories and Mac hidden files from distribution" + @echo "---> removing SVN directories and Mac hidden files from distribution" @find $(DIR)/bin/$(APPLICATION).app -name CVS -prune -exec rm -rf {} \; @find $(DIR)/bin/$(APPLICATION).app -name .DS_Store -exec rm -f {} \; - @find $(DIR)/bin/$(APPLICATION).app -name .svn -exec rm -rf {} \; + @find $(DIR)/bin/$(APPLICATION).app -name .svn -prune -exec rm -rf {} \; From 0d347e12ea7bb863edbbc3cf40ac6b682c32e638 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 23 Apr 2009 11:59:13 +0000 Subject: [PATCH 051/444] [#11172] md2 export bug(s) export with object transformations applied. --- release/scripts/md2_export.py | 103 +++++++++++++++++----------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/release/scripts/md2_export.py b/release/scripts/md2_export.py index 588336ed447..cf5752597da 100644 --- a/release/scripts/md2_export.py +++ b/release/scripts/md2_export.py @@ -612,29 +612,9 @@ class md2_obj: ###################################################### # Validation ###################################################### + def validation(object): global user_frame_list - - #move the object to the origin if it's not already there - if object.getLocation('worldspace')!=(0.0, 0.0, 0.0): - print "Model not centered at origin" - result=Blender.Draw.PupMenu("Model not centered at origin%t|Center (will not work with animations!)|Do not center") - if result==1: - object.setLocation(0.0,0.0,0.0) - - #resize the object in case it is not the right size - if object.getSize('worldspace')!=(1.0,1.0,1.0): - print "Object is scaled-You should scale the mesh verts, not the object" - result=Blender.Draw.PupMenu("Object is scaled-You should scale the mesh verts, not the object%t|Fix scale (will not work with animations!)|Do not scale") - if result==1: - object.setSize(1.0,1.0,1.0) - - if object.getEuler('worldspace')!=Blender.Mathutils.Euler(0.0,0.0,0.0): - print "object.rot: ", object.getEuler('worldspace') - print "Object is rotated-You should rotate the mesh verts, not the object" - result=Blender.Draw.PupMenu("Object is rotated-You should rotate the mesh verts, not the object%t|Fix rotation (will not work with animations!)|Do not rotate") - if result==1: - object.setEuler([0.0,0.0,0.0]) #get access to the mesh data mesh=object.getData(False, True) #get the object (not just name) and the Mesh, not NMesh @@ -696,7 +676,8 @@ def validation(object): result=Blender.Draw.PupMenu("Model has more than 1 texture map assigned%t|Quit") #return False if mesh_image: - size=mesh_image.getSize() + try: size=mesh_image.getSize() + except: size= 256,256 # No image data #is this really what the user wants if (size[0]!=256 or size[1]!=256): print "Texture map size is non-standard (not 256x256), it is: ",size[0],"x",size[1] @@ -753,6 +734,8 @@ def fill_md2(md2, object): #create the vertex list from the first frame Blender.Set("curframe", 1) + has_uvs = mesh.faceUV + #header information md2.ident=844121161 md2.version=8 @@ -761,9 +744,11 @@ def fill_md2(md2, object): #get the skin information #use the first faces' image for the texture information - if mesh.faceUV: + if has_uvs: mesh_image=mesh.faces[0].image - size=mesh_image.getSize() + try: size=mesh_image.getSize() + except: size= 256,256 + md2.skin_width=size[0] md2.skin_height=size[1] md2.num_skins=1 @@ -777,12 +762,14 @@ def fill_md2(md2, object): #put texture information in the md2 structure #build UV coord dictionary (prevents double entries-saves space) + if not has_uvs: + t=(0,0) + for face in mesh.faces: for i in xrange(0,3): - if mesh.faceUV: + if has_uvs: t=(face.uv[i]) - else: - t=(0,0) + tex_key=(t[0],t[1]) if not tex_list.has_key(tex_key): tex_list[tex_key]=tex_count @@ -798,16 +785,25 @@ def fill_md2(md2, object): #put faces in the md2 structure #for each face in the model + + if not has_uvs: + uv_coords=[(0,0)]*3 + for this_face in xrange(0, md2.num_faces): md2.faces.append(md2_face()) + mf = mesh.faces[this_face] + mf_v = mf.v + if has_uvs: + uv_coords = mf.uv + for i in xrange(0,3): #blender uses indexed vertexes so this works very well - md2.faces[this_face].vertex_index[i]=mesh.faces[this_face].verts[i].index + md2.faces[this_face].vertex_index[i] = mf_v[i].index #lookup texture index in dictionary - if mesh.faceUV: - uv_coord=(mesh.faces[this_face].uv[i]) - else: - uv_coord=(0,0) + if has_uvs: + uv_coord = uv_coords[i] + # otherwise we set it before + tex_key=(uv_coord[0],uv_coord[1]) tex_index=tex_list[tex_key] md2.faces[this_face].texture_index[i]=tex_index @@ -837,13 +833,18 @@ def fill_md2(md2, object): for frame_counter in xrange(0,md2.num_frames): progress+=progressIncrement - Blender.Window.DrawProgressBar(progress, "Calculating Frame: "+str(frame_counter)) + Blender.Window.DrawProgressBar(progress, "Calculating Frame: %d of %d" % (frame_counter, md2.num_frames)) #add a frame md2.frames.append(md2_frame()) #update the mesh objects vertex positions for the animation Blender.Set("curframe", frame_counter) #set blender to the correct frame - mesh.getFromObject(object.name) #update the mesh to make verts current + + + + + mesh.getFromObject(object) #update the mesh to make verts current + mesh.transform(object.matrixWorld) #each frame has a scale and transform value that gets the vertex value between 0-255 #since the scale and transform are the same for the all the verts in the frame, we only need @@ -862,13 +863,14 @@ def fill_md2(md2, object): frame_max_z=-100000.0 for face in mesh.faces: - for vert in face.verts: - if frame_min_x>vert.co[1]: frame_min_x=vert.co[1] - if frame_max_xvert.co[0]: frame_min_y=vert.co[0] - if frame_max_yvert.co[2]: frame_min_z=vert.co[2] - if frame_max_zco[1]: frame_min_x=co[1] + if frame_max_xco[0]: frame_min_y=co[0] + if frame_max_yco[2]: frame_min_z=co[2] + if frame_max_z maxdot): maxdot = dot; maxdotindex = j; From 70f1b45430b09e3d522b3633645e180d725de82c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 23 Apr 2009 13:30:34 +0000 Subject: [PATCH 052/444] Fix for part of bug #18496: issue with light state switching when using Dome. --- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 2 +- .../GamePlayer/common/GPC_RenderTools.cpp | 2 +- source/gameengine/Ketsji/KX_Dome.cpp | 35 +++++++------------ source/gameengine/Ketsji/KX_Dome.h | 3 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 6 ++-- 5 files changed, 20 insertions(+), 28 deletions(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 9dbda3f195b..e393b6d9af4 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -68,8 +68,8 @@ void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty) { m_clientobject = NULL; m_lastlightlayer = -1; - m_lastlighting = false; m_lastauxinfo = NULL; + m_lastlighting = true; /* force disable in DisableOpenGLLights() */ DisableOpenGLLights(); } diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index eafdb8a96bb..1a0d985a864 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -76,8 +76,8 @@ void GPC_RenderTools::BeginFrame(RAS_IRasterizer* rasty) { m_clientobject = NULL; m_lastlightlayer = -1; - m_lastlighting = false; m_lastauxinfo = NULL; + m_lastlighting = true; /* force disable in DisableOpenGLLights() */ DisableOpenGLLights(); } diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index bcff00af76c..077e2ce33b7 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -52,18 +52,18 @@ KX_Dome::KX_Dome ( struct Text* warptext ): - m_canvas(canvas), - m_rasterizer(rasterizer), - m_rendertools(rendertools), - m_engine(engine), + dlistSupported(false), + canvaswidth(-1), canvasheight(-1), m_drawingmode(engine->GetDrawType()), m_size(size), m_resolution(res), m_mode(mode), m_angle(angle), m_resbuffer(resbuf), - canvaswidth(-1), canvasheight(-1), - dlistSupported(false) + m_canvas(canvas), + m_rasterizer(rasterizer), + m_rendertools(rendertools), + m_engine(engine) { warp.usemesh = false; @@ -206,7 +206,7 @@ void KX_Dome::CalculateImageSize(void) canvasheight = m_canvas->GetHeight(); m_buffersize = (canvaswidth > canvasheight?canvasheight:canvaswidth); - m_buffersize *= m_resbuffer; //reduce buffer size for better performance + m_buffersize = (int)(m_buffersize*m_resbuffer); //reduce buffer size for better performance int i = 0; while ((1 << i) <= m_buffersize) @@ -230,8 +230,6 @@ void KX_Dome::CalculateImageSize(void) } bool KX_Dome::CreateDL(){ - int i,j; - dlistId = glGenLists((GLsizei) m_numimages); if (dlistId != 0) { if(m_mode == DOME_FISHEYE){ @@ -409,7 +407,7 @@ y varies from -1 to 1 u and v vary from 0 to 1 i ranges from 0 to 1, if negative don't draw that mesh node */ - int i,j,k; + int i; int nodeX=0, nodeY=0; vector columns, lines; @@ -431,7 +429,7 @@ i ranges from 0 to 1, if negative don't draw that mesh node warp.n_width = atoi(columns[0]); warp.n_height = atoi(columns[1]); - if (lines.size() < 2 + (warp.n_width * warp.n_height)){ + if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)){ printf("Error: Warp Mesh File with insufficient data!\n"); return false; }else{ @@ -1543,8 +1541,6 @@ void KX_Dome::Draw(void) void KX_Dome::DrawEnvMap(void) { - int i,j; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -1675,7 +1671,7 @@ void KX_Dome::DrawEnvMap(void) void KX_Dome::DrawDomeFisheye(void) { - int i,j; + int i; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); @@ -1759,7 +1755,7 @@ void KX_Dome::DrawDomeFisheye(void) void KX_Dome::DrawPanorama(void) { - int i,j; + int i; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -1846,8 +1842,6 @@ void KX_Dome::DrawPanorama(void) void KX_Dome::DrawDomeWarped(void) { - int i,j; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -1880,10 +1874,6 @@ void KX_Dome::DrawDomeWarped(void) glEnable(GL_TEXTURE_2D); glColor3f(1.0,1.0,1.0); - - float uv_width = (float)(warp.bufferwidth-1) / warp.imagewidth; - float uv_height = (float)(warp.bufferheight-1) / warp.imageheight; - if (dlistSupported){ glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); glCallList(dlistId + m_numfaces); @@ -1934,4 +1924,5 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) // restore the original orientation cam->NodeSetLocalOrientation(camori); cam->NodeUpdateGS(0.f); -} \ No newline at end of file +} + diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 762b09e6429..84f0c5c72ed 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -181,4 +181,5 @@ protected: KX_KetsjiEngine* m_engine; }; -#endif \ No newline at end of file +#endif + diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index ef43d6b176c..63db54a296e 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -145,8 +145,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system) m_stereo(false), m_curreye(0), - m_usedome(false), - m_logger(NULL), // Set up timing info display variables @@ -164,7 +162,9 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system) m_overrideFrameColor(false), m_overrideFrameColorR(0.0), m_overrideFrameColorG(0.0), - m_overrideFrameColorB(0.0) + m_overrideFrameColorB(0.0), + + m_usedome(false) { // Initialize the time logger m_logger = new KX_TimeCategoryLogger (25); From 67b3e1a07b61f4bfccdd120e04942367ae3c8088 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 23 Apr 2009 20:30:01 +0000 Subject: [PATCH 053/444] BGE bug #17863: Shaky game camera. --- .../Physics/Bullet/CcdPhysicsController.cpp | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 0b9da8f46d3..b944ae085ba 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -572,10 +572,22 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time) btSoftBody* sb = GetSoftBody(); if (sb) { - btVector3 aabbMin,aabbMax; - sb->getAabb(aabbMin,aabbMax); - btVector3 worldPos = (aabbMax+aabbMin)*0.5f; - m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); + if (sb->m_pose.m_bframe) + { + btVector3 worldPos = sb->m_pose.m_com; + btQuaternion worldquat; + btMatrix3x3 trs = sb->m_pose.m_rot*sb->m_pose.m_scl; + trs.getRotation(worldquat); + m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); + m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); + } + else + { + btVector3 aabbMin,aabbMax; + sb->getAabb(aabbMin,aabbMax); + btVector3 worldPos = (aabbMax+aabbMin)*0.5f; + m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); + } m_MotionState->calculateWorldTransformations(); return true; } From 0feaedfa9af37be8ae9cd1bb29a242921bf51ae0 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 23 Apr 2009 21:19:42 +0000 Subject: [PATCH 054/444] BGE bug #17950: crash when GE softbody is parented to a rigid body/soft body/dynamic object. --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b7f74d57ca4..84b7407aacf 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1528,6 +1528,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_dynamic_parent = parentgameobject; //cannot be dynamic: objprop.m_dyna = false; + objprop.m_softbody = false; shapeprops->m_mass = 0.f; } From b4abca0daab7a82a64e40eb83fbbb3a26ece9ee7 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Thu, 23 Apr 2009 23:44:43 +0000 Subject: [PATCH 055/444] patch for paths_svg2obj.py by author J.M.Soler: http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg_en.htm This patch adds support for Patterns. --- release/scripts/bpymodules/paths_svg2obj.py | 41 ++++++++++++++++----- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/release/scripts/bpymodules/paths_svg2obj.py b/release/scripts/bpymodules/paths_svg2obj.py index d51fe74190d..6bab6dcbfd8 100644 --- a/release/scripts/bpymodules/paths_svg2obj.py +++ b/release/scripts/bpymodules/paths_svg2obj.py @@ -1,7 +1,7 @@ # -*- coding: latin-1 -*- """ -SVG 2 OBJ translater, 0.5.9n -Copyright (c) jm soler juillet/novembre 2004-february 2009, +SVG 2 OBJ translater, 0.5.9o +Copyright (c) jm soler juillet/novembre 2004-april 2009, # --------------------------------------------------------------- released under GNU Licence for the Blender 2.42 Python Scripts Bundle. @@ -255,7 +255,7 @@ Changelog: - removed all debug statements - correction of a zero division error in the calc_arc function. - 0.5.9f: - 2007/15/7 + 0.5.9f: - 2007/15/7 - Correction de plusieurs bugs sur l'attributions des couleurs et le nommage des courbes @@ -266,6 +266,8 @@ Changelog: 0.5.9k : - 14/01/2009 0.5.9l : - 31/01/2009 0.5.9n : - 01/02/2009 + 0.5.9o : - 04/04/2009, remove pattern if it made with path. + ================================================================================== ==================================================================================""" @@ -280,6 +282,7 @@ LAST_ID='' LAST_COLOR=[0.0,0.0,0.0,0.0] SEPARATE_CURVES=0 USE_COLORS=0 +PATTERN=0 SVGCOLORNAMELIST={ 'aliceblue':[240, 248, 255] ,'antiquewhite':[250, 235, 215] ,'aqua':[ 0, 255, 255], 'aquamarine':[127, 255, 212] @@ -787,6 +790,7 @@ def polygon(prp): D.append('Z') return D + #-------------------- # 0.5.8, to remove exec #-------------------- @@ -1462,13 +1466,13 @@ def collect_ATTRIBUTS(data): # -------------------------------------------- def build_HIERARCHY(t): global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global LAST_ID + global LAST_ID, PATTERN TRANSFORM=0 t=t.replace('\t',' ') while t.find(' ')!=-1: t=t.replace(' ',' ') n0=0 t0=t1=0 - baliste=[] + #baliste=[] balisetype=['?','?','/','/','!','!'] BALISES=['D', #DECL_TEXTE', 'D', #DECL_TEXTE', @@ -1490,26 +1494,37 @@ def build_HIERARCHY(t): if t0>-1 and t1>-1: if t[t0+1] in balisetype: b=balisetype.index(t[t0+1]) + if t[t0+2]=='-': b=balisetype.index(t[t0+1])+1 + balise=BALISES[b] + if b==2: parent=STACK.pop(-1) if parent!=None and TRANSFORM>0: TRANSFORM-=1 + elif t[t1-1] in balisetype: balise=BALISES[balisetype.index(t[t1-1])+1] + else: t2=t.find(' ',t0) if t2>t1: t2=t1 ouvrante=1 NOM=t[t0+1:t2] + + if '-1: balise=BALISES[-1] + if NOM=='pattern' and not PATTERN: + t1=t.find('',t0)+len('') + balise=BALISES[-3] else: balise=BALISES[-2] if balise=='E' or balise=='O': + proprietes=collect_ATTRIBUTS(t[t0:t1+ouvrante]) if 'id' in proprietes: @@ -1532,6 +1547,11 @@ def build_HIERARCHY(t): # 0.5.8, to remove exec #-------------------- D=OTHERSSHAPES[proprietes['TYPE']](proprietes) + + #elif proprietes['TYPE'] in ['pattern']: + # print 'pattern' + # D='' + CP=[0.0,0.0] if len(D)>0: cursor=0 @@ -1567,7 +1587,7 @@ def build_HIERARCHY(t): def scan_FILE(nom): global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global SEPARATE_CURVES, USE_COLORS + global SEPARATE_CURVES, USE_COLORS, PATTERN dir,name=split(nom) name=name.split('.') @@ -1583,13 +1603,14 @@ def scan_FILE(nom): togAS = Blender.Draw.Create(0) togSP = Blender.Draw.Create(0) togCOL = Blender.Draw.Create(0) + Pattern= Blender.Draw.Create(0) block=[\ ("Clamp Width 1", togW, "Rescale the import with a Width of one unit"),\ ("Clamp Height 1", togH, "Rescale the import with a Heightof one unit"),\ ("No Rescaling", togAS, "No rescaling, the result can be very large"),\ ("Separate Curves", togSP, "Create an object for each curve, Slower. May manage colors"),\ - ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option")] - + ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option"),\ + ("Import Patterns", Pattern, "import pattern content if it is made with paths.")] retval = Blender.Draw.PupBlock("Import Options", block) if togW.val: scale_=1 elif togH.val: scale_=2 @@ -1598,6 +1619,8 @@ def scan_FILE(nom): if togSP.val: SEPARATE_CURVES=1 if togCOL.val and SEPARATE_CURVES : USE_COLORS=1 + + if Pattern.val : PATTERN =1 t1=Blender.sys.time() # 0.4.1 : to avoid to use sax and the xml @@ -1625,4 +1648,4 @@ def functionSELECT(nom): if __name__=='__main__': - Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg') + Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg') \ No newline at end of file From a5f4d7cb53682a944eee0f10bbae77f3b0465417 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 24 Apr 2009 07:45:17 +0000 Subject: [PATCH 056/444] BGE PyAPI epydoc errors fixed --- source/gameengine/PyDoc/GameKeys.py | 4 ++-- .../gameengine/PyDoc/KX_ConstraintActuator.py | 18 +++++++++--------- source/gameengine/PyDoc/KX_GameObject.py | 2 +- source/gameengine/PyDoc/KX_SoundActuator.py | 16 ++++++++-------- source/gameengine/PyDoc/KX_StateActuator.py | 16 ++++++++-------- source/gameengine/PyDoc/Rasterizer.py | 4 ++-- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/source/gameengine/PyDoc/GameKeys.py b/source/gameengine/PyDoc/GameKeys.py index 310f2b0d506..14cd7e4f25c 100644 --- a/source/gameengine/PyDoc/GameKeys.py +++ b/source/gameengine/PyDoc/GameKeys.py @@ -174,8 +174,8 @@ def EventToCharacter(event, shift): @type event: int @param event: key event from GameKeys or the keyboard sensor. - @type event: bool - @param event: set to true if shift is held. + @type shift: bool + @param shift: set to true if shift is held. @rtype: string """ diff --git a/source/gameengine/PyDoc/KX_ConstraintActuator.py b/source/gameengine/PyDoc/KX_ConstraintActuator.py index a30b859548b..89ca4d80c73 100644 --- a/source/gameengine/PyDoc/KX_ConstraintActuator.py +++ b/source/gameengine/PyDoc/KX_ConstraintActuator.py @@ -19,15 +19,15 @@ class KX_ConstraintActuator(SCA_IActuator): @type direction: 3-tuple of float: [x,y,z] @ivar option: Binary combination of the following values: - Applicable to Distance constraint: - KX_ACT_CONSTRAINT_NORMAL ( 64) : Activate alignment to surface - KX_ACT_CONSTRAINT_DISTANCE ( 512) : Activate distance control - KX_ACT_CONSTRAINT_LOCAL (1024) : direction of the ray is along the local axis - Applicable to Force field constraint: - KX_ACT_CONSTRAINT_DOROTFH (2048) : Force field act on rotation as well - Applicable to both: - KX_ACT_CONSTRAINT_MATERIAL ( 128) : Detect material rather than property - KX_ACT_CONSTRAINT_PERMANENT ( 256) : No deactivation if ray does not hit target + Applicable to Distance constraint: + - KX_ACT_CONSTRAINT_NORMAL ( 64) : Activate alignment to surface + - KX_ACT_CONSTRAINT_DISTANCE ( 512) : Activate distance control + - KX_ACT_CONSTRAINT_LOCAL (1024) : direction of the ray is along the local axis + Applicable to Force field constraint: + - KX_ACT_CONSTRAINT_DOROTFH (2048) : Force field act on rotation as well + Applicable to both: + - KX_ACT_CONSTRAINT_MATERIAL ( 128) : Detect material rather than property + - KX_ACT_CONSTRAINT_PERMANENT ( 256) : No deactivation if ray does not hit target @type option: integer @ivar time: activation time of the actuator. The actuator disables itself after this many frame. diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index abdd4c3eda1..db0aebfc761 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -110,7 +110,7 @@ class KX_GameObject: # (SCA_IObject) """ Sets the game object's occlusion capability. - @type visible: boolean + @type occlusion: boolean @type recursive: boolean @param recursive: optional argument to set all childrens occlusion flag too. """ diff --git a/source/gameengine/PyDoc/KX_SoundActuator.py b/source/gameengine/PyDoc/KX_SoundActuator.py index 37ae3c6640d..0aec57c851c 100644 --- a/source/gameengine/PyDoc/KX_SoundActuator.py +++ b/source/gameengine/PyDoc/KX_SoundActuator.py @@ -36,20 +36,20 @@ class KX_SoundActuator(SCA_IActuator): @type orientation: 3x3 matrix [[float]] @ivar type: Sets the operation mode of the actuator. You can use one of the following constant: - KX_SOUNDACT_PLAYSTOP (1) - KX_SOUNDACT_PLAYEND (2) - KX_SOUNDACT_LOOPSTOP (3) - KX_SOUNDACT_LOOPEND (4) - KX_SOUNDACT_LOOPBIDIRECTIONAL (5) - KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP (6) + - KX_SOUNDACT_PLAYSTOP (1) + - KX_SOUNDACT_PLAYEND (2) + - KX_SOUNDACT_LOOPSTOP (3) + - KX_SOUNDACT_LOOPEND (4) + - KX_SOUNDACT_LOOPBIDIRECTIONAL (5) + - KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP (6) @type type: integer - @group Play Methods: startSound, pauseSound, stopSound. + @group Play Methods: startSound, pauseSound, stopSound """ def setFilename(filename): """ DEPRECATED: Use the filename property instead. - Sets the filename of the sound this actuator plays. + Sets the filename of the sound this actuator plays. @type filename: string """ diff --git a/source/gameengine/PyDoc/KX_StateActuator.py b/source/gameengine/PyDoc/KX_StateActuator.py index fe3669d3809..d9785ad13fa 100644 --- a/source/gameengine/PyDoc/KX_StateActuator.py +++ b/source/gameengine/PyDoc/KX_StateActuator.py @@ -9,17 +9,17 @@ class KX_StateActuator(SCA_IActuator): Property: @ivar operation: type of bit operation to be applied on object state mask. - You can use one of the following constant: - KX_STATE_OP_CPY (0) : Copy state mask - KX_STATE_OP_SET (1) : Add bits to state mask - KX_STATE_OP_CLR (2) : Substract bits to state mask - KX_STATE_OP_NEG (3) : Invert bits to state mask + You can use one of the following constant: + - KX_STATE_OP_CPY (0) : Copy state mask + - KX_STATE_OP_SET (1) : Add bits to state mask + - KX_STATE_OP_CLR (2) : Substract bits to state mask + - KX_STATE_OP_NEG (3) : Invert bits to state mask @type operation: integer @ivar mask: value that defines the bits that will be modified by the operation. - The bits that are 1 in the mask will be updated in the object state, - the bits that are 0 are will be left unmodified expect for the Copy operation - which copies the mask to the object state + The bits that are 1 in the mask will be updated in the object state, + the bits that are 0 are will be left unmodified expect for the Copy operation + which copies the mask to the object state @type mask: integer """ def setOperation(op): diff --git a/source/gameengine/PyDoc/Rasterizer.py b/source/gameengine/PyDoc/Rasterizer.py index 3a2d6408ac9..fdd53c27898 100644 --- a/source/gameengine/PyDoc/Rasterizer.py +++ b/source/gameengine/PyDoc/Rasterizer.py @@ -82,8 +82,8 @@ def getScreenRay(x, y, dist, property): @type y: float @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other @type dist: float - @param prop: property name that object must have; can be omitted => detect any object - @type prop: string + @param property: property name that object must have; can be omitted => detect any object + @type property: string @rtype: L{KX_GameObject} @return: the first object hit or None if no object or object does not match prop """ From 252928ab36b03e73b35ea79e36a03e8f982274f6 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 24 Apr 2009 19:49:15 +0000 Subject: [PATCH 057/444] BGE: removed support for time dependent modifiers, they don't make sense in the GE. Disable modifiers when Bullet soft body is used: bullet needs the original vertex array. --- source/blender/blenkernel/intern/DerivedMesh.c | 2 ++ source/gameengine/Converter/BL_ModifierDeformer.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index eb2975be0c0..6cf934fa165 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2158,6 +2158,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], if((md->mode & required_mode) != required_mode) continue; if(mti->isDisabled && mti->isDisabled(md)) continue; + if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; if(mti->type == eModifierTypeType_OnlyDeform) { if(!deformedVerts) @@ -2228,6 +2229,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], } if(mti->isDisabled && mti->isDisabled(md)) continue; if(needMapping && !modifier_supportsMapping(md)) continue; + if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; /* add an orco layer if needed by this modifier */ if(dm && mti->requiredDataMask) { diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index 09dbe966d0b..c3131559a6f 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -97,10 +97,16 @@ bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob) { if (!ob->modifiers.first) return false; + // soft body cannot use mesh modifiers + if ((ob->gameflag & OB_SOFT_BODY) != 0) + return false; ModifierData* md; for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) { - if (md->mode & eModifierMode_Realtime) - return true; + if (modifier_dependsOnTime(md)) + continue; + if (!(md->mode & eModifierMode_Realtime)) + continue; + return true; } return false; } From 6b48e25ba4c758d12620a4fe342101e079714ec3 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Fri, 24 Apr 2009 20:17:42 +0000 Subject: [PATCH 058/444] Change scon's ordering of static libraries to resolve problem on Linux 64-bit builds. --- tools/Blender.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/Blender.py b/tools/Blender.py index 9c978fccf49..7f9df068754 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -126,8 +126,6 @@ def setup_staticlibs(lenv): libincs += Split(lenv['BF_SDL_LIBPATH']) if lenv['WITH_BF_FFMPEG']: libincs += Split(lenv['BF_FFMPEG_LIBPATH']) - if lenv['WITH_BF_STATICCXX']: - statlibs += Split(lenv['BF_CXX_LIB_STATIC']) if lenv['WITH_BF_OPENEXR']: libincs += Split(lenv['BF_OPENEXR_LIBPATH']) if lenv['WITH_BF_STATICOPENEXR']: @@ -141,6 +139,8 @@ def setup_staticlibs(lenv): statlibs += Split(lenv['BF_OPENAL_LIB_STATIC']) if lenv['WITH_BF_STATICOPENGL']: statlibs += Split(lenv['BF_OPENGL_LIB_STATIC']) + if lenv['WITH_BF_STATICCXX']: + statlibs += Split(lenv['BF_CXX_LIB_STATIC']) if lenv['WITH_BF_PYTHON'] and lenv['WITH_BF_STATICPYTHON']: statlibs += Split(lenv['BF_PYTHON_LIB_STATIC']) From 0c482f76071ff0f48f1b469f9b5173ee7b067add Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 24 Apr 2009 20:27:04 +0000 Subject: [PATCH 059/444] BGE API - small changes - print CListValue errors only once. - bge_api_validate_py.txt now validates modules as well as types. - added missing functions and consts for epydoc modules. some of these in GameLogic.py still need sorting. --- source/gameengine/Expressions/ListValue.cpp | 16 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 4 +- source/gameengine/PyDoc/GameKeys.py | 235 +++++++++--------- source/gameengine/PyDoc/GameLogic.py | 130 +++++++++- source/gameengine/PyDoc/Rasterizer.py | 26 ++ .../gameengine/PyDoc/bge_api_validate_py.txt | 39 ++- 6 files changed, 316 insertions(+), 134 deletions(-) diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index c78963142d1..3596128f12d 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -530,7 +530,7 @@ PyObject* CListValue::Pycount(PyObject* value) { int numfound = 0; - CValue* checkobj = ConvertPythonToValue(value, "cList.count(val): CValueList, "); + CValue* checkobj = ConvertPythonToValue(value, ""); /* error ignored */ if (checkobj==NULL) { /* in this case just return that there are no items in the list */ PyErr_Clear(); @@ -578,18 +578,24 @@ PyObject* CListValue::Pyfrom_id(PyObject* value) CValue* CListValue::Calc(VALUE_OPERATOR op,CValue *val) { //assert(false); // todo: implement me! - fprintf(stderr, "CValueList::Calc not yet implimented\n"); + static int error_printed = 0; + if (error_printed==0) { + fprintf(stderr, "CValueList::Calc not yet implimented\n"); + error_printed = 1; + } return NULL; } - - CValue* CListValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue* val) { //assert(false); // todo: implement me! - fprintf(stderr, "CValueList::CalcFinal not yet implimented\n"); + static int error_printed = 0; + if (error_printed==0) { + fprintf(stderr, "CValueList::CalcFinal not yet implimented\n"); + error_printed = 1; + } return NULL; } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index bf3b64f1ecf..f82110c2bd2 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -852,7 +852,7 @@ static PyObject* gPyEnableMotionBlur(PyObject*, PyObject* args) Py_RETURN_NONE; } -static PyObject* gPyDisableMotionBlur(PyObject*, PyObject* args) +static PyObject* gPyDisableMotionBlur(PyObject*) { if (!gp_Rasterizer) { PyErr_SetString(PyExc_RuntimeError, "Rasterizer.disableMotionBlur(), Rasterizer not available"); @@ -1043,7 +1043,7 @@ static struct PyMethodDef rasterizer_methods[] = { {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"}, - {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_VARARGS,"disable motion blur"}, + {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_NOARGS,"disable motion blur"}, {"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"}, diff --git a/source/gameengine/PyDoc/GameKeys.py b/source/gameengine/PyDoc/GameKeys.py index 14cd7e4f25c..e798f6c901b 100644 --- a/source/gameengine/PyDoc/GameKeys.py +++ b/source/gameengine/PyDoc/GameKeys.py @@ -5,126 +5,6 @@ Documentation for the GameKeys module. This module holds key constants for the SCA_KeyboardSensor. -Alphabet keys -------------- - - AKEY - - BKEY - - CKEY - - DKEY - - EKEY - - FKEY - - GKEY - - HKEY - - IKEY - - JKEY - - KKEY - - LKEY - - MKEY - - NKEY - - OKEY - - PKEY - - QKEY - - RKEY - - SKEY - - TKEY - - UKEY - - VKEY - - WKEY - - XKEY - - YKEY - - ZKEY - -Number keys ------------ - - ZEROKEY - - ONEKEY - - TWOKEY - - THREEKEY - - FOURKEY - - FIVEKEY - - SIXKEY - - SEVENKEY - - EIGHTKEY - - NINEKEY - -Shift Modifiers ---------------- - - CAPSLOCKKEY - - - LEFTCTRLKEY - - LEFTALTKEY - - RIGHTALTKEY - - RIGHTCTRLKEY - - RIGHTSHIFTKEY - - LEFTSHIFTKEY - -Arrow Keys ----------- - - LEFTARROWKEY - - DOWNARROWKEY - - RIGHTARROWKEY - - UPARROWKEY - -Numberpad Keys --------------- - - PAD0 - - PAD1 - - PAD2 - - PAD3 - - PAD4 - - PAD5 - - PAD6 - - PAD7 - - PAD8 - - PAD9 - - PADPERIOD - - PADSLASHKEY - - PADASTERKEY - - PADMINUS - - PADENTER - - PADPLUSKEY - -Function Keys -------------- - - F1KEY - - F2KEY - - F3KEY - - F4KEY - - F5KEY - - F6KEY - - F7KEY - - F8KEY - - F9KEY - - F10KEY - - F11KEY - - F12KEY - -Other Keys ----------- - - ACCENTGRAVEKEY - - BACKSLASHKEY - - BACKSPACEKEY - - COMMAKEY - - DELKEY - - ENDKEY - - EQUALKEY - - ESCKEY - - HOMEKEY - - INSERTKEY - - LEFTBRACKETKEY - - LINEFEEDKEY - - MINUSKEY - - PAGEDOWNKEY - - PAGEUPKEY - - PAUSEKEY - - PERIODKEY - - QUOTEKEY - - RIGHTBRACKETKEY - - RETKEY - - SEMICOLONKEY - - SLASHKEY - - SPACEKEY - - TABKEY Example:: # Set a connected keyboard sensor to accept F1 @@ -156,7 +36,120 @@ Example:: # Activate Left! if key[0] == GameKeys.DKEY: # Activate Right! - + +@group Alphabet keys: AKEY, BKEY, CKEY, DKEY, EKEY, FKEY, GKEY, HKEY, IKEY, JKEY, KKEY, LKEY, MKEY, NKEY, OKEY, PKEY, QKEY, RKEY, SKEY, TKEY, UKEY, VKEY, WKEY, XKEY, YKEY, ZKEY +@var AKEY: +@var BKEY: +@var CKEY: +@var DKEY: +@var EKEY: +@var FKEY: +@var GKEY: +@var HKEY: +@var IKEY: +@var JKEY: +@var KKEY: +@var LKEY: +@var MKEY: +@var NKEY: +@var OKEY: +@var PKEY: +@var QKEY: +@var RKEY: +@var SKEY: +@var TKEY: +@var UKEY: +@var VKEY: +@var WKEY: +@var XKEY: +@var YKEY: +@var ZKEY: + +@group Number keys: ZEROKEY, ONEKEY, TWOKEY, THREEKEY, FOURKEY, FIVEKEY, SIXKEY, SEVENKEY, EIGHTKEY, NINEKEY +@var ZEROKEY: +@var ONEKEY: +@var TWOKEY: +@var THREEKEY: +@var FOURKEY: +@var FIVEKEY: +@var SIXKEY: +@var SEVENKEY: +@var EIGHTKEY: +@var NINEKEY: + +@group Modifiers: CAPSLOCKKEY, LEFTCTRLKEY, LEFTALTKEY, RIGHTALTKEY, RIGHTCTRLKEY, RIGHTSHIFTKEY, LEFTSHIFTKEY +@var CAPSLOCKKEY: +@var LEFTCTRLKEY: +@var LEFTALTKEY: +@var RIGHTALTKEY: +@var RIGHTCTRLKEY: +@var RIGHTSHIFTKEY: +@var LEFTSHIFTKEY: + +@group Arrow Keys: LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY +@var LEFTARROWKEY: +@var DOWNARROWKEY: +@var RIGHTARROWKEY: +@var UPARROWKEY: + +@group Numberpad Keys: PAD0, PAD1, PAD2, PAD3, PAD4, PAD5, PAD6, PAD7, PAD8, PAD9, PADPERIOD, PADSLASHKEY, PADASTERKEY, PADMINUS, PADENTER, PADPLUSKEY +@var PAD0: +@var PAD1: +@var PAD2: +@var PAD3: +@var PAD4: +@var PAD5: +@var PAD6: +@var PAD7: +@var PAD8: +@var PAD9: +@var PADPERIOD: +@var PADSLASHKEY: +@var PADASTERKEY: +@var PADMINUS: +@var PADENTER: +@var PADPLUSKEY: + +@group Function Keys: F1KEY, F2KEY, F3KEY, F4KEY, F5KEY, F6KEY, F7KEY, F8KEY, F9KEY, F10KEY, F11KEY, F12KEY +@var F1KEY: +@var F2KEY: +@var F3KEY: +@var F4KEY: +@var F5KEY: +@var F6KEY: +@var F7KEY: +@var F8KEY: +@var F9KEY: +@var F10KEY: +@var F11KEY: +@var F12KEY: + +@group Other Keys: ACCENTGRAVEKEY, BACKSLASHKEY, BACKSPACEKEY, COMMAKEY, DELKEY, ENDKEY, EQUALKEY, ESCKEY, HOMEKEY, INSERTKEY, LEFTBRACKETKEY, LINEFEEDKEY, MINUSKEY, PAGEDOWNKEY, PAGEUPKEY, PAUSEKEY, PERIODKEY, QUOTEKEY, RIGHTBRACKETKEY, RETKEY, SEMICOLONKEY, SLASHKEY, SPACEKEY, TABKEY +@var ACCENTGRAVEKEY: +@var BACKSLASHKEY: +@var BACKSPACEKEY: +@var COMMAKEY: +@var DELKEY: +@var ENDKEY: +@var EQUALKEY: +@var ESCKEY: +@var HOMEKEY: +@var INSERTKEY: +@var LEFTBRACKETKEY: +@var LINEFEEDKEY: +@var MINUSKEY: +@var PAGEDOWNKEY: +@var PAGEUPKEY: +@var PAUSEKEY: +@var PERIODKEY: +@var QUOTEKEY: +@var RIGHTBRACKETKEY: +@var RETKEY: +@var SEMICOLONKEY: +@var SLASHKEY: +@var SPACEKEY: +@var TABKEY: + """ def EventToString(event): diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 1996aa3f8a9..74e7f852018 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -62,25 +62,29 @@ Documentation for the GameLogic Module. GameLogic.addActiveActuator(actuator, True) See the actuator's reference for available methods: + - L{2DFilterActuator} - L{ActionActuator} - L{AddObjectActuator} - L{CameraActuator} - L{CDActuator} - L{ConstraintActuator} + - L{DynamicActuator} - L{EndObjectActuator} - L{GameActuator} - L{IpoActuator} - L{NetworkMessageActuator} - L{ObjectActuator} + - L{ParentActuator} - L{PropertyActuator} - L{RandomActuator} - L{ReplaceMeshActuator} - L{SceneActuator} + - L{ShapeActionActuator} - L{SoundActuator} + - L{StateActuator} - L{TrackToActuator} - L{VisibilityActuator} - - L{DynamicActuator} - + Most logic brick's methods are accessors for the properties available in the logic buttons. Consult the logic bricks documentation for more information on how each logic brick works. @@ -107,20 +111,31 @@ Documentation for the GameLogic Module. @var KX_PROPSENSOR_CHANGED: Activate when the property changes @var KX_PROPSENSOR_EXPRESSION: Activate when the expression matches -@group Constraint Actuator: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ + + + +@group Constraint Actuator: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ, KX_CONSTRAINTACT_DIRNX, KX_CONSTRAINTACT_DIRNY, KX_CONSTRAINTACT_DIRPX, KX_CONSTRAINTACT_DIRPY, KX_CONSTRAINTACT_ORIX, KX_CONSTRAINTACT_ORIY, KX_CONSTRAINTACT_ORIZ @var KX_CONSTRAINTACT_LOCX: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_LOCY: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_LOCZ: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_ROTX: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_ROTY: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_ROTZ: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_DIRNX: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_DIRNY: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_DIRPX: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_DIRPY: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_ORIX: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_ORIY: See L{KX_ConstraintActuator} +@var KX_CONSTRAINTACT_ORIZ: See L{KX_ConstraintActuator} -@group IPO Actuator: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND +@group IPO Actuator: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND, KX_IPOACT_FROM_PROP @var KX_IPOACT_PLAY: See L{KX_IpoActuator} @var KX_IPOACT_PINGPONG: See L{KX_IpoActuator} @var KX_IPOACT_FLIPPER: See L{KX_IpoActuator} @var KX_IPOACT_LOOPSTOP: See L{KX_IpoActuator} @var KX_IPOACT_LOOPEND: See L{KX_IpoActuator} +@var KX_IPOACT_FROM_PROP: See L{KX_IpoActuator} @group Random Distributions: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL @var KX_RANDOMACT_BOOL_CONST: See L{SCA_RandomActuator} @@ -183,8 +198,103 @@ Documentation for the GameLogic Module. @var KX_MOUSE_BUT_LEFT: See L{SCA_MouseSensor} @var KX_MOUSE_BUT_MIDDLE: See L{SCA_MouseSensor} @var KX_MOUSE_BUT_RIGHT: See L{SCA_MouseSensor} + +@group States: KX_STATE1, KX_STATE10, KX_STATE11, KX_STATE12, KX_STATE13, KX_STATE14, KX_STATE15, KX_STATE16, KX_STATE17, KX_STATE18, KX_STATE19, KX_STATE2, KX_STATE20, KX_STATE21, KX_STATE22, KX_STATE23, KX_STATE24, KX_STATE25, KX_STATE26, KX_STATE27, KX_STATE28, KX_STATE29, KX_STATE3, KX_STATE30, KX_STATE4, KX_STATE5, KX_STATE6, KX_STATE7, KX_STATE8, KX_STATE9, KX_STATE_OP_CLR, KX_STATE_OP_CPY, KX_STATE_OP_NEG, KX_STATE_OP_SET +@var KX_STATE1: +@var KX_STATE10: +@var KX_STATE11: +@var KX_STATE12: +@var KX_STATE13: +@var KX_STATE14: +@var KX_STATE15: +@var KX_STATE16: +@var KX_STATE17: +@var KX_STATE18: +@var KX_STATE19: +@var KX_STATE2: +@var KX_STATE20: +@var KX_STATE21: +@var KX_STATE22: +@var KX_STATE23: +@var KX_STATE24: +@var KX_STATE25: +@var KX_STATE26: +@var KX_STATE27: +@var KX_STATE28: +@var KX_STATE29: +@var KX_STATE3: +@var KX_STATE30: +@var KX_STATE4: +@var KX_STATE5: +@var KX_STATE6: +@var KX_STATE7: +@var KX_STATE8: +@var KX_STATE9: +@var KX_STATE_OP_CLR: +@var KX_STATE_OP_CPY: +@var KX_STATE_OP_NEG: +@var KX_STATE_OP_SET: + +@group UNSORTED: BL_DST_ALPHA, BL_DST_COLOR, BL_ONE, BL_ONE_MINUS_DST_ALPHA, BL_ONE_MINUS_DST_COLOR, BL_ONE_MINUS_SRC_ALPHA, BL_ONE_MINUS_SRC_COLOR, BL_SRC_ALPHA, BL_SRC_ALPHA_SATURATE, BL_SRC_COLOR, BL_ZERO, CAM_POS, CONSTANT_TIMER, KX_ACT_CONSTRAINT_DISTANCE, KX_ACT_CONSTRAINT_DOROTFH, KX_ACT_CONSTRAINT_FHNX, KX_ACT_CONSTRAINT_FHNY, KX_ACT_CONSTRAINT_FHNZ, KX_ACT_CONSTRAINT_FHPX, KX_ACT_CONSTRAINT_FHPY, KX_ACT_CONSTRAINT_FHPZ, KX_ACT_CONSTRAINT_LOCAL, KX_ACT_CONSTRAINT_MATERIAL, KX_ACT_CONSTRAINT_NORMAL, KX_ACT_CONSTRAINT_PERMANENT, MODELMATRIX, MODELMATRIX_INVERSE, MODELMATRIX_INVERSETRANSPOSE, MODELMATRIX_TRANSPOSE, MODELVIEWMATRIX, MODELVIEWMATRIX_INVERSE, MODELVIEWMATRIX_INVERSETRANSPOSE, MODELVIEWMATRIX_TRANSPOSE, RAS_2DFILTER_BLUR, RAS_2DFILTER_CUSTOMFILTER, RAS_2DFILTER_DILATION, RAS_2DFILTER_DISABLED, RAS_2DFILTER_ENABLED, RAS_2DFILTER_EROSION, RAS_2DFILTER_GRAYSCALE, RAS_2DFILTER_INVERT, RAS_2DFILTER_LAPLACIAN, RAS_2DFILTER_MOTIONBLUR, RAS_2DFILTER_NOFILTER, RAS_2DFILTER_PREWITT, RAS_2DFILTER_SEPIA, RAS_2DFILTER_SHARPEN, RAS_2DFILTER_SOBEL, SHD_TANGENT, VIEWMATRIX, VIEWMATRIX_INVERSE, VIEWMATRIX_INVERSETRANSPOSE, VIEWMATRIX_TRANSPOSE +@var BL_DST_ALPHA: +@var BL_DST_COLOR: +@var BL_ONE: +@var BL_ONE_MINUS_DST_ALPHA: +@var BL_ONE_MINUS_DST_COLOR: +@var BL_ONE_MINUS_SRC_ALPHA: +@var BL_ONE_MINUS_SRC_COLOR: +@var BL_SRC_ALPHA: +@var BL_SRC_ALPHA_SATURATE: +@var BL_SRC_COLOR: +@var BL_ZERO: +@var CAM_POS: +@var CONSTANT_TIMER: +@var KX_ACT_CONSTRAINT_DISTANCE: +@var KX_ACT_CONSTRAINT_DOROTFH: +@var KX_ACT_CONSTRAINT_FHNX: +@var KX_ACT_CONSTRAINT_FHNY: +@var KX_ACT_CONSTRAINT_FHNZ: +@var KX_ACT_CONSTRAINT_FHPX: +@var KX_ACT_CONSTRAINT_FHPY: +@var KX_ACT_CONSTRAINT_FHPZ: +@var KX_ACT_CONSTRAINT_LOCAL: +@var KX_ACT_CONSTRAINT_MATERIAL: +@var KX_ACT_CONSTRAINT_NORMAL: +@var KX_ACT_CONSTRAINT_PERMANENT: +@var MODELMATRIX: +@var MODELMATRIX_INVERSE: +@var MODELMATRIX_INVERSETRANSPOSE: +@var MODELMATRIX_TRANSPOSE: +@var MODELVIEWMATRIX: +@var MODELVIEWMATRIX_INVERSE: +@var MODELVIEWMATRIX_INVERSETRANSPOSE: +@var MODELVIEWMATRIX_TRANSPOSE: +@var RAS_2DFILTER_BLUR: +@var RAS_2DFILTER_CUSTOMFILTER: +@var RAS_2DFILTER_DILATION: +@var RAS_2DFILTER_DISABLED: +@var RAS_2DFILTER_ENABLED: +@var RAS_2DFILTER_EROSION: +@var RAS_2DFILTER_GRAYSCALE: +@var RAS_2DFILTER_INVERT: +@var RAS_2DFILTER_LAPLACIAN: +@var RAS_2DFILTER_MOTIONBLUR: +@var RAS_2DFILTER_NOFILTER: +@var RAS_2DFILTER_PREWITT: +@var RAS_2DFILTER_SEPIA: +@var RAS_2DFILTER_SHARPEN: +@var RAS_2DFILTER_SOBEL: +@var SHD_TANGENT: +@var VIEWMATRIX: +@var VIEWMATRIX_INVERSE: +@var VIEWMATRIX_INVERSETRANSPOSE: +@var VIEWMATRIX_TRANSPOSE: """ +# TODO +# globalDict +# error + def getCurrentController(): """ Gets the Python controller associated with this Python script. @@ -197,6 +307,14 @@ def getCurrentScene(): @rtype: L{KX_Scene} """ +def getSceneList(): + """ + Gets a list of the current scenes loaded in the game engine. + + @note: Scenes in your blend file that have not been converted wont be in this list. This list will only contain scenes such as overlays scenes. + + @rtype: list of L{KX_Scene} + """ def addActiveActuator(actuator, activate): """ Activates the given actuator. @@ -309,3 +427,7 @@ def getBlendFileList(path = "//"): @return: A list of filenames, with no directory prefix @rtype: list """ +def PrintGLInfo(): + """ + Prints GL Extension Info into the console + """ \ No newline at end of file diff --git a/source/gameengine/PyDoc/Rasterizer.py b/source/gameengine/PyDoc/Rasterizer.py index fdd53c27898..25877364836 100644 --- a/source/gameengine/PyDoc/Rasterizer.py +++ b/source/gameengine/PyDoc/Rasterizer.py @@ -148,6 +148,13 @@ def setMistColor(rgb): @type rgb: list [r, g, b] """ + +def setAmbientColor(rgb): + """ + Sets the color of ambient light. + + @type rgb: list [r, g, b] + """ def setMistStart(start): """ @@ -164,6 +171,13 @@ def setMistEnd(end): @type end: float """ +def disableMist(): + """ + Disables mist. + + @note: Set any of the mist properties to enable mist. + """ + def setEyeSeparation(eyesep): """ Sets the eye separation for stereo mode. @@ -237,3 +251,15 @@ def drawLine(fromVec,toVec,color): @type color: list [r, g, b] """ +def enableMotionBlur(factor): + """ + Enable the motion blue effect. + + @param factor: the ammount of motion blur to display. + @type factor: float [0.0 - 1.0] + """ + +def disableMotionBlur(): + """ + Disable the motion blue effect. + """ diff --git a/source/gameengine/PyDoc/bge_api_validate_py.txt b/source/gameengine/PyDoc/bge_api_validate_py.txt index 0920e5d3c7d..492dcef408b 100644 --- a/source/gameengine/PyDoc/bge_api_validate_py.txt +++ b/source/gameengine/PyDoc/bge_api_validate_py.txt @@ -12,9 +12,17 @@ # # Currently it only prints missing modules and methods (not attributes) +import sys, os BGE_API_DOC_PATH = 'source/gameengine/PyDoc' + +mods = ['GameLogic', 'Rasterizer', 'GameKeys'] +mods_dict = {} +for m in mods: + mods_dict[m] = sys.modules[m] + + import GameTypes type_members = {} @@ -34,7 +42,7 @@ for type_name in dir(GameTypes): # print type_object.__name__ + '.' + k members.append(member) -import sys, os + doc_dir= os.path.join(os.getcwd(), BGE_API_DOC_PATH) @@ -58,7 +66,7 @@ def check_attribute(type_mame, member): ''' - if l.startswith('@ivar'): + if l.startswith('@ivar') or l.startswith('@var'): var = l.split()[1].split(':')[0] if var == member: @@ -108,3 +116,30 @@ for type_name in sorted(type_members.keys()): else: print "\tmissing: %s.%s" % (type_name, member) + +# Now check the modules +for mod_name, pymod in mods_dict.iteritems(): + print pymod + del sys.modules[mod_name] + + # Now well get the python version + pydoc = __import__(mod_name) + pydoc = reload(pydoc) # avoid using the out dated pyc file only + print pydoc.__file__ + + for member in sorted(dir(pymod)): + if hasattr(pydoc, member) or check_attribute(mod_name, member): + if PRINT_OK: + print "\tfound module attr: %s.%s" % (mod_name, member) + else: + print "\tmissing module attr: %s.%s" % (mod_name, member) + + # Restore real module + sys.modules[mod_name] = pymod + + +sys.path.pop() # remove the pydoc dir from our import paths + + + + From 3038fb1a0175ef5e3d595460a7f281c77028b5a1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 25 Apr 2009 07:17:36 +0000 Subject: [PATCH 060/444] [#18606] Writing to KX_GameObject.orientation causes crash Own bug, conversion function to get an orientation from python - PyOrientationTo() ignored user input completely :| (breaking the orientation attribute) Also made KX_GameObject worldOrientation writable and minor doc fixes. --- source/gameengine/Ketsji/KX_GameObject.cpp | 48 ++++++++++++++-------- source/gameengine/Ketsji/KX_GameObject.h | 1 + source/gameengine/Ketsji/KX_PyMath.cpp | 3 +- source/gameengine/PyDoc/KX_GameObject.py | 10 ++--- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 7629f9d8f1a..297d3048a3a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1133,7 +1133,7 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("state", KX_GameObject, pyattr_get_state, pyattr_set_state), KX_PYATTRIBUTE_RO_FUNCTION("meshes", KX_GameObject, pyattr_get_meshes), KX_PYATTRIBUTE_RW_FUNCTION("localOrientation",KX_GameObject,pyattr_get_localOrientation,pyattr_set_localOrientation), - KX_PYATTRIBUTE_RO_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation), + KX_PYATTRIBUTE_RW_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_worldOrientation), KX_PYATTRIBUTE_RW_FUNCTION("localPosition", KX_GameObject, pyattr_get_localPosition, pyattr_set_localPosition), KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition), KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), @@ -1515,6 +1515,26 @@ PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYAT return PyObjectFrom(self->NodeGetWorldOrientation()); } +int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self= static_cast(self_v); + + /* if value is not a sequence PyOrientationTo makes an error */ + MT_Matrix3x3 rot; + if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, ")) + return NULL; + + if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) { + self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); + } + else { + self->NodeSetLocalOrientation(rot); + } + + self->NodeUpdateGS(0.f); + return 0; +} + PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); @@ -1530,7 +1550,7 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT /* if value is not a sequence PyOrientationTo makes an error */ MT_Matrix3x3 rot; - if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, ")) + if (!PyOrientationTo(value, rot, "gameOb.localOrientation = sequence: KX_GameObject, ")) return NULL; self->NodeSetLocalOrientation(rot); @@ -2170,23 +2190,15 @@ PyObject* KX_GameObject::PyGetOrientation() //keywords PyObject* KX_GameObject::PySetOrientation(PyObject* value) { ShowDeprecationWarning("setOrientation()", "the orientation property"); - MT_Matrix3x3 matrix; - if (PyObject_IsMT_Matrix(value, 3) && PyMatTo(value, matrix)) - { - NodeSetLocalOrientation(matrix); - NodeUpdateGS(0.f); - Py_RETURN_NONE; - } + MT_Matrix3x3 rot; + + /* if value is not a sequence PyOrientationTo makes an error */ + if (!PyOrientationTo(value, rot, "gameOb.setOrientation(sequence): KX_GameObject, ")) + return NULL; - MT_Quaternion quat; - if (PyVecTo(value, quat)) - { - matrix.setRotation(quat); - NodeSetLocalOrientation(matrix); - NodeUpdateGS(0.f); - Py_RETURN_NONE; - } - return NULL; + NodeSetLocalOrientation(rot); + NodeUpdateGS(0.f); + Py_RETURN_NONE; } PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args) diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 2ca4fc6a63f..fe9f39a6ed3 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -884,6 +884,7 @@ public: static PyObject* pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index 0093a72808e..051d7ae7dba 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -75,9 +75,8 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) return false; } -bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix) +bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefix) { - MT_Matrix3x3 rot; int size= PySequence_Size(pyval); if (size == 4) diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index db0aebfc761..10abf8b8197 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -49,13 +49,13 @@ class KX_GameObject: # (SCA_IObject) @type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. @type localOrientation: 3x3 Matrix [[float]] - @ivar worldOrientation: The object's world orientation. Read-only. + @ivar worldOrientation: The object's world orientation. @type worldOrientation: 3x3 Matrix [[float]] @ivar localScaling: The object's local scaling factor. @type localScaling: list [sx, sy, sz] @ivar worldScaling: The object's world scaling factor. Read-only @type worldScaling: list [sx, sy, sz] - @ivar localPosition: The object's local position. + @ivar localPosition: The object's local position. @type localPosition: list [x, y, z] @ivar worldPosition: The object's world position. @type worldPosition: list [x, y, z] @@ -87,10 +87,10 @@ class KX_GameObject: # (SCA_IObject) Delete this object, can be used inpace of the EndObject Actuator. The actual removal of the object from the scene is delayed. """ - def replaceMesh(mesh_name): + def replaceMesh(mesh): """ Replace the mesh of this object with a new mesh. This works the same was as the actuator. - @type mesh_name: string + @type mesh: L{KX_MeshProxy} or mesh name """ def getVisible(): """ @@ -468,7 +468,7 @@ class KX_GameObject: # (SCA_IObject) @type objfrom: L{KX_GameObject} or 3-tuple or None @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to @type dist: float - @param prop: property name that object must have; can be omitted => detect any object + @param prop: property name that object must have; can be omitted or "" => detect any object @type prop: string @param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin @type face: int From b991b32458cdccb19a203e7ba4ca6b5780aad6cb Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 25 Apr 2009 12:20:59 +0000 Subject: [PATCH 061/444] BGE mesh modifiers: fix view frustrum culling for mesh with modifiers. Update the bounding box based on mesh extent after applying the modifiers. --- .../Converter/BL_BlenderDataConversion.cpp | 8 +++++++- source/gameengine/Converter/BL_MeshDeformer.h | 1 + .../Converter/BL_ModifierDeformer.cpp | 9 +++++++++ source/gameengine/Converter/BL_SkinDeformer.h | 5 +++++ .../Ketsji/KX_ConvertPhysicsObjects.cpp | 7 +++++++ .../Physics/Bullet/CcdGraphicController.cpp | 17 +++++++++++++++-- .../Physics/Bullet/CcdGraphicController.h | 2 ++ .../Physics/common/PHY_IGraphicController.h | 2 ++ source/gameengine/Rasterizer/RAS_Deformer.h | 1 + 9 files changed, 49 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 84b7407aacf..b2f283220a0 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1298,8 +1298,14 @@ void BL_CreateGraphicObjectNew(KX_GameObject* gameobj, gameobj->SetGraphicController(ctrl); ctrl->setNewClientInfo(gameobj->getClientInfo()); ctrl->setLocalAabb(localAabbMin, localAabbMax); - if (isActive) + if (isActive) { + // add first, this will create the proxy handle env->addCcdGraphicController(ctrl); + // update the mesh if there is a deformer, this will also update the bounding box for modifiers + RAS_Deformer* deformer = gameobj->GetDeformer(); + if (deformer) + deformer->UpdateBuckets(); + } } break; #endif diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 34944421b28..d1754618df2 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -64,6 +64,7 @@ public: virtual void SetSimulatedTime(double time){}; virtual bool Apply(class RAS_IPolyMaterial *mat); virtual bool Update(void){ return false; }; + virtual bool UpdateBuckets(void){ return false; }; virtual RAS_Deformer* GetReplica(){return NULL;}; virtual void ProcessReplica() { }; struct Mesh* GetMesh() { return m_bmesh; }; diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index c3131559a6f..3c4c0c5caad 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -37,6 +37,7 @@ #include "STR_HashedString.h" #include "RAS_IPolygonMaterial.h" #include "BL_SkinMeshObject.h" +#include "PHY_IGraphicController.h" //#include "BL_ArmatureController.h" #include "DNA_armature_types.h" @@ -132,6 +133,14 @@ bool BL_ModifierDeformer::Update(void) m_dm->release(m_dm); } m_dm = dm; + /* update the graphic controller */ + PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController(); + if (ctrl) { + float min_r[3], max_r[3]; + INIT_MINMAX(min_r, max_r); + m_dm->getMinMax(m_dm, min_r, max_r); + ctrl->setLocalAabb(min_r, max_r); + } m_lastModifierUpdate=m_gameobj->GetLastFrame(); bShapeUpdate = true; } diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index ee240588851..0a7b60788f9 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -71,6 +71,11 @@ public: virtual ~BL_SkinDeformer(); bool Update (void); bool Apply (class RAS_IPolyMaterial *polymat); + bool UpdateBuckets(void) + { + // update the deformer and all the mesh slots; Apply() does it well, so just call it. + return Apply(NULL); + } bool PoseUpdated(void) { if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) { diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index f4f8ec9f91b..700c5f304e7 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -759,6 +759,13 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, //printf("update\n"); return true;//?? } + virtual bool UpdateBuckets(void) + { + // this is to update the mesh slots outside the rasterizer, + // no need to do it for this deformer, it's done in any case in Apply() + return false; + } + virtual RAS_Deformer *GetReplica() { KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this); diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp index caf18fd28ba..2d1f841af0c 100644 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp +++ b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp @@ -47,11 +47,24 @@ void CcdGraphicController::setLocalAabb(const btVector3& aabbMin,const btVector3 void CcdGraphicController::setLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax) { - m_localAabbMin = btVector3(aabbMin[0],aabbMin[1],aabbMin[2]); - m_localAabbMax = btVector3(aabbMax[0],aabbMax[1],aabbMax[2]); + m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]); + m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]); SetGraphicTransform(); } +void CcdGraphicController::setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax) +{ + m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]); + m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]); + SetGraphicTransform(); +} + +void CcdGraphicController::setLocalAabb(const float* aabbMin,const float* aabbMax) +{ + m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]); + m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]); + SetGraphicTransform(); +} void CcdGraphicController::getAabb(btVector3& aabbMin, btVector3& aabbMax) { diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h index 8faa0944313..8f44a623371 100644 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.h +++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h @@ -38,6 +38,8 @@ public: void setLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax); void setLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax); + virtual void setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax); + virtual void setLocalAabb(const float aabbMin[3],const float aabbMax[3]); PHY_IMotionState* GetMotionState() { return m_motionState; } void getAabb(btVector3& aabbMin, btVector3& aabbMax); diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h index 36b8a978e87..8acc5c2f9d3 100644 --- a/source/gameengine/Physics/common/PHY_IGraphicController.h +++ b/source/gameengine/Physics/common/PHY_IGraphicController.h @@ -47,6 +47,8 @@ class PHY_IGraphicController : public PHY_IController SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') */ virtual bool SetGraphicTransform()=0; + virtual void setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax)=0; + virtual void setLocalAabb(const float* aabbMin,const float* aabbMax)=0; virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate) {return 0;} diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index 5a6bab4c82d..fe081dd4aa5 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -44,6 +44,7 @@ public: virtual void Relink(GEN_Map*map)=0; virtual bool Apply(class RAS_IPolyMaterial *polymat)=0; virtual bool Update(void)=0; + virtual bool UpdateBuckets(void)=0; virtual RAS_Deformer *GetReplica()=0; virtual void ProcessReplica()=0; virtual bool SkipVertexTransform() From 5233069908265611bc542d370258b1ab96fddfb4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 25 Apr 2009 12:58:07 +0000 Subject: [PATCH 062/444] Running 2.48rc on my system segfaults when starting the game engine, only on the release, not for my own builds. Setting the SDL video driver to dummy prevents the crash, this is recommended in the SDL docs if your not using the video driver. --- source/creator/creator.c | 1 + source/gameengine/PyDoc/KX_GameObject.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 5c0ca9e07ff..7804eb7ad98 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -538,6 +538,7 @@ int main(int argc, char **argv) BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */ #ifndef DISABLE_SDL + setenv("SDL_VIDEODRIVER", "dummy", 1); /* initializing the video driver can cause crashes on some systems - Campbell */ #ifdef __linux__ /* On linux the default SDL driver dma often would not play * use alsa if none is set */ diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 10abf8b8197..fcb3d91dbcb 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -159,7 +159,7 @@ class KX_GameObject: # (SCA_IObject) @param orn: a rotation matrix specifying the new rotation. @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. """ - def alignAxisToVect(vect, axis): + def alignAxisToVect(vect, axis, factor): """ Aligns any of the game object's axis along the given vector. @@ -170,6 +170,8 @@ class KX_GameObject: # (SCA_IObject) - 0: X axis - 1: Y axis - 2: Z axis (default) + @type factor: float + @param factor: Only rotate a feaction of the distance to the target vector (0.0 - 1.0) """ def getAxisVect(vect): """ From 113b438dce15061d57539ab694e30e115bb1418e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 25 Apr 2009 17:41:17 +0000 Subject: [PATCH 063/444] [#18611] console.py linewrap from Jim Hi8ll (jthill) --- release/scripts/console.py | 75 +++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/release/scripts/console.py b/release/scripts/console.py index 0e46f41f581..c6ae22a86f5 100644 --- a/release/scripts/console.py +++ b/release/scripts/console.py @@ -708,20 +708,23 @@ def draw_gui(): # Fixed margin. use a margin since 0 margin can be hard to seewhen close to a crt's edge. margin = 4 + # Convenience + FNT_NAME, FNT_HEIGHT = __FONT_SIZES__[__FONT_SIZE__] + # Draw cursor location colour if __CONSOLE_LINE_OFFSET__ == 0: - cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], __FONT_SIZES__[__FONT_SIZE__][0]) + cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], FNT_NAME) BGL.glColor3f(0.8, 0.2, 0.2) if cmd2curWidth == 0: - BGL.glRecti(margin,2,margin+2, __FONT_SIZES__[__FONT_SIZE__][1]+2) + BGL.glRecti(margin,2,margin+2, FNT_HEIGHT+2) else: - BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, __FONT_SIZES__[__FONT_SIZE__][1]+2) + BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, FNT_HEIGHT+2) BGL.glColor3f(1,1,1) # Draw the set of cammands to the buffer consoleLineIdx = __CONSOLE_LINE_OFFSET__ + 1 wrapLineIndex = 0 - while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * __FONT_SIZES__[__FONT_SIZE__][1]: + while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * FNT_HEIGHT: if cmdBuffer[-consoleLineIdx].type == 0: BGL.glColor3f(1, 1, 1) elif cmdBuffer[-consoleLineIdx].type == 1: @@ -734,53 +737,41 @@ def draw_gui(): BGL.glColor3f(1, 1, 0) if consoleLineIdx == 1: # user input - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - else: - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - - # Wrapping is totally slow, can even hang blender - dont do it! - ''' - if consoleLineIdx == 1: # NEVER WRAP THE USER INPUT - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) - # BUG, LARGE TEXT DOSENT DISPLAY - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - - - else: # WRAP? - # LINE WRAP - if Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) > __CONSOLE_RECT__[2]: + BGL.glRasterPos2i(margin, (FNT_HEIGHT * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) + Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) + else: # WRAP + lwid = Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) + if margin + lwid > __CONSOLE_RECT__[2]: wrapLineList = [] - copyCmd = [cmdBuffer[-consoleLineIdx].cmd, ''] - while copyCmd != ['','']: - while margin + Draw.GetStringWidth(copyCmd[0], __FONT_SIZES__[__FONT_SIZE__][0]) > __CONSOLE_RECT__[2]: - #print copyCmd - copyCmd[1] = '%s%s'% (copyCmd[0][-1], copyCmd[1]) # Add the char on the end - copyCmd[0] = copyCmd[0][:-1]# remove last chat - - # Now we have copyCmd[0] at a good length we can print it. - if copyCmd[0] != '': - wrapLineList.append(copyCmd[0]) - - copyCmd[0]='' - copyCmd = [copyCmd[1], copyCmd[0]] - + wtext = cmdBuffer[-consoleLineIdx].cmd + wlimit = len(wtext) + chunksz = int(( __CONSOLE_RECT__[2] - margin ) / (lwid / len(wtext))) + lstart = 0 + fsize = FNT_NAME + while lstart < wlimit: + lend = min(lstart+chunksz,wlimit) + ttext = wtext[lstart:lend] + while lend < wlimit and Draw.GetStringWidth(ttext, fsize) + margin < __CONSOLE_RECT__[2]: + lend += 1 + ttext = wtext[lstart:lend] + while lend > lstart+1 and Draw.GetStringWidth(ttext, fsize) + margin > __CONSOLE_RECT__[2]: + lend -= 1 + ttext = wtext[lstart:lend] + wrapLineList.append(ttext) + lstart = lend # Now we have a list of lines, draw them (OpenGLs reverse ordering requires this odd change) wrapLineList.reverse() for wline in wrapLineList: - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1]*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8) - Draw.Text(wline, __FONT_SIZES__[__FONT_SIZE__][0]) + BGL.glRasterPos2i(margin, (FNT_HEIGHT*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8) + Draw.Text(wline, FNT_NAME) wrapLineIndex += 1 - wrapLineIndex-=1 # otherwise we get a silly extra line. + wrapLineIndex-=1 # otherwise we get a silly extra line. else: # no wrapping. - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - ''' + BGL.glRasterPos2i(margin, (FNT_HEIGHT * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) + Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) consoleLineIdx += 1 - # This recieves the event index, call a function from here depending on the event. def handle_button_event(evt): From dd21e9b62691daab1464dda0a0ab44d107480dec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 25 Apr 2009 17:52:04 +0000 Subject: [PATCH 064/444] patch from michael williamson, export multiple UV layers to lightwave [#18575] remove unused local variables --- release/scripts/lightwave_export.py | 37 +++++++++++-------- .../nodes/intern/TEX_nodes/TEX_distance.c | 1 - 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/release/scripts/lightwave_export.py b/release/scripts/lightwave_export.py index 9235af12f7e..115761ec3e0 100644 --- a/release/scripts/lightwave_export.py +++ b/release/scripts/lightwave_export.py @@ -351,23 +351,28 @@ def generate_vmad_vc(mesh): # === Generate Per-Face UV Coords (VMAD Chunk) === # ================================================ def generate_vmad_uv(mesh): - data = cStringIO.StringIO() - data.write("TXUV") # type - data.write(struct.pack(">H", 2)) # dimension - data.write(generate_nstring("Blender's UV Coordinates")) # name + layers = mesh.getUVLayerNames() + org_uv = mesh.activeUVLayer + for l in layers: + mesh.activeUVLayer = l + data = cStringIO.StringIO() + data.write("TXUV") # type + data.write(struct.pack(">H", 2)) # dimension + data.write(generate_nstring(l)) # name + for i, f in enumerate(mesh.faces): + if not i%100: + Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coordinates") + + uv = f.uv + f_v = f.v + for j in xrange(len(f)-1, -1, -1): # Reverse order + U,V = uv[j] + v = f_v[j].index + data.write(struct.pack(">H", v)) # vertex index + data.write(struct.pack(">H", i)) # face index + data.write(struct.pack(">ff", U, V)) - for i, f in enumerate(mesh.faces): - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coordinates") - - uv = f.uv - f_v = f.v - for j in xrange(len(f)-1, -1, -1): # Reverse order - U,V = uv[j] - v = f_v[j].index - data.write(struct.pack(">H", v)) # vertex index - data.write(struct.pack(">H", i)) # face index - data.write(struct.pack(">ff", U, V)) + mesh.activeUVLayer = org_uv return data.getvalue() # ====================================== diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c index ff9ec4db76b..d23eb6bc589 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c @@ -44,7 +44,6 @@ static bNodeSocketType outputs[]= { static void valuefn(float *out, float *coord, bNode *node, bNodeStack **in, short thread) { float coord1[3], coord2[3]; - float x, y, z; tex_input_vec(coord1, in[0], coord, thread); tex_input_vec(coord2, in[1], coord, thread); From fb7803c300a89892f1d5a76398b3c2506465cf60 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 25 Apr 2009 20:26:27 +0000 Subject: [PATCH 065/444] Amendment for 19924 - no setenv() on Windows, make it work with _putenv_s(). --- source/creator/creator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/creator/creator.c b/source/creator/creator.c index 7804eb7ad98..74e899d2d14 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -538,7 +538,11 @@ int main(int argc, char **argv) BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */ #ifndef DISABLE_SDL +#ifndef WIN32 setenv("SDL_VIDEODRIVER", "dummy", 1); /* initializing the video driver can cause crashes on some systems - Campbell */ +#else + _putenv_s("SDL_VIDEODRIVER", "dummy"); +#endif #ifdef __linux__ /* On linux the default SDL driver dma often would not play * use alsa if none is set */ From fc4ba5e13116835c3208ecfe21c9ccc3e93277f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 26 Apr 2009 09:41:39 +0000 Subject: [PATCH 066/444] When adding multiline text drawing I missed a case where the image pointer should have been checked - drawing text on a face with no image would crash blender. Better tooltip for game actuator file field. --- source/blender/gpu/intern/gpu_draw.c | 21 ++++++++------------- source/blender/src/buttons_logic.c | 2 +- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7b1fc67d0c6..6925186d63a 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -79,29 +79,24 @@ void GPU_render_text(MTFace *tface, int mode, const char *textstr, int textlen, unsigned int *col, float *v1, float *v2, float *v3, float *v4, int glattrib) { - if (mode & TF_BMFONT) { - Image* ima; - int characters, index, character; + if ((mode & TF_BMFONT) && (textlen>0) && tface->tpage) { + Image* ima = (Image*)tface->tpage; + int index, character; float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; float advance_tab; - /* multiline */ - float line_start= 0.0f, line_height; + float line_start= 0.0f, line_height; + if (v4) line_height= MAX4(v1[1], v2[1], v3[1], v4[2]) - MIN4(v1[1], v2[1], v3[1], v4[2]); else line_height= MAX3(v1[1], v2[1], v3[1]) - MIN3(v1[1], v2[1], v3[1]); line_height *= 1.2; /* could be an option? */ /* end multiline */ + - characters = textlen; - - ima = (Image*)tface->tpage; - if (ima == NULL) - characters = 0; - - // color has been set + /* color has been set */ if (tface->mode & TF_OBCOL) col= NULL; else if (!col) @@ -116,7 +111,7 @@ void GPU_render_text(MTFace *tface, int mode, advance_tab= advance * 4; /* tab width could also be an option */ - for (index = 0; index < characters; index++) { + for (index = 0; index < textlen; index++) { float uv[4][2]; // lets calculate offset stuff diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 67531e9b3b8..0a7bbf656b3 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -2389,7 +2389,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh ysize = 48; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file"); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); // uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation"); } /* else if (gma->type == ACT_GAME_START) From ba563216e9ec4e7c3e55ca343948d925a2dc1651 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 26 Apr 2009 12:23:30 +0000 Subject: [PATCH 067/444] BGE: Fix Orthographic mode and viewport scaling - the BGE now uses correct glOrtho projection whe camera is in orthographic mode - --- .../gameplayer/ghost/GP_ghost.vcproj | 3 +- .../Converter/BL_BlenderDataConversion.cpp | 2 +- source/gameengine/Ketsji/KX_Camera.cpp | 158 +++++++++--------- source/gameengine/Ketsji/KX_Camera.h | 2 + source/gameengine/Ketsji/KX_Dome.cpp | 6 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 86 ++++++---- source/gameengine/Ketsji/KX_Light.cpp | 3 +- source/gameengine/Rasterizer/RAS_CameraData.h | 4 +- .../Rasterizer/RAS_FramingManager.cpp | 101 +++++++++++ .../Rasterizer/RAS_FramingManager.h | 22 +++ .../gameengine/Rasterizer/RAS_IRasterizer.h | 26 ++- .../RAS_OpenGLRasterizer.cpp | 33 +++- .../RAS_OpenGLRasterizer.h | 15 +- .../gameengine/VideoTexture/ImageRender.cpp | 46 ++--- 14 files changed, 356 insertions(+), 151 deletions(-) diff --git a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj index 01ccd916edb..5cd8a9c469b 100644 --- a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj +++ b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj @@ -166,12 +166,13 @@ (ob->data); - RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob)); + RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob)); KX_Camera *gamecamera; gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index e536d1f1e7e..8565346b30e 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -47,7 +47,7 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, m_camdata(camdata), m_dirty(true), m_normalized(false), - m_frustum_culling(frustum_culling && camdata.m_perspective), + m_frustum_culling(frustum_culling), m_set_projection_matrix(false), m_set_frustum_center(false) { @@ -184,6 +184,11 @@ float KX_Camera::GetLens() const return m_camdata.m_lens; } +float KX_Camera::GetScale() const +{ + return m_camdata.m_scale; +} + float KX_Camera::GetCameraNear() const @@ -264,80 +269,83 @@ void KX_Camera::ExtractFrustumSphere() MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix; clip_camcs_matrix.invert(); - // detect which of the corner of the far clipping plane is the farthest to the origin - MT_Vector4 nfar; // far point in device normalized coordinate - MT_Point3 farpoint; // most extreme far point in camera coordinate - MT_Point3 nearpoint;// most extreme near point in camera coordinate - MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate - MT_Scalar F=1.0, N; // square distance of far and near point to origin - MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0 - MT_Scalar e, s; // far and near clipping distance (<0) - MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance - MT_Scalar z; // projection of sphere center on z axis (<0) - // tmp value - MT_Vector4 npoint(1., 1., 1., 1.); - MT_Vector4 hpoint; - MT_Point3 point; - MT_Scalar len; - for (int i=0; i<4; i++) - { - hpoint = clip_camcs_matrix*npoint; - point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]); - len = point.dot(point); - if (len > F) - { - nfar = npoint; - farpoint = point; - F = len; - } - // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane - len = npoint[0]; - npoint[0] = -npoint[1]; - npoint[1] = len; - farcenter += point; - } - // the far center is the average of the far clipping points - farcenter *= 0.25; - // the extreme near point is the opposite point on the near clipping plane - nfar.setValue(-nfar[0], -nfar[1], -1., 1.); - nfar = clip_camcs_matrix*nfar; - nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]); - N = nearpoint.dot(nearpoint); - e = farpoint[2]; - s = nearpoint[2]; - // projection on XY plane for distance to axis computation - MT_Point2 farxy(farpoint[0], farpoint[1]); - // f is forced positive by construction - f = farxy.length(); - // get corresponding point on the near plane - farxy *= s/e; - // this formula preserve the sign of n - n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length(); - c = MT_Point2(farcenter[0], farcenter[1]).length()/e; - // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case - z = (F-N)/(2.0*(e-s+c*(f-n))); - m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z); - m_frustum_radius = m_frustum_center.distance(farpoint); - -#if 0 - // The most extreme points on the near and far plane. (normalized device coords) - MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.); - - // Transform to hom camera local space - hnear = clip_camcs_matrix*hnear; - hfar = clip_camcs_matrix*hfar; - - // Tranform to 3d camera local space. - MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]); - MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]); - - // Compute center - // don't use camera data in case the user specifies the matrix directly - m_frustum_center = MT_Point3(0., 0., - (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(nearpoint[2]-farpoint[2] /*m_camdata.m_clipend - m_camdata.m_clipstart*/))); - m_frustum_radius = m_frustum_center.distance(farpoint); -#endif - + if (m_projection_matrix[3][3] == MT_Scalar(0.0)) + { + // frustrum projection + // detect which of the corner of the far clipping plane is the farthest to the origin + MT_Vector4 nfar; // far point in device normalized coordinate + MT_Point3 farpoint; // most extreme far point in camera coordinate + MT_Point3 nearpoint;// most extreme near point in camera coordinate + MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate + MT_Scalar F=-1.0, N; // square distance of far and near point to origin + MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0 + MT_Scalar e, s; // far and near clipping distance (<0) + MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance + MT_Scalar z; // projection of sphere center on z axis (<0) + // tmp value + MT_Vector4 npoint(1., 1., 1., 1.); + MT_Vector4 hpoint; + MT_Point3 point; + MT_Scalar len; + for (int i=0; i<4; i++) + { + hpoint = clip_camcs_matrix*npoint; + point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]); + len = point.dot(point); + if (len > F) + { + nfar = npoint; + farpoint = point; + F = len; + } + // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane + len = npoint[0]; + npoint[0] = -npoint[1]; + npoint[1] = len; + farcenter += point; + } + // the far center is the average of the far clipping points + farcenter *= 0.25; + // the extreme near point is the opposite point on the near clipping plane + nfar.setValue(-nfar[0], -nfar[1], -1., 1.); + nfar = clip_camcs_matrix*nfar; + nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]); + // this is a frustrum projection + N = nearpoint.dot(nearpoint); + e = farpoint[2]; + s = nearpoint[2]; + // projection on XY plane for distance to axis computation + MT_Point2 farxy(farpoint[0], farpoint[1]); + // f is forced positive by construction + f = farxy.length(); + // get corresponding point on the near plane + farxy *= s/e; + // this formula preserve the sign of n + n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length(); + c = MT_Point2(farcenter[0], farcenter[1]).length()/e; + // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case + z = (F-N)/(2.0*(e-s+c*(f-n))); + m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z); + m_frustum_radius = m_frustum_center.distance(farpoint); + } + else + { + // orthographic projection + // The most extreme points on the near and far plane. (normalized device coords) + MT_Vector4 hnear(1., 1., 1., 1.), hfar(-1., -1., -1., 1.); + + // Transform to hom camera local space + hnear = clip_camcs_matrix*hnear; + hfar = clip_camcs_matrix*hfar; + + // Tranform to 3d camera local space. + MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]); + MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]); + + // just use mediant point + m_frustum_center = (farpoint + nearpoint)*0.5; + m_frustum_radius = m_frustum_center.distance(farpoint); + } // Transform to world space. m_frustum_center = GetCameraToWorld()(m_frustum_center); m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index d570fac213a..83316972ca0 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -184,6 +184,8 @@ public: /** Gets the aperture. */ float GetLens() const; + /** Gets the ortho scale. */ + float GetScale() const; /** Gets the near clip distance. */ float GetCameraNear() const; /** Gets the far clip distance. */ diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 077e2ce33b7..9565c53e0bf 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -1507,8 +1507,7 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i) MT_Transform camtrans(cam->GetWorldToCamera()); MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); // restore the original orientation @@ -1914,8 +1913,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) MT_Transform camtrans(cam->GetWorldToCamera()); MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); scene->CalculateVisibleMeshes(m_rasterizer,cam); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 63db54a296e..9bac0f7d758 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1093,7 +1093,7 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect area = userviewport; } - else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) { + else if ( !m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) { RAS_FramingManager::ComputeViewport( scene->GetFramingType(), m_canvas->GetDisplayArea(), @@ -1163,13 +1163,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) { bool override_camera; RAS_Rect viewport, area; - float left, right, bottom, top, nearfrust, farfrust, focallength; - const float ortho = 100.0; + float nearfrust, farfrust, focallength; // KX_Camera* cam = scene->GetActiveCamera(); if (!cam) return; - GetSceneViewport(scene, cam, area, viewport); // store the computed viewport in the scene @@ -1187,19 +1185,24 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) override_camera = override_camera && (cam->GetName() == "__default__cam__"); if (override_camera && m_overrideCamUseOrtho) { - MT_CmMatrix4x4 projmat = m_overrideCamProjMat; - m_rasterizer->SetProjectionMatrix(projmat); + m_rasterizer->SetProjectionMatrix(m_overrideCamProjMat); + if (!cam->hasValidProjectionMatrix()) { + // needed to get frustrum planes for culling + MT_Matrix4x4 projmat; + projmat.setValue(m_overrideCamProjMat.getPointer()); + cam->SetProjectionMatrix(projmat); + } } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() ) { m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); } else { RAS_FrameFrustum frustum; - float lens = cam->GetLens(); bool orthographic = !cam->GetCameraData()->m_perspective; nearfrust = cam->GetCameraNear(); farfrust = cam->GetCameraFar(); focallength = cam->GetFocalLength(); + MT_Matrix4x4 projmat; if(override_camera) { nearfrust = m_overrideCamNear; @@ -1207,45 +1210,56 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) } if (orthographic) { - lens *= ortho; - nearfrust = (nearfrust + 1.0)*ortho; - farfrust *= ortho; + + RAS_FramingManager::ComputeOrtho( + scene->GetFramingType(), + area, + viewport, + cam->GetScale(), + nearfrust, + farfrust, + frustum + ); + if (!cam->GetViewport()) { + frustum.x1 *= m_cameraZoom; + frustum.x2 *= m_cameraZoom; + frustum.y1 *= m_cameraZoom; + frustum.y2 *= m_cameraZoom; + } + projmat = m_rasterizer->GetOrthoMatrix( + frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar); + + } else { + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + cam->GetLens(), + nearfrust, + farfrust, + frustum + ); + + if (!cam->GetViewport()) { + frustum.x1 *= m_cameraZoom; + frustum.x2 *= m_cameraZoom; + frustum.y1 *= m_cameraZoom; + frustum.y2 *= m_cameraZoom; + } + projmat = m_rasterizer->GetFrustumMatrix( + frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar, focallength); } - - RAS_FramingManager::ComputeFrustum( - scene->GetFramingType(), - area, - viewport, - lens, - nearfrust, - farfrust, - frustum - ); - - left = frustum.x1 * m_cameraZoom; - right = frustum.x2 * m_cameraZoom; - bottom = frustum.y1 * m_cameraZoom; - top = frustum.y2 * m_cameraZoom; - nearfrust = frustum.camnear; - farfrust = frustum.camfar; - - MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( - left, right, bottom, top, nearfrust, farfrust, focallength); - cam->SetProjectionMatrix(projmat); // Otherwise the projection matrix for each eye will be the same... - if (m_rasterizer->Stereo()) + if (!orthographic && m_rasterizer->Stereo()) cam->InvalidateProjectionMatrix(); } MT_Transform camtrans(cam->GetWorldToCamera()); - if (!cam->GetCameraData()->m_perspective) - camtrans.getOrigin()[2] *= ortho; MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); //redundant, already done in Render() diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 7bc982111fe..498eb7262b5 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -160,8 +160,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T /* setup rasterizer transformations */ ras->SetProjectionMatrix(projectionmat); - ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); } void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index e3af43fb839..c8f4d9a0a17 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -32,6 +32,7 @@ struct RAS_CameraData { float m_lens; + float m_scale; float m_clipstart; float m_clipend; bool m_perspective; @@ -42,10 +43,11 @@ struct RAS_CameraData int m_viewporttop; float m_focallength; - RAS_CameraData(float lens = 35.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, + RAS_CameraData(float lens = 35.0, float scale = 6.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) : m_lens(lens), + m_scale(scale), m_clipstart(clipstart), m_clipend(clipend), m_perspective(perspective), diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.cpp b/source/gameengine/Rasterizer/RAS_FramingManager.cpp index e2bbca48bb5..ea18ffb2298 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.cpp +++ b/source/gameengine/Rasterizer/RAS_FramingManager.cpp @@ -70,6 +70,39 @@ ComputeDefaultFrustum( frustum.camfar = camfar; } + void +RAS_FramingManager:: +ComputeDefaultOrtho( + const float camnear, + const float camfar, + const float scale, + const float design_aspect_ratio, + RAS_FrameFrustum & frustum +) +{ + float halfSize = scale*0.5f; + float sizeX; + float sizeY; + + if (design_aspect_ratio > 1.f) { + // halfsize defines the width + sizeX = halfSize; + sizeY = halfSize/design_aspect_ratio; + } else { + // halfsize defines the height + sizeX = halfSize * design_aspect_ratio; + sizeY = halfSize; + } + + frustum.x2 = sizeX; + frustum.x1 = -frustum.x2; + frustum.y2 = sizeY; + frustum.y1 = -frustum.y2; + frustum.camnear = -camfar; + frustum.camfar = camfar; +} + + void RAS_FramingManager:: ComputeBestFitViewRect( @@ -227,5 +260,73 @@ ComputeFrustum( } } + void +RAS_FramingManager:: + ComputeOrtho( + const RAS_FrameSettings &settings, + const RAS_Rect &availableViewport, + const RAS_Rect &viewport, + const float scale, + const float camnear, + const float camfar, + RAS_FrameFrustum &frustum + ) +{ + RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); + + const float design_width = float(settings.DesignAspectWidth()); + const float design_height = float(settings.DesignAspectHeight()); + + float design_aspect_ratio = float(1); + + if (design_height == float(0)) { + // well this is ill defined + // lets just scale the thing + type = RAS_FrameSettings::e_frame_scale; + } else { + design_aspect_ratio = design_width/design_height; + } + + + ComputeDefaultOrtho( + camnear, + camfar, + scale, + design_aspect_ratio, + frustum + ); + + switch (type) { + + case RAS_FrameSettings::e_frame_extend: + { + RAS_Rect vt; + ComputeBestFitViewRect( + availableViewport, + design_aspect_ratio, + vt + ); + + // now scale the calculated frustum by the difference + // between vt and the viewport in each axis. + // These are always > 1 + + float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); + float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); + + frustum.x1 *= x_scale; + frustum.x2 *= x_scale; + frustum.y1 *= y_scale; + frustum.y2 *= y_scale; + + break; + } + case RAS_FrameSettings::e_frame_scale : + case RAS_FrameSettings::e_frame_bars: + default : + break; + } + +} diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h index 0a226ac30f9..4398e2d00c3 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.h +++ b/source/gameengine/Rasterizer/RAS_FramingManager.h @@ -207,6 +207,18 @@ public : * and camera description */ + static + void + ComputeOrtho( + const RAS_FrameSettings &settings, + const RAS_Rect &availableViewport, + const RAS_Rect &viewport, + const float scale, + const float camnear, + const float camfar, + RAS_FrameFrustum &frustum + ); + static void ComputeFrustum( @@ -229,6 +241,16 @@ public : RAS_FrameFrustum & frustum ); + static + void + ComputeDefaultOrtho( + const float camnear, + const float camfar, + const float scale, + const float design_aspect_ratio, + RAS_FrameFrustum & frustum + ); + private : static diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 96472b112d6..dc8c3c1ebf8 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -250,9 +250,9 @@ public: * Sets the modelview matrix. */ virtual void SetViewMatrix(const MT_Matrix4x4 & mat, - const MT_Vector3& campos, - const MT_Point3 &camLoc, - const MT_Quaternion &camOrientQuat)=0; + const MT_Matrix3x3 & ori, + const MT_Point3 & pos, + bool perspective)=0; /** */ virtual const MT_Point3& GetCameraPosition()=0; @@ -326,6 +326,26 @@ public: float focallength = 0.0f, bool perspective = true )=0; + + /** + * Generates a orthographic projection matrix from the specified frustum. + * @param left the left clipping plane + * @param right the right clipping plane + * @param bottom the bottom clipping plane + * @param top the top clipping plane + * @param frustnear the near clipping plane + * @param frustfar the far clipping plane + * @return a 4x4 matrix representing the projection transform. + */ + virtual MT_Matrix4x4 GetOrthoMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar + )=0; + /** * Sets the specular color component of the lighting equation. */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index bf50cde2280..3fe5e26abc3 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -921,17 +921,40 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( return result; } +MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar +){ + MT_Matrix4x4 result; + double mat[16]; + + // stereo is meaning less for orthographic, disable it + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(left, right, bottom, top, frustnear, frustfar); + + glGetDoublev(GL_PROJECTION_MATRIX, mat); + result.setValue(mat); + + return result; +} + // next arguments probably contain redundant info, for later... -void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos, - const MT_Point3 &, const MT_Quaternion &camOrientQuat) +void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, + const MT_Matrix3x3 & camOrientMat3x3, + const MT_Point3 & pos, + bool perspective) { m_viewmatrix = mat; // correction for stereo - if(Stereo()) + if(Stereo() && perspective) { - MT_Matrix3x3 camOrientMat3x3(camOrientQuat); MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention MT_Vector3 unitViewupVec(0.0, 0.0, 1.0); MT_Vector3 viewDir, viewupVec; @@ -977,7 +1000,7 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vecto glMatrixMode(GL_MODELVIEW); glLoadMatrixd(glviewmat); - m_campos = campos; + m_campos = pos; } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 6013946fadf..4d51a477d48 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -163,9 +163,9 @@ public: virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat); virtual void SetViewMatrix( const MT_Matrix4x4 & mat, - const MT_Vector3& campos, - const MT_Point3 &camLoc, - const MT_Quaternion &camOrientQuat + const MT_Matrix3x3 & ori, + const MT_Point3 & pos, + bool perspective ); virtual const MT_Point3& GetCameraPosition(); @@ -216,6 +216,15 @@ public: bool perspective ); + virtual MT_Matrix4x4 GetOrthoMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar + ); + virtual void SetSpecularity( float specX, float specY, diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 9a3c4fea70e..f1df47af373 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -181,7 +181,6 @@ void ImageRender::Render() frustrum.camnear = -mirrorOffset[2]; frustrum.camfar = -mirrorOffset[2]+m_clip; } - const float ortho = 100.0; const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); // The screen area that ImageViewport will copy is also the rendering zone @@ -214,37 +213,44 @@ void ImageRender::Render() float farfrust = m_camera->GetCameraFar(); float aspect_ratio = 1.0f; Scene *blenderScene = m_scene->GetBlenderScene(); + MT_Matrix4x4 projmat; - if (orthographic) { - lens *= ortho; - nearfrust = (nearfrust + 1.0)*ortho; - farfrust *= ortho; - } // compute the aspect ratio from frame blender scene settings so that render to texture // works the same in Blender and in Blender player if (blenderScene->r.ysch != 0) - aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); + aspect_ratio = float(blenderScene->r.xsch*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp); - RAS_FramingManager::ComputeDefaultFrustum( - nearfrust, - farfrust, - lens, - aspect_ratio, - frustrum); - - MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( - frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + if (orthographic) { + RAS_FramingManager::ComputeDefaultOrtho( + nearfrust, + farfrust, + m_camera->GetScale(), + aspect_ratio, + frustrum + ); + + projmat = m_rasterizer->GetOrthoMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + } else + { + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + } m_camera->SetProjectionMatrix(projmat); } MT_Transform camtrans(m_camera->GetWorldToCamera()); - if (!m_camera->GetCameraData()->m_perspective) - camtrans.getOrigin()[2] *= ortho; MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), - m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldOrientation(), m_camera->NodeGetWorldPosition(), m_camera->GetCameraData()->m_perspective); m_camera->SetModelviewMatrix(viewmat); // restore the stereo mode now that the matrix is computed m_rasterizer->SetStereoMode(stereomode); From af1c25c9d0b69a268a2ac824b8ab0e3032d5f110 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 26 Apr 2009 13:26:18 +0000 Subject: [PATCH 068/444] Fixed shrinkwrap bug: shrinkwrap wasn't using the updated coordinates/normals of vertexs when the DerivedMesh had been modified by a previous modifier. before revision 19744, users would only notice a strange behaviour of shrinkwrap in projection mode (because it was using the wrong normals) (jpbouza reported this) after revision 19744 this bug was "bigger". Anyway it's fixed now :) --- source/blender/blenkernel/intern/modifier.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 10bcb2e09f2..c9f6bc18abd 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -7915,7 +7915,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived else if(ob->type==OB_LATTICE) dm = NULL; else return; - if(dm != NULL && (dataMask & CD_MVERT)) + if(dm != NULL && (dataMask & (1<type==OB_LATTICE) dm = NULL; else return; - if(dm != NULL && (dataMask & CD_MVERT)) + if(dm != NULL && (dataMask & (1< Date: Sun, 26 Apr 2009 18:38:16 +0000 Subject: [PATCH 069/444] Missing end-of-line. --- source/blender/blenkernel/intern/particle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 3fea9e44acb..0ebdcdf58e0 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3974,4 +3974,4 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] VECADDFAC(center, bb->vec, xvec, bb->offset[0]); VECADDFAC(center, center, yvec, bb->offset[1]); -} \ No newline at end of file +} From ce3aabb4e78b16f570db9268b4a71b762d36b290 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 26 Apr 2009 21:23:59 +0000 Subject: [PATCH 070/444] Rewind own commit that aimed to make converting meshes faster at startup. Some files probably need to have UV's welded so better do this even though it seems inefficient. --- source/gameengine/Rasterizer/RAS_TexVert.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 210addfb927..60b00be5705 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -113,19 +113,18 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent) tangent.getValue(m_tangent); } + // compare two vertices, and return TRUE if both are almost identical (they can be shared) -#define _VEC_EQUAL3(_v1, _v2) (_v1[0]==_v2[0] && _v1[1]==_v2[1] && _v1[2]==_v2[2]) -#define _VEC_EQUAL2(_v1, _v2) (_v1[0]==_v2[0] && _v1[1]==_v2[1]) bool RAS_TexVert::closeTo(const RAS_TexVert* other) { return (m_flag == other->m_flag && m_rgba == other->m_rgba && - _VEC_EQUAL3(m_normal, other->m_normal) && - _VEC_EQUAL3(m_tangent, other->m_tangent) && - _VEC_EQUAL2(m_uv1, other->m_uv1) && - _VEC_EQUAL2(m_uv2, other->m_uv2) // p -- - /* we know the verts must be shared so dont need to check this */ - /*&& FAST_MT_fuzzyEqual3(m_localxyz, other->m_localxyz)*/) ; + MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) && + MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) && + MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) && + MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* && + MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/) ; + /* dont bother comparing m_localxyz since we know there from the same vert */ } short RAS_TexVert::getFlag() const From 7a042dcc3a0091fd351b116414e432623daefa6e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 26 Apr 2009 21:30:42 +0000 Subject: [PATCH 071/444] [#18623] projection paint alpha paintingacts as 1bit -- 2.49RC1 Also fixed... - smear with alpha channels (had to disabled blending modes). - using uninitialized memory in a few cases. - negative index in an array bug. --- source/blender/src/imagepaint.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 4d6c0898bce..478debfb922 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -707,7 +707,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w); } - ibuf = BKE_image_get_ibuf((Image *)tf->tpage, NULL); /* TODO - this may be slow, the only way around it is to have an ibuf index per face */ + ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */ if (!ibuf) return 0; if (interp) { @@ -1362,7 +1362,7 @@ float project_paint_uvpixel_mask( ImBuf *ibuf_other; const MTFace *tf_other = ps->dm_mtface_mask + face_index; - if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL))) { + if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) { /* BKE_image_get_ibuf - TODO - this may be slow */ unsigned char rgba_ub[4]; float rgba_f[4]; @@ -1518,7 +1518,7 @@ static ProjPixel *project_paint_uvpixel_init( ImBuf *ibuf_other; const MTFace *tf_other = ps->dm_mtface_clone + face_index; - if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL))) { + if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) { /* BKE_image_get_ibuf - TODO - this may be slow */ if (ibuf->rect_float) { @@ -1969,7 +1969,6 @@ static void project_bucket_clip_face( const int flip = ((SIDE_OF_LINE(v1coSS, v2coSS, v3coSS) > 0.0f) != (SIDE_OF_LINE(uv1co, uv2co, uv3co) > 0.0f)); float bucket_bounds_ss[4][2]; - float w[3]; /* get the UV space bounding box */ inside_bucket_flag |= BLI_in_rctf(bucket_bounds, v1coSS[0], v1coSS[1]); @@ -2040,6 +2039,7 @@ static void project_bucket_clip_face( /* Maximum possible 6 intersections when using a rectangle and triangle */ float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */ float v1_clipSS[2], v2_clipSS[2]; + float w[3]; /* calc center*/ float cent[2] = {0.0f, 0.0f}; @@ -2082,6 +2082,7 @@ static void project_bucket_clip_face( if ((*tot) < 3) { /* no intersections to speak of */ *tot = 0; + return; } /* now we have all points we need, collect their angles and sort them clockwise */ @@ -2116,7 +2117,6 @@ static void project_bucket_clip_face( if (flip) qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort_flip); else qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort); - /* remove doubles */ /* first/last check */ if (fabs(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE && fabs(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) { @@ -3030,7 +3030,7 @@ static void project_paint_begin(ProjPaintState *ps, short mval[2]) ps->buckets_x = (int)(ps->screen_width / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV)); ps->buckets_y = (int)(ps->screen_height / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV)); - printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); + /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */ /* really high values could cause problems since it has to allocate a few * (ps->buckets_x*ps->buckets_y) sized arrays */ @@ -3203,7 +3203,7 @@ static void project_paint_begin(ProjPaintState *ps, short mval[2]) image_index = BLI_linklist_index(image_LinkList, tf->tpage); - if (image_index==-1 && BKE_image_get_ibuf((Image *)tf->tpage, NULL)) { /* MemArena dosnt have an append func */ + if (image_index==-1 && BKE_image_get_ibuf(tf->tpage, NULL)) { /* MemArena dosnt have an append func */ BLI_linklist_append(&image_LinkList, tf->tpage); image_index = ps->image_tot; ps->image_tot++; @@ -3225,10 +3225,10 @@ static void project_paint_begin(ProjPaintState *ps, short mval[2]) for (node= image_LinkList, i=0; node; node= node->next, i++, projIma++) { projIma->ima = node->link; - // calloced - projIma->touch = 0; + projIma->touch = 0; projIma->ibuf = BKE_image_get_ibuf(projIma->ima, NULL); projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); - // calloced - memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); + memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); } /* we have built the array, discard the linked list */ @@ -3378,7 +3378,7 @@ static void partial_redraw_array_init(ImagePaintPartialRedraw *pr) static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot) { - int touch; + int touch= 0; while (tot--) { pr->x1 = MIN2(pr->x1, pr_other->x1); pr->y1 = MIN2(pr->y1, pr_other->y1); @@ -3506,6 +3506,7 @@ static void blend_color_mix(unsigned char *cp, const unsigned char *cp1, const u cp[0]= (mfac*cp1[0]+fac*cp2[0])/255; cp[1]= (mfac*cp1[1]+fac*cp2[1])/255; cp[2]= (mfac*cp1[2]+fac*cp2[2])/255; + cp[3]= (mfac*cp1[3]+fac*cp2[3])/255; } static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2, const float fac) @@ -3514,6 +3515,7 @@ static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2, cp[0]= mfac*cp1[0] + fac*cp2[0]; cp[1]= mfac*cp1[1] + fac*cp2[1]; cp[2]= mfac*cp1[2] + fac*cp2[2]; + cp[3]= mfac*cp1[3] + fac*cp2[3]; } static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask) @@ -3550,8 +3552,8 @@ static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, floa if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0) return; - - ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); + /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ + blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha*mask*255)); BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena); } @@ -3564,7 +3566,8 @@ static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, fl return; IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_smear, projPixel->pixel.f_pt); - ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); + /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ + blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, rgba_smear, (rgba_ub), (int)(alpha*mask*255)); BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena); } @@ -4325,7 +4328,7 @@ static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, sho ) { ImBuf *ibuf; - newimage = (Image*)((s->me->mtface+newfaceindex)->tpage); + newimage = (s->me->mtface+newfaceindex)->tpage; ibuf= BKE_image_get_ibuf(newimage, G.sima?&G.sima->iuser:NULL); if(ibuf && ibuf->rect) From 310356a732d9460bd647c8e5b465bed6ae037e89 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 26 Apr 2009 21:33:22 +0000 Subject: [PATCH 072/444] Shrinkwrap fix (before I only fixed normal projection) nearest surface + nearest vertex fixed now --- source/blender/blenkernel/intern/shrinkwrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 6784f014efa..69ce9f3d5cd 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -191,7 +191,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM calc.vgroup = get_named_vertexgroup_num(calc.ob, smd->vgroup_name); - if(dm != NULL) + if(dm != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { //Setup arrays to get vertexs positions, normals and deform weights calc.vert = dm->getVertDataArray(dm, CD_MVERT); From f64265d714e0497a3a78423334e2248244d9c18f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 27 Apr 2009 00:49:01 +0000 Subject: [PATCH 073/444] Bugfix #18603: Clear User Transform does not work -- 2.49RC1 Modified the behaviour of Clear User Transform so that when there's no action, Clear User Transform now resets the entire pose to the rest pose. However, when there is an action, the pose on selected bones gets cleared to the pose defined in the action, not the rest pose. --- source/blender/src/poseobject.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index c081bcbcb45..551aca0cc91 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -1748,18 +1748,25 @@ void pose_clear_user_transforms (void) if (ob->pose == NULL) return; - /* find selected bones */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) { - /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */ - pchan->bone->flag &= ~BONE_UNKEYED; + /* if the object has an action, restore pose to the pose defined by the action by clearing pose on selected bones */ + if (ob->action) { + /* find selected bones */ + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) { + /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */ + pchan->bone->flag &= ~BONE_UNKEYED; + } } + + /* clear pose locking flag + * - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared + */ + ob->pose->flag |= POSE_DO_UNLOCK; + } + else { + /* no action, so restore entire pose to rest pose (cannot restore only selected bones) */ + rest_pose(ob->pose); } - - /* clear pose locking flag - * - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared - */ - ob->pose->flag |= POSE_DO_UNLOCK; DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); BIF_undo_push("Clear User Transform"); From d2ff190dfbe5606e38c515ecbd43778999a00507 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Mon, 27 Apr 2009 04:21:05 +0000 Subject: [PATCH 074/444] Lower the vertex welding threshold, for removing duplicate/nearby vertices for soft bodies (this broke susanne softbody regression test) --- source/gameengine/Converter/KX_ConvertActuators.cpp | 2 +- source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index eb2d0a1c4b1..73d35a78ded 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -38,7 +38,7 @@ #include "KX_BlenderSceneConverter.h" #include "KX_ConvertActuators.h" - +#include "SND_Scene.h" // Actuators //SCA logiclibrary native logicbricks #include "SCA_PropertyActuator.h" diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 700c5f304e7..be3b758a14b 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -905,7 +905,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, // Soft bodies require welding. Only avoid remove doubles for non-soft bodies! if (objprop->m_softbody) - shapeInfo->setVertexWeldingThreshold1(0.01f); //todo: expose this to the UI + shapeInfo->setVertexWeldingThreshold1(0.0001f); //todo: expose this to the UI bm = shapeInfo->CreateBulletShape(); //no moving concave meshes, so don't bother calculating inertia diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 0c26a6a7b3b..9e67e39b2a5 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -34,7 +34,7 @@ #include "KX_Scene.h" #include "MT_assert.h" - +#include "SND_Scene.h" #include "KX_KetsjiEngine.h" #include "KX_BlenderMaterial.h" #include "RAS_IPolygonMaterial.h" diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 83a4692f815..dbba7723cc5 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -43,7 +43,7 @@ #include "SG_IObject.h" #include "SCA_IScene.h" #include "MT_Transform.h" -#include "SND_Scene.h" + #include "RAS_FramingManager.h" #include "RAS_Rect.h" From 5d1d6ad4d19cf2b76abb9ed323027f194a65e2a0 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Mon, 27 Apr 2009 05:06:24 +0000 Subject: [PATCH 075/444] Don't always activate a Bullet rigid body If you want to keep a rigid body awake, please use the GUI 'No Sleeping' option for Rigid bodies. --- source/gameengine/Ketsji/KX_BulletPhysicsController.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index 831f9241fec..bc5a64d36a8 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -438,8 +438,6 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) { - if (GetRigidBody()) - GetRigidBody()->activate(true); if (!m_bDyna) { From 9c3d628082035c8b7ff49aa6e72898345a683584 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 27 Apr 2009 07:07:22 +0000 Subject: [PATCH 076/444] [#18616] Scons+MinGW compiling error with gaming engine enabled. Attempt to fix building in windows with mingw --- source/creator/creator.c | 6 +++--- source/gameengine/Expressions/InputParser.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 74e899d2d14..a1531fd7180 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -538,10 +538,10 @@ int main(int argc, char **argv) BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */ #ifndef DISABLE_SDL -#ifndef WIN32 - setenv("SDL_VIDEODRIVER", "dummy", 1); /* initializing the video driver can cause crashes on some systems - Campbell */ -#else +#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS) _putenv_s("SDL_VIDEODRIVER", "dummy"); +#else + setenv("SDL_VIDEODRIVER", "dummy", 1); /* initializing the video driver can cause crashes on some systems - Campbell */ #endif #ifdef __linux__ /* On linux the default SDL driver dma often would not play diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index 66075dd8d42..834dff7af89 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -38,7 +38,7 @@ // cool things like (IF(LOD==1,CCurvedValue,IF(LOD==2,CCurvedValue2)) etc... #include "IfExpr.h" -#if defined(WIN32) || defined(WIN64) +#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS) #define strcasecmp _stricmp #ifndef strtoll From 22df42cdecbf29d886ea6cf81810ecbc575522e4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 27 Apr 2009 11:49:40 +0000 Subject: [PATCH 077/444] Fix for bug #18032: AAO pixel cache + refraction artifacts, the pixel cache can only be used for the first hit. --- source/blender/render/intern/source/occlusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 494feb96c18..f9301bc0805 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1632,7 +1632,7 @@ void sample_occ(Render *re, ShadeInput *shi) sample_occ_surface(shi); } /* try to get result from the cache if possible */ - else if(!sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) { + else if(shi->depth!=0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) { /* no luck, let's sample the occlusion */ exclude.obi= shi->obi - re->objectinstance; exclude.facenr= shi->vlr->index; From e2582ba6c1eb075a3971c7a51e4873a954120c47 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 27 Apr 2009 12:18:18 +0000 Subject: [PATCH 078/444] Fix for bug #18610: in the Game menu enabling "Record Game Physics to IPO" made "Generate Display Lists" hidden (these work fine together). --- source/blender/src/header_info.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 612836c86e9..71abed0d806 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -1720,15 +1720,15 @@ static uiBlock *info_gamemenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Enable All Frames", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES, ""); } - if(G.fileflags & G_FILE_GAME_TO_IPO) { - uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Record Game Physics to IPO", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, ""); - } else { - if(G.fileflags & G_FILE_DISPLAY_LISTS) { uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Generate Display Lists", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_DISPLAY_LISTS, ""); } else { uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Generate Display Lists", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_DISPLAY_LISTS, ""); } + + if(G.fileflags & G_FILE_GAME_TO_IPO) { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Record Game Physics to IPO", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, ""); + } else { uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Record Game Physics to IPO", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, ""); } From 369c8b8055da5f43f52158fc629b6bb4e112d8a8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 27 Apr 2009 14:22:02 +0000 Subject: [PATCH 079/444] [#18628] stuck triangle when projection painting -- 2.49RC1 Increasing the tolerance when making intersection comparisons fixed this. There is also a problem where a pixel aligned quad would get a diagonal line down the face. offset the pixel locations a little to avoid this (crappy I know but will fix most cases). --- source/blender/src/imagepaint.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 478debfb922..89dff67585e 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -186,7 +186,7 @@ typedef struct ImagePaintPartialRedraw { // #define PROJ_BUCKET_CLONE_INIT 1<<1 /* used for testing doubles, if a point is on a line etc */ -#define PROJ_GEOM_TOLERANCE 0.0002f +#define PROJ_GEOM_TOLERANCE 0.00075f /* vert flags */ #define PROJ_VERT_CULL 1 @@ -2315,9 +2315,20 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel * this is done so we can avoid offseting all the pixels by 0.5 which causes * problems when wrapping negative coords */ - xhalfpx = 0.5f / ibuf_xf; - yhalfpx = 0.5f / ibuf_yf; + xhalfpx = (0.5f+ (PROJ_GEOM_TOLERANCE/3.0f) ) / ibuf_xf; + yhalfpx = (0.5f+ (PROJ_GEOM_TOLERANCE/4.0f) ) / ibuf_yf; + /* Note about (PROJ_GEOM_TOLERANCE/x) above... + Needed to add this offset since UV coords are often quads aligned to pixels. + In this case pixels can be exactly between 2 triangles causing nasty + artifacts. + + This workaround can be removed and painting will still work on most cases + but since the first thing most people try is painting onto a quad- better make it work. + */ + + + tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx; tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx; From c56ee09c48b4d29dabe1c7daa2133777c27944f6 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 27 Apr 2009 16:40:26 +0000 Subject: [PATCH 080/444] BGE bug #18624: Collision detection fails on parented objects. Partial fix, parented shape now moves with the parent but still the parent near detector detects the child only in the zone where it was parented. --- source/gameengine/Ketsji/KX_BulletPhysicsController.cpp | 3 +++ source/gameengine/Ketsji/KX_BulletPhysicsController.h | 1 + 2 files changed, 4 insertions(+) diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index bc5a64d36a8..891317e64a1 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -361,6 +361,7 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost) btBroadphaseProxy* handle = body->getBroadphaseHandle(); m_savedCollisionFlags = body->getCollisionFlags(); m_savedMass = GetMass(); + m_savedDyna = m_bDyna; m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; m_savedCollisionFilterMask = handle->m_collisionFilterMask; m_savedActivationState = body->getActivationState(); @@ -370,6 +371,7 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost) btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), btBroadphaseProxy::StaticFilter, btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + m_bDyna = false; } } @@ -384,6 +386,7 @@ void KX_BulletPhysicsController::RestoreDynamics() m_savedCollisionFilterGroup, m_savedCollisionFilterMask); body->forceActivationState(m_savedActivationState); + m_bDyna = m_savedDyna; } } diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index b39098206f7..2174f0db499 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -13,6 +13,7 @@ private: short int m_savedCollisionFilterGroup; short int m_savedCollisionFilterMask; MT_Scalar m_savedMass; + bool m_savedDyna; btCollisionShape* m_bulletChildShape; public: From 352eaccd5d991ad8966d686ae0954c7a0b03345c Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 27 Apr 2009 16:44:02 +0000 Subject: [PATCH 081/444] BGE: Add soft body welding parameter to the Advanced Settings panel. The values are very small so I chose to use logarithmic scale. Should be fine, it's an advanced setting after all. --- source/blender/blenkernel/intern/bullet.c | 1 + source/blender/makesdna/DNA_object_force.h | 2 +- source/blender/src/buttons_logic.c | 20 +++++++++++++------ .../Converter/BL_BlenderDataConversion.cpp | 5 +++++ .../Ketsji/KX_ConvertPhysicsObject.h | 1 + .../Ketsji/KX_ConvertPhysicsObjects.cpp | 4 +++- source/gameengine/Ketsji/KX_GameObject.cpp | 8 ++++---- 7 files changed, 29 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/bullet.c b/source/blender/blenkernel/intern/bullet.c index b389f8c0536..657507ee048 100644 --- a/source/blender/blenkernel/intern/bullet.c +++ b/source/blender/blenkernel/intern/bullet.c @@ -82,6 +82,7 @@ BulletSoftBody *bsbNew(void) bsb->collisionflags = 0; //bsb->collisionflags = OB_BSB_COL_CL_RS + OB_BSB_COL_CL_SS; bsb->numclusteriterations = 64; + bsb->welding = -4.f; return bsb; } diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 49435000820..73dd8b28d15 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -119,7 +119,7 @@ typedef struct BulletSoftBody { float kAHR; /* Anchors hardness [0,1] */ int collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ int numclusteriterations; /* number of iterations to refine collision clusters*/ - + float welding; /* welding limit to remove duplicate/nearby vertices, 0.0000001..0.01 */ } BulletSoftBody; /* BulletSoftBody.flag */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 0a7bbf656b3..8b6cc457994 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3073,19 +3073,19 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) { uiBlock *block; Object *ob = arg_ob; - short yco = 20, xco = 0; + short yco, xco = 0; block= uiNewBlock(&curarea->uiblocks, "advanced_bullet_options", UI_EMBOSS, UI_HELV, curarea->win); /* use this for a fake extra empy space around the buttons */ if (ob->gameflag & OB_SOFT_BODY) { - uiDefBut(block, LABEL, 0, "", -10, -10, 380, 60, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "", -10, -10, 380, 80, NULL, 0, 0, 0, 0, ""); if (ob->bsoft) { - + yco = 40; uiBlockBeginAlign(block); uiDefButBitI(block, TOG, OB_BSB_COL_CL_RS, 0, "Cluster Collision RS", xco, yco, 180, 19, &ob->bsoft->collisionflags, 0, 0, 0, 0, @@ -3102,6 +3102,14 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) xco+=180, yco, 180, 19, &ob->bsoft->piterations, 0, 10, 0, 0, "Position solver iterations"); uiBlockEndAlign(block); + yco -= 20; + xco = 0; + if (ob->bsoft->welding == 0.f) + ob->bsoft->welding = -4.f; + + uiDefButF(block, NUMSLI, 0, "Welding(10^) ", + xco, yco, 360, 19, &ob->bsoft->welding, -7.f, -2.f, 10, 2, + "Threshold to remove duplicate/nearby vertices. Displayed in logarithmic scale for readability: linear values from 0.0000001 to 0.01"); /* //too complex tweaking, disable for now @@ -3131,7 +3139,7 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) if (ob->gameflag & OB_DYNAMIC) { - yco = 100; + yco = 80; uiDefBut(block, LABEL, 0, "", -10, -10, 380, 120, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); if (ob->margin < 0.001f) @@ -3173,7 +3181,7 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) uiBlockEndAlign(block); - uiDefBut(block, LABEL, 0, "Clamp Velocity (zero disables)", xco, yco, 180*2, 19, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Clamp Velocity (0=disabled)", xco, yco, 180*2, 19, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); @@ -3215,7 +3223,7 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) } else { - + yco = 20; uiDefBut(block, LABEL, 0, "", -10, -10, 380, 60, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, 0, "Margin", xco, yco, 180, 19, &ob->margin, 0.0, 1.0, 1, 0, diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 962af7cc4c9..b330515c0d3 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1418,6 +1418,10 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */ objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ + if (blenderobject->bsoft->welding == 0.f) + objprop.m_soft_welding = 0.0001f; /* welding */ + else + objprop.m_soft_welding = pow(10.f,blenderobject->bsoft->welding); /* welding */ } else { @@ -1457,6 +1461,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_kAHR= 0.7f; objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS; objprop.m_soft_numclusteriterations= 16; + objprop.m_soft_welding = 0.0001f; } } diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 3534500e619..40c715974f9 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -124,6 +124,7 @@ struct KX_ObjectProperties float m_soft_kAHR; /* Anchors hardness [0,1] */ int m_soft_collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ int m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/ + float m_soft_welding; /* threshold to remove duplicate/nearby vertices */ ///////////////////////// diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index be3b758a14b..1943c436258 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -905,7 +905,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, // Soft bodies require welding. Only avoid remove doubles for non-soft bodies! if (objprop->m_softbody) - shapeInfo->setVertexWeldingThreshold1(0.0001f); //todo: expose this to the UI + { + shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI + } bm = shapeInfo->CreateBulletShape(); //no moving concave meshes, so don't bother calculating inertia diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 297d3048a3a..53c2d6c7937 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -462,11 +462,11 @@ void KX_GameObject::RemoveMeshes() void KX_GameObject::UpdateTransform() { - if (m_pPhysicsController1) - // only update the transform of static object, dynamic object are handled differently - // note that for bullet, this does not even update the transform of static object + // HACK: saves function call for dynamic object, they are handled differently + if (m_pPhysicsController1 && !m_pPhysicsController1->IsDyna()) + // Note that for Bullet, this does not even update the transform of static object // but merely sets there collision flag to "kinematic" because the synchronization is - // done differently during physics simulation + // done during physics simulation m_pPhysicsController1->SetSumoTransform(true); if (m_pGraphicController) // update the culling tree From dc664e3925d97f1a8bef8c85d5a47941e0866ad4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 27 Apr 2009 17:53:41 +0000 Subject: [PATCH 082/444] TexVert sharing was disabled for flat faces, this is silly since a building or any other model with flat faces will often be able to share texverts. Simple testcase with a subdivided cube used 1/3 as many texverts and spend half as much time in the rasterizer while profiling. --- source/gameengine/Rasterizer/RAS_MeshObject.cpp | 4 ++-- source/gameengine/Rasterizer/RAS_TexVert.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 5625b172913..278aa9c75e2 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -304,7 +304,7 @@ void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i, slot = mmat->m_baseslot; darray = slot->CurrentDisplayArray(); - if(!flat) { + { /* Shared Vertex! */ /* find vertices shared between faces, with the restriction * that they exist in the same display array, and have the * same uv coordinate etc */ @@ -332,7 +332,7 @@ void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i, slot->AddPolygonVertex(offset); poly->SetVertexOffset(i, offset); - if(!flat) { + { /* Shared Vertex! */ SharedVertex shared; shared.m_darray = darray; shared.m_offset = offset; diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 60b00be5705..8eee24ac7f0 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -117,7 +117,9 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent) // compare two vertices, and return TRUE if both are almost identical (they can be shared) bool RAS_TexVert::closeTo(const RAS_TexVert* other) { - return (m_flag == other->m_flag && + return ( + /* m_flag == other->m_flag && */ + /* at the moment the face only stores the smooth/flat setting so dont bother comparing it */ m_rgba == other->m_rgba && MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) && MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) && From fa826774a3f2a2db67466d38ed26fbdb845e37a4 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 27 Apr 2009 22:14:51 +0000 Subject: [PATCH 083/444] CMake files changes for FFMpeg update This was broken since last month !!! --- CMakeLists.txt | 2 +- source/creator/CMakeLists.txt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b7f3999e82..1340ec0f3b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,7 +285,7 @@ IF(WIN32) SET(FFMPEG ${LIBDIR}/ffmpeg) SET(FFMPEG_INC ${FFMPEG}/include) - SET(FFMPEG_LIB avcodec-51 avformat-52 avdevice-52 avutil-49 swscale-0) + SET(FFMPEG_LIB avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0) SET(FFMPEG_LIBPATH ${FFMPEG}/lib) IF(CMAKE_CL_64) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a20913bc714..f31a68365fb 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -173,14 +173,14 @@ IF(WIN32) ADD_CUSTOM_COMMAND(TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avcodec-51.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avcodec-52.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avformat-52.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avdevice-52.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avutil-49.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avutil-50.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaac-0.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaad-0.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaad-2.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libmp3lame-0.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libx264-59.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libx264-67.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\swscale-0.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\xvidcore.dll\" \"${TARGETDIR}\\\" ) From d4f8b416e92ec5b71bddfa688e9a63ea86510721 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 27 Apr 2009 22:21:42 +0000 Subject: [PATCH 084/444] BGE soft body: change welding option to disable welding check by default: speeds up shape conversion. This is fine if the object has no duplicate vertices. Otherwise, bullet will be extremely slow and you can either set some welding or remove duplicates in the mesh. Welding is now displayed in linear scale: 0.0 -> 0.01, no need to use logarithmic scale ;-). Fix a bug with Bullet by which vertex array for soft body must have 3xfloat stride. --- source/blender/blenkernel/intern/bullet.c | 2 +- source/blender/makesdna/DNA_object_force.h | 2 +- source/blender/src/buttons_logic.c | 9 +-- .../Converter/BL_BlenderDataConversion.cpp | 7 +-- .../Physics/Bullet/CcdPhysicsController.cpp | 60 ++++++++++--------- .../Physics/Bullet/CcdPhysicsController.h | 10 +--- 6 files changed, 43 insertions(+), 47 deletions(-) diff --git a/source/blender/blenkernel/intern/bullet.c b/source/blender/blenkernel/intern/bullet.c index 657507ee048..44e8ed1f08c 100644 --- a/source/blender/blenkernel/intern/bullet.c +++ b/source/blender/blenkernel/intern/bullet.c @@ -82,7 +82,7 @@ BulletSoftBody *bsbNew(void) bsb->collisionflags = 0; //bsb->collisionflags = OB_BSB_COL_CL_RS + OB_BSB_COL_CL_SS; bsb->numclusteriterations = 64; - bsb->welding = -4.f; + bsb->welding = 0.f; return bsb; } diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 73dd8b28d15..e8e865a533c 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -119,7 +119,7 @@ typedef struct BulletSoftBody { float kAHR; /* Anchors hardness [0,1] */ int collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ int numclusteriterations; /* number of iterations to refine collision clusters*/ - float welding; /* welding limit to remove duplicate/nearby vertices, 0.0000001..0.01 */ + float welding; /* welding limit to remove duplicate/nearby vertices, 0.0..0.01 */ } BulletSoftBody; /* BulletSoftBody.flag */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 8b6cc457994..eb65dcc6785 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3104,12 +3104,9 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) uiBlockEndAlign(block); yco -= 20; xco = 0; - if (ob->bsoft->welding == 0.f) - ob->bsoft->welding = -4.f; - - uiDefButF(block, NUMSLI, 0, "Welding(10^) ", - xco, yco, 360, 19, &ob->bsoft->welding, -7.f, -2.f, 10, 2, - "Threshold to remove duplicate/nearby vertices. Displayed in logarithmic scale for readability: linear values from 0.0000001 to 0.01"); + uiDefButF(block, NUMSLI, 0, "Welding ", + xco, yco, 360, 19, &ob->bsoft->welding, 0.f, 0.01f, 10, 4, + "Welding threshold: distance between nearby vertices to be considered equal => set to 0.0 to disable welding test and speed up scene loading (ok if the mesh has no duplicates)"); /* //too complex tweaking, disable for now diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b330515c0d3..ef3efbcec87 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1418,10 +1418,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */ objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ - if (blenderobject->bsoft->welding == 0.f) - objprop.m_soft_welding = 0.0001f; /* welding */ - else - objprop.m_soft_welding = pow(10.f,blenderobject->bsoft->welding); /* welding */ + objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */ } else { @@ -1461,7 +1458,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_kAHR= 0.7f; objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS; objprop.m_soft_numclusteriterations= 16; - objprop.m_soft_welding = 0.0001f; + objprop.m_soft_welding = 0.f; } } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index b944ae085ba..b171fbb3c34 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1368,9 +1368,9 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo } } - m_vertexArray.resize(tot_bt_verts); + m_vertexArray.resize(tot_bt_verts*3); - btVector3 *bt= &m_vertexArray[0]; + btScalar *bt= &m_vertexArray[0]; for (int p2=0; p2getXYZ(); vert_tag_array[orig_index]= false; - bt->setX(vtx[0]); bt->setY(vtx[1]); bt->setZ(vtx[2]); - bt++; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; } } } @@ -1421,11 +1422,11 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo } } - m_vertexArray.resize(tot_bt_verts); + m_vertexArray.resize(tot_bt_verts*3); m_polygonIndexArray.resize(tot_bt_tris); m_triFaceArray.resize(tot_bt_tris*3); - btVector3 *bt= &m_vertexArray[0]; + btScalar *bt= &m_vertexArray[0]; int *poly_index_pt= &m_polygonIndexArray[0]; int *tri_pt= &m_triFaceArray[0]; @@ -1459,20 +1460,23 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo if (vert_tag_array[i1]==true) { /* *** v1 *** */ vert_tag_array[i1]= false; vtx = v1->getXYZ(); - bt->setX(vtx[0]); bt->setY( vtx[1]); bt->setZ(vtx[2]); - bt++; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; } if (vert_tag_array[i2]==true) { /* *** v2 *** */ vert_tag_array[i2]= false; vtx = v2->getXYZ(); - bt->setX(vtx[0]); bt->setY(vtx[1]); bt->setZ(vtx[2]); - bt++; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; } if (vert_tag_array[i3]==true) { /* *** v3 *** */ vert_tag_array[i3]= false; vtx = v3->getXYZ(); - bt->setX(vtx[0]); bt->setY(vtx[1]); bt->setZ(vtx[2]); - bt++; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; } if (poly->VertexCount()==4) @@ -1493,8 +1497,9 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo if (vert_tag_array[i4]==true) { /* *** v4 *** */ vert_tag_array[i4]= false; vtx = v4->getXYZ(); - bt->setX(vtx[0]); bt->setY(vtx[1]); bt->setZ(vtx[2]); - bt++; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; } } } @@ -1577,7 +1582,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() break; case PHY_SHAPE_POLYTOPE: - collisionShape = new btConvexHullShape(&m_vertexArray[0].getX(), m_vertexArray.size()); + collisionShape = new btConvexHullShape(&m_vertexArray[0], m_vertexArray.size()/3, 3*sizeof(btScalar)); break; case PHY_SHAPE_MESH: @@ -1594,9 +1599,9 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() m_polygonIndexArray.size(), &m_triFaceArray[0], 3*sizeof(int), - m_vertexArray.size(), - (btScalar*) &m_vertexArray[0].x(), - sizeof(btVector3) + m_vertexArray.size()/3, + &m_vertexArray[0], + 3*sizeof(btScalar) ); btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays); @@ -1619,12 +1624,13 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() bool removeDuplicateVertices=true; // m_vertexArray not in multiple of 3 anymore, use m_triFaceArray for(int i=0; iaddTriangle( - m_vertexArray[m_triFaceArray[i]], - m_vertexArray[m_triFaceArray[i+1]], - m_vertexArray[m_triFaceArray[i+2]], - removeDuplicateVertices - ); + btScalar *bt = &m_vertexArray[3*m_triFaceArray[i]]; + btVector3 v1(bt[0], bt[1], bt[2]); + bt = &m_vertexArray[3*m_triFaceArray[i+1]]; + btVector3 v2(bt[0], bt[1], bt[2]); + bt = &m_vertexArray[3*m_triFaceArray[i+2]]; + btVector3 v3(bt[0], bt[1], bt[2]); + collisionMeshData->addTriangle(v1, v2, v3, removeDuplicateVertices); } indexVertexArrays = collisionMeshData; @@ -1634,9 +1640,9 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() m_polygonIndexArray.size(), &m_triFaceArray[0], 3*sizeof(int), - m_vertexArray.size(), - (btScalar*) &m_vertexArray[0].x(), - sizeof(btVector3)); + m_vertexArray.size()/3, + &m_vertexArray[0], + 3*sizeof(btScalar)); } // this shape will be shared and not deleted until shapeInfo is deleted diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 4510bbddf65..4ab478b2106 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -161,8 +161,8 @@ public: btTransform m_childTrans; btVector3 m_childScale; void* m_userData; - btAlignedObjectArray m_vertexArray; // Contains both vertex array for polytope shape and - // triangle array for concave mesh shape. + btAlignedObjectArray m_vertexArray; // Contains both vertex array for polytope shape and + // triangle array for concave mesh shape. Each vertex is 3 consecutive values // In this case a triangle is made of 3 consecutive points std::vector m_polygonIndexArray; // Contains the array of polygon index in the // original mesh that correspond to shape triangles. @@ -173,11 +173,7 @@ public: void setVertexWeldingThreshold1(float threshold) { - m_weldingThreshold1 = threshold; - } - float getVertexWeldingThreshold1() const - { - return m_weldingThreshold1; + m_weldingThreshold1 = threshold*threshold; } protected: static std::map m_meshShapeMap; From eee8dd9086e5b8e1abe36fb545b07aaeba351d57 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 28 Apr 2009 13:02:49 +0000 Subject: [PATCH 085/444] - Updated BGE docs to match the game engines class inheritance more closely. - Grouped deprecated functions for KX_Camera, KX_GameObject, SCA_ISensor, SCA_ILogicBrick, KX_Scene --- source/gameengine/PyDoc/BL_Shader.py | 5 +++- source/gameengine/PyDoc/CListValue.py | 4 ++- source/gameengine/PyDoc/CPropValue.py | 8 ++++++ source/gameengine/PyDoc/CValue.py | 8 ++++++ source/gameengine/PyDoc/KX_BlenderMaterial.py | 5 +++- source/gameengine/PyDoc/KX_Camera.py | 3 +++ source/gameengine/PyDoc/KX_GameObject.py | 9 +++---- source/gameengine/PyDoc/KX_MeshProxy.py | 4 ++- .../PyDoc/KX_PhysicsObjectWrapper.py | 4 ++- source/gameengine/PyDoc/KX_PolyProxy.py | 3 ++- source/gameengine/PyDoc/KX_Scene.py | 14 +++++++++- source/gameengine/PyDoc/KX_VehicleWrapper.py | 4 ++- source/gameengine/PyDoc/KX_VertexProxy.py | 4 ++- source/gameengine/PyDoc/PyObjectPlus.py | 26 +++++++++++++++++++ source/gameengine/PyDoc/SCA_ILogicBrick.py | 4 ++- source/gameengine/PyDoc/SCA_IObject.py | 9 +++++++ source/gameengine/PyDoc/SCA_ISensor.py | 1 + 17 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 source/gameengine/PyDoc/CPropValue.py create mode 100644 source/gameengine/PyDoc/CValue.py create mode 100644 source/gameengine/PyDoc/PyObjectPlus.py create mode 100644 source/gameengine/PyDoc/SCA_IObject.py diff --git a/source/gameengine/PyDoc/BL_Shader.py b/source/gameengine/PyDoc/BL_Shader.py index 182b73d437b..10e8b7c94ef 100644 --- a/source/gameengine/PyDoc/BL_Shader.py +++ b/source/gameengine/PyDoc/BL_Shader.py @@ -1,4 +1,7 @@ -class BL_Shader: # (PyObjectPlus) + +from PyObjectPlus import * + +class BL_Shader(PyObjectPlus): """ BL_Shader GLSL shaders. diff --git a/source/gameengine/PyDoc/CListValue.py b/source/gameengine/PyDoc/CListValue.py index e9fc4215bb6..1f60e8a7bc2 100644 --- a/source/gameengine/PyDoc/CListValue.py +++ b/source/gameengine/PyDoc/CListValue.py @@ -1,4 +1,6 @@ -class CListValue: # (PyObjectPlus) +from CPropValue import * + +class CListValue(CPropValue): """ CListValue diff --git a/source/gameengine/PyDoc/CPropValue.py b/source/gameengine/PyDoc/CPropValue.py new file mode 100644 index 00000000000..498b47ab013 --- /dev/null +++ b/source/gameengine/PyDoc/CPropValue.py @@ -0,0 +1,8 @@ +# +# Documentation for CValue class +from CValue import * +class CPropValue(CValue): + """ + This class has no python functions + """ + pass diff --git a/source/gameengine/PyDoc/CValue.py b/source/gameengine/PyDoc/CValue.py new file mode 100644 index 00000000000..e9b0563955b --- /dev/null +++ b/source/gameengine/PyDoc/CValue.py @@ -0,0 +1,8 @@ +# +# Documentation for CValue class +from PyObjectPlus import * +class CValue(PyObjectPlus): + """ + This class has no python functions + """ + pass diff --git a/source/gameengine/PyDoc/KX_BlenderMaterial.py b/source/gameengine/PyDoc/KX_BlenderMaterial.py index 21417db1802..c70a7dddcca 100644 --- a/source/gameengine/PyDoc/KX_BlenderMaterial.py +++ b/source/gameengine/PyDoc/KX_BlenderMaterial.py @@ -1,4 +1,7 @@ -class KX_BlenderMaterial: # (PyObjectPlus) + +from PyObjectPlus import * + +class KX_BlenderMaterial(PyObjectPlus): # , RAS_IPolyMaterial) """ KX_BlenderMaterial diff --git a/source/gameengine/PyDoc/KX_Camera.py b/source/gameengine/PyDoc/KX_Camera.py index f5d0d45f968..5c54935192a 100644 --- a/source/gameengine/PyDoc/KX_Camera.py +++ b/source/gameengine/PyDoc/KX_Camera.py @@ -40,6 +40,8 @@ class KX_Camera(KX_GameObject): Regenerated every frame from the camera's position and orientation. This is camera_to_world inverted. @type world_to_camera: 4x4 Matrix [[float]] + + @group Deprecated: enableViewport """ def sphereInsideFrustum(centre, radius): @@ -187,6 +189,7 @@ class KX_Camera(KX_GameObject): def enableViewport(viewport): """ + DEPRECATED: use the isViewport property Use this camera to draw a viewport on the screen (for split screen games or overlay scenes). The viewport region is defined with L{setViewport}. @type viewport: bool diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index fcb3d91dbcb..2688de0d018 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -1,18 +1,18 @@ # $Id$ # Documentation for game objects -# from SCA_IObject import * +from SCA_IObject import * # from SCA_ISensor import * # from SCA_IController import * # from SCA_IActuator import * -class KX_GameObject: # (SCA_IObject) +class KX_GameObject(SCA_IObject): """ All game objects are derived from this class. Properties assigned to game objects are accessible as attributes of this class. - - note: Calling ANY method or attribute on an object that has been removed from a scene will raise a RuntimeError, if an object may have been removed since last accessing it use the L{isValid} attribute to check. + - note: Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the L{invalid} attribute to check. @ivar name: The object's name. (Read only) - note: Currently (Blender 2.49) the prefix "OB" is added to all objects name. This may change in blender 2.5. @@ -79,8 +79,7 @@ class KX_GameObject: # (SCA_IObject) - note: This attribute is experemental and may be removed (but probably wont be). - note: Changes to this list will not update the KX_GameObject. @type actuators: list - @ivar isValid: Retuerns fails when the object has been removed from the scene and can no longer be used. - @type isValid: bool + @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh """ def endObject(): """ diff --git a/source/gameengine/PyDoc/KX_MeshProxy.py b/source/gameengine/PyDoc/KX_MeshProxy.py index e8839ac484c..c864523cde8 100644 --- a/source/gameengine/PyDoc/KX_MeshProxy.py +++ b/source/gameengine/PyDoc/KX_MeshProxy.py @@ -1,7 +1,9 @@ # $Id$ # Documentation for KX_MeshProxy -class KX_MeshProxy: +from SCA_IObject import * + +class KX_MeshProxy(SCA_IObject): """ A mesh object. diff --git a/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py b/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py index 2171cf4c7b6..ea9a2a3a411 100644 --- a/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py +++ b/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py @@ -1,4 +1,6 @@ -class KX_PhysicsObjectWrapper: # (PyObjectPlus) +from PyObjectPlus import * + +class KX_PhysicsObjectWrapper(PyObjectPlus): """ KX_PhysicsObjectWrapper diff --git a/source/gameengine/PyDoc/KX_PolyProxy.py b/source/gameengine/PyDoc/KX_PolyProxy.py index bcd42c2ac2e..2d1c1f9b218 100644 --- a/source/gameengine/PyDoc/KX_PolyProxy.py +++ b/source/gameengine/PyDoc/KX_PolyProxy.py @@ -1,7 +1,8 @@ # $Id$ # Documentation for the polygon proxy class +from SCA_IObject import * -class KX_PolyProxy: +class KX_PolyProxy(SCA_IObject): """ A polygon holds the index of the vertex forming the poylgon. diff --git a/source/gameengine/PyDoc/KX_Scene.py b/source/gameengine/PyDoc/KX_Scene.py index 5dcd560ee96..4fe150be898 100644 --- a/source/gameengine/PyDoc/KX_Scene.py +++ b/source/gameengine/PyDoc/KX_Scene.py @@ -1,7 +1,9 @@ # $Id$ # Documentation for KX_Scene.py -class KX_Scene: +from PyObjectPlus import * + +class KX_Scene(PyObjectPlus): """ Scene. @@ -41,6 +43,12 @@ class KX_Scene: @type name: string @ivar objects: A list of objects in the scene. @type objects: L{CListValue} of L{KX_GameObject} + @ivar objects_inactive: A list of objects on background layers (used for the addObject actuator). + @type objects_inactive: L{CListValue} of L{KX_GameObject} + @ivar lights: A list of lights in the scene. + @type lights: L{CListValue} of L{KX_GameObject} + @ivar cameras: A list of cameras in the scene. + @type cameras: L{CListValue} of L{KX_GameObject} @ivar active_camera: The current active camera @type active_camera: L{KX_Camera} @ivar suspended: True if the scene is suspended. @@ -49,22 +57,26 @@ class KX_Scene: @type activity_culling: boolean @ivar activity_culling_radius: The distance outside which to do activity culling. Measured in manhattan distance. @type activity_culling_radius: float + @group Deprecated: getLightList, getObjectList, getName """ def getLightList(): """ + DEPRECATED: use the 'lights' property. Returns the list of lights in the scene. @rtype: list [L{KX_LightObject}] """ def getObjectList(): """ + DEPRECATED: use the 'objects' property. Returns the list of objects in the scene. @rtype: list [L{KX_GameObject}] """ def getName(): """ + DEPRECATED: use the 'name' property. Returns the name of the scene. @rtype: string diff --git a/source/gameengine/PyDoc/KX_VehicleWrapper.py b/source/gameengine/PyDoc/KX_VehicleWrapper.py index 087aa167475..3d91b7db676 100644 --- a/source/gameengine/PyDoc/KX_VehicleWrapper.py +++ b/source/gameengine/PyDoc/KX_VehicleWrapper.py @@ -1,4 +1,6 @@ -class KX_VehicleWrapper: # (PyObjectPlus) +from PyObjectPlus import * + +class KX_VehicleWrapper(PyObjectPlus): """ KX_VehicleWrapper diff --git a/source/gameengine/PyDoc/KX_VertexProxy.py b/source/gameengine/PyDoc/KX_VertexProxy.py index 7ee5087b316..114e0d88075 100644 --- a/source/gameengine/PyDoc/KX_VertexProxy.py +++ b/source/gameengine/PyDoc/KX_VertexProxy.py @@ -1,7 +1,9 @@ # $Id$ # Documentation for the vertex proxy class -class KX_VertexProxy: +from SCA_IObject import * + +class KX_VertexProxy(SCA_IObject): """ A vertex holds position, UV, colour and normal information. diff --git a/source/gameengine/PyDoc/PyObjectPlus.py b/source/gameengine/PyDoc/PyObjectPlus.py new file mode 100644 index 00000000000..1750bcb6ca1 --- /dev/null +++ b/source/gameengine/PyDoc/PyObjectPlus.py @@ -0,0 +1,26 @@ +# +# Documentation for PyObjectPlus base class + +class PyObjectPlus: + """ + PyObjectPlus base class of most other types in the Game Engine. + + @ivar invalid: Test if the object has been freed by the game engine and is no longer valid. + + Normally this is not a problem but when storing game engine data in the GameLogic module, + KX_Scenes or other KX_GameObjects its possible to hold a reference to invalid data. + Calling an attribute or method on an invalid object will raise a SystemError. + + The invalid attribute allows testing for this case without exception handling. + @type invalid: bool + """ + + def isA(game_type): + """ + Check if this is a type or a subtype game_type. + + @param game_type: the name of the type or the type its self from the L{GameTypes} module. + @type game_type: string or type + @return: True if this object is a type or a subtype of game_type. + @rtype: bool + """ diff --git a/source/gameengine/PyDoc/SCA_ILogicBrick.py b/source/gameengine/PyDoc/SCA_ILogicBrick.py index 4688ba12bb6..2bfe407204a 100644 --- a/source/gameengine/PyDoc/SCA_ILogicBrick.py +++ b/source/gameengine/PyDoc/SCA_ILogicBrick.py @@ -1,8 +1,9 @@ # $Id$ # Documentation for the logic brick base class SCA_ILogicBrick from KX_GameObject import * +from CValue import * -class SCA_ILogicBrick: +class SCA_ILogicBrick(CValue): """ Base class for all logic bricks. @@ -10,6 +11,7 @@ class SCA_ILogicBrick: @type executePriority: int @ivar owner: The game object this logic brick is attached to (read only). @type owner: L{KX_GameObject} or None in exceptional cases. + @group Deprecated: getOwner, setExecutePriority, getExecutePriority """ def getOwner(): diff --git a/source/gameengine/PyDoc/SCA_IObject.py b/source/gameengine/PyDoc/SCA_IObject.py new file mode 100644 index 00000000000..92e4884e815 --- /dev/null +++ b/source/gameengine/PyDoc/SCA_IObject.py @@ -0,0 +1,9 @@ +# +# Documentation for SCA_IObject class + +from CValue import * +class SCA_IObject(CValue): + """ + This class has no python functions + """ + pass diff --git a/source/gameengine/PyDoc/SCA_ISensor.py b/source/gameengine/PyDoc/SCA_ISensor.py index ab35996aa50..0b72548b103 100644 --- a/source/gameengine/PyDoc/SCA_ISensor.py +++ b/source/gameengine/PyDoc/SCA_ISensor.py @@ -24,6 +24,7 @@ class SCA_ISensor(SCA_ILogicBrick): @type triggered: boolean @ivar positive: True if this sensor brick is in a positive state. (Read only) @type positive: boolean + @group Deprecated: isPositive, isTriggered, getUsePosPulseMode, setUsePosPulseMode, getFrequency, setFrequency, getUseNegPulseMode, setUseNegPulseMode, getInvert, setInvert, getLevel, setLevel """ def reset(): From 94c6cadfe22d0fe1cdc666243463bc7971c5de51 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 28 Apr 2009 13:11:56 +0000 Subject: [PATCH 086/444] BGE PyAPI - renamed generic attribute "isValid" to "invalid" since BL_Shader already uses isValid. - Moved deprecation warnings from CValue - removed unused KX_Scene::SetProjectionMatrix and KX_Scene::GetViewMatrix - Added KX_Scene attributes "lights", "cameras", "objects_inactive", to allow access to objects in unseen layers (before the AddObject actuator adds them) - KX_Camera deprecated cam.enableViewport(bool) for cam.isViewport which can be read as well. --- .../gameengine/Expressions/PyObjectPlus.cpp | 61 ++++++++++++-- source/gameengine/Expressions/PyObjectPlus.h | 10 ++- source/gameengine/Expressions/Value.cpp | 50 ----------- source/gameengine/Expressions/Value.h | 5 -- source/gameengine/Ketsji/KX_Camera.cpp | 34 ++++++-- source/gameengine/Ketsji/KX_Camera.h | 3 + source/gameengine/Ketsji/KX_GameObject.cpp | 17 ++-- source/gameengine/Ketsji/KX_Scene.cpp | 83 +++++++++++-------- source/gameengine/Ketsji/KX_Scene.h | 33 +------- 9 files changed, 157 insertions(+), 139 deletions(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 54f076741cc..8bd34cdc73b 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -113,13 +113,13 @@ PyMethodDef PyObjectPlus::Methods[] = { }; PyAttributeDef PyObjectPlus::Attributes[] = { - KX_PYATTRIBUTE_RO_FUNCTION("isValid", PyObjectPlus, pyattr_get_is_valid), + KX_PYATTRIBUTE_RO_FUNCTION("invalid", PyObjectPlus, pyattr_get_invalid), {NULL} //Sentinel }; -PyObject* PyObjectPlus::pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +PyObject* PyObjectPlus::pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - Py_RETURN_TRUE; + Py_RETURN_FALSE; } /*------------------------------ @@ -137,8 +137,8 @@ PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) { PyObjectPlus *self_plus= BGE_PROXY_REF(self); if(self_plus==NULL) { - if(!strcmp("isValid", PyString_AsString(attr))) { - Py_RETURN_FALSE; + if(!strcmp("invalid", PyString_AsString(attr))) { + Py_RETURN_TRUE; } PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; @@ -896,5 +896,56 @@ PyObject *PyObjectPlus::NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool return self->m_proxy; } +/////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// +/* deprecation warning management */ +bool PyObjectPlus::m_ignore_deprecation_warnings(false); +void PyObjectPlus::SetDeprecationWarnings(bool ignoreDeprecationWarnings) +{ + m_ignore_deprecation_warnings = ignoreDeprecationWarnings; +} + +void PyObjectPlus::ShowDeprecationWarning(const char* old_way,const char* new_way) +{ + if (!m_ignore_deprecation_warnings) { + printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way); + + // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno) + + PyObject *getframe, *frame; + PyObject *f_lineno, *f_code, *co_filename; + + getframe = PySys_GetObject((char *)"_getframe"); // borrowed + if (getframe) { + frame = PyObject_CallObject(getframe, NULL); + if (frame) { + f_lineno= PyObject_GetAttrString(frame, "f_lineno"); + f_code= PyObject_GetAttrString(frame, "f_code"); + if (f_lineno && f_code) { + co_filename= PyObject_GetAttrString(f_code, "co_filename"); + if (co_filename) { + + printf("\t%s:%d\n", PyString_AsString(co_filename), (int)PyInt_AsLong(f_lineno)); + + Py_DECREF(f_lineno); + Py_DECREF(f_code); + Py_DECREF(co_filename); + Py_DECREF(frame); + return; + } + } + + Py_XDECREF(f_lineno); + Py_XDECREF(f_code); + Py_DECREF(frame); + } + + } + PyErr_Clear(); + printf("\tERROR - Could not access sys._getframe(0).f_lineno or sys._getframe().f_code.co_filename\n"); + } +} + + #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 257851ef4b3..f90a1436d00 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -446,7 +446,7 @@ public: KX_PYMETHOD_O(PyObjectPlus,isA); /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */ - static PyObject* pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp); static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns); @@ -458,6 +458,14 @@ public: */ virtual void ProcessReplica(); + + static bool m_ignore_deprecation_warnings; + + /** enable/disable display of deprecation warnings */ + static void SetDeprecationWarnings(bool ignoreDeprecationWarnings); + /** Shows a deprecation warning */ + static void ShowDeprecationWarning(const char* method,const char* prop); + }; PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict); diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 6e8f2ba1061..088b5cb98a4 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -32,7 +32,6 @@ ////////////////////////////////////////////////////////////////////// double CValue::m_sZeroVec[3] = {0.0,0.0,0.0}; -bool CValue::m_ignore_deprecation_warnings(false); #ifndef NO_EXP_PYTHON_EMBEDDING @@ -781,52 +780,3 @@ void CValue::SetValue(CValue* newval) // no one should get here assertd(newval->GetNumber() == 10121969); } -/////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////// -/* deprecation warning management */ -void CValue::SetDeprecationWarnings(bool ignoreDeprecationWarnings) -{ - m_ignore_deprecation_warnings = ignoreDeprecationWarnings; -} - -void CValue::ShowDeprecationWarning(const char* old_way,const char* new_way) -{ - if (!m_ignore_deprecation_warnings) { - printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way); - - // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno) - - PyObject *getframe, *frame; - PyObject *f_lineno, *f_code, *co_filename; - - getframe = PySys_GetObject((char *)"_getframe"); // borrowed - if (getframe) { - frame = PyObject_CallObject(getframe, NULL); - if (frame) { - f_lineno= PyObject_GetAttrString(frame, "f_lineno"); - f_code= PyObject_GetAttrString(frame, "f_code"); - if (f_lineno && f_code) { - co_filename= PyObject_GetAttrString(f_code, "co_filename"); - if (co_filename) { - - printf("\t%s:%d\n", PyString_AsString(co_filename), (int)PyInt_AsLong(f_lineno)); - - Py_DECREF(f_lineno); - Py_DECREF(f_code); - Py_DECREF(co_filename); - Py_DECREF(frame); - return; - } - } - - Py_XDECREF(f_lineno); - Py_XDECREF(f_code); - Py_DECREF(frame); - } - - } - PyErr_Clear(); - printf("\tERROR - Could not access sys._getframe(0).f_lineno or sys._getframe().f_code.co_filename\n"); - } -} - diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 97ce9cddcea..fca603a831e 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -303,10 +303,6 @@ public: STR_String op2str(VALUE_OPERATOR op); - /** enable/disable display of deprecation warnings */ - static void SetDeprecationWarnings(bool ignoreDeprecationWarnings); - /** Shows a deprecation warning */ - static void ShowDeprecationWarning(const char* method,const char* prop); // setting / getting flags inline void SetSelected(bool bSelected) { m_ValFlags.Selected = bSelected; } @@ -338,7 +334,6 @@ private: ValueFlags m_ValFlags; // Frequently used flags in a bitfield (low memoryusage) int m_refcount; // Reference Counter static double m_sZeroVec[3]; - static bool m_ignore_deprecation_warnings; }; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 8565346b30e..bc2c2fc33b0 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -478,10 +478,12 @@ PyMethodDef KX_Camera::Methods[] = { KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera), KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix), KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix), - KX_PYMETHODTABLE_O(KX_Camera, enableViewport), KX_PYMETHODTABLE(KX_Camera, setViewport), KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop), + // DEPRECATED + KX_PYMETHODTABLE_O(KX_Camera, enableViewport), + {NULL,NULL} //Sentinel }; @@ -494,6 +496,8 @@ PyAttributeDef KX_Camera::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("near", KX_Camera, pyattr_get_near, pyattr_set_near), KX_PYATTRIBUTE_RW_FUNCTION("far", KX_Camera, pyattr_get_far, pyattr_set_far), + KX_PYATTRIBUTE_RW_FUNCTION("isViewport", KX_Camera, pyattr_get_is_viewport, pyattr_set_is_viewport), + KX_PYATTRIBUTE_RO_FUNCTION("projection_matrix", KX_Camera, pyattr_get_projection_matrix), KX_PYATTRIBUTE_RO_FUNCTION("modelview_matrix", KX_Camera, pyattr_get_modelview_matrix), KX_PYATTRIBUTE_RO_FUNCTION("camera_to_world", KX_Camera, pyattr_get_camera_to_world), @@ -745,8 +749,9 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport, "Sets this camera's viewport status\n" ) { - int viewport = PyObject_IsTrue(value); + ShowDeprecationWarning("enableViewport(bool)", "the isViewport property"); + int viewport = PyObject_IsTrue(value); if (viewport == -1) { PyErr_SetString(PyExc_ValueError, "camera.enableViewport(bool): KX_Camera, expected True/False or 0/1"); return NULL; @@ -776,10 +781,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, setOnTop, "setOnTop()\n" "Sets this camera's viewport on top\n") { - class KX_Scene* scene; - - scene = KX_GetActiveScene(); - MT_assert(scene); + class KX_Scene* scene = KX_GetActiveScene(); scene->SetCameraOnTop(this); Py_RETURN_NONE; } @@ -863,6 +865,26 @@ int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, P return 0; } + +PyObject* KX_Camera::pyattr_get_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Camera* self= static_cast(self_v); + return PyBool_FromLong(self->GetViewport()); +} + +int KX_Camera::pyattr_set_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_Camera* self= static_cast(self_v); + int param = PyObject_IsTrue( value ); + if (param == -1) { + PyErr_SetString(PyExc_AttributeError, "camera.isViewport = bool: KX_Camera, expected True or False"); + return 1; + } + self->EnableViewport((bool)param); + return 0; +} + + PyObject* KX_Camera::pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Camera* self= static_cast(self_v); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 83316972ca0..e99a0594701 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -284,6 +284,9 @@ public: static PyObject* pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 53c2d6c7937..ed162238e8a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1067,7 +1067,6 @@ CListValue* KX_GameObject::GetChildrenRecursive() /* ------- python stuff ---------------------------------------------------*/ PyMethodDef KX_GameObject::Methods[] = { - {"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O}, {"applyForce", (PyCFunction) KX_GameObject::sPyApplyForce, METH_VARARGS}, {"applyTorque", (PyCFunction) KX_GameObject::sPyApplyTorque, METH_VARARGS}, {"applyRotation", (PyCFunction) KX_GameObject::sPyApplyRotation, METH_VARARGS}, @@ -1106,6 +1105,7 @@ PyMethodDef KX_GameObject::Methods[] = { // deprecated {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS}, {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O}, + {"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O}, {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS}, {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O}, {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS}, @@ -1177,8 +1177,8 @@ PyObject* KX_GameObject::PyReplaceMesh(PyObject* value) PyObject* KX_GameObject::PyEndObject() { - KX_Scene *scene = KX_GetActiveScene(); + scene->DelayedRemoveObject(this); Py_RETURN_NONE; @@ -1321,7 +1321,6 @@ PyMappingMethods KX_GameObject::Mapping = { (objobjargproc)KX_GameObject::Map_SetItem, /*objobjargproc mp_ass_subscript */ }; - PyTypeObject KX_GameObject::Type = { PyObject_HEAD_INIT(NULL) 0, @@ -2069,17 +2068,20 @@ PyObject* KX_GameObject::PyGetParent() PyObject* KX_GameObject::PySetParent(PyObject* value) { + KX_Scene *scene = KX_GetActiveScene(); KX_GameObject *obj; + if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject")) return NULL; - this->SetParent(KX_GetActiveScene(), obj); + this->SetParent(scene, obj); Py_RETURN_NONE; } PyObject* KX_GameObject::PyRemoveParent() { KX_Scene *scene = KX_GetActiveScene(); + this->RemoveParent(scene); Py_RETURN_NONE; } @@ -2249,6 +2251,7 @@ PyObject* KX_GameObject::PySetPosition(PyObject* value) PyObject* KX_GameObject::PySetWorldPosition(PyObject* value) { + ShowDeprecationWarning("setWorldPosition()", "the worldPosition property"); MT_Point3 pos; if (PyVecTo(value, pos)) { @@ -2585,6 +2588,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage, "body = Message body (string)" "to = Name of object to send the message to") { + KX_Scene *scene = KX_GetActiveScene(); char* subject; char* body = (char *)""; char* to = (char *)""; @@ -2592,9 +2596,8 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage, if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to)) return NULL; - - KX_GetActiveScene()->GetNetworkScene()->SendMessage(to, from, subject, body); - + + scene->GetNetworkScene()->SendMessage(to, from, subject, body); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 9e67e39b2a5..1c1cc881d17 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -255,13 +255,6 @@ KX_Scene::~KX_Scene() Py_DECREF(m_attr_dict); } -void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat) -{ - m_projectionmat = pmat; -} - - - RAS_BucketManager* KX_Scene::GetBucketManager() { return m_bucketmanager; @@ -1153,24 +1146,6 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) gameobj->AddMeshUser(); } - - -MT_CmMatrix4x4& KX_Scene::GetViewMatrix() -{ - MT_Scalar cammat[16]; - m_active_camera->GetWorldToCamera().getValue(cammat); - m_viewmat = cammat; - return m_viewmat; -} - - - -MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix() -{ - return m_projectionmat; -} - - KX_Camera* KX_Scene::FindCamera(KX_Camera* cam) { list::iterator it = m_cameras.begin(); @@ -1645,9 +1620,9 @@ PyParentObject KX_Scene::Parents[] = { }; PyMethodDef KX_Scene::Methods[] = { - KX_PYMETHODTABLE(KX_Scene, getLightList), - KX_PYMETHODTABLE(KX_Scene, getObjectList), - KX_PYMETHODTABLE(KX_Scene, getName), + KX_PYMETHODTABLE_NOARGS(KX_Scene, getLightList), + KX_PYMETHODTABLE_NOARGS(KX_Scene, getObjectList), + KX_PYMETHODTABLE_NOARGS(KX_Scene, getName), KX_PYMETHODTABLE(KX_Scene, addObject), {NULL,NULL} //Sentinel @@ -1665,6 +1640,39 @@ PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *a return self->GetObjectList()->GetProxy(); } +PyObject* KX_Scene::pyattr_get_objects_inactive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene* self= static_cast(self_v); + return self->GetInactiveList()->GetProxy(); +} + +PyObject* KX_Scene::pyattr_get_lights(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene* self= static_cast(self_v); + return self->GetLightList()->GetProxy(); +} + +PyObject* KX_Scene::pyattr_get_cameras(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + /* With refcounts in this case... + * the new CListValue is owned by python, so its possible python holds onto it longer then the BGE + * however this is the same with "scene.objects + []", when you make a copy by adding lists. + */ + + KX_Scene* self= static_cast(self_v); + CListValue* clist = new CListValue(); + + /* return self->GetCameras()->GetProxy(); */ + + list::iterator it = self->GetCameras()->begin(); + while (it != self->GetCameras()->end()) { + clist->Add((*it)->AddRef()); + it++; + } + + return clist->NewProxy(true); +} + PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast(self_v); @@ -1672,13 +1680,16 @@ PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_ } PyAttributeDef KX_Scene::Attributes[] = { - KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name), - KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects), - KX_PYATTRIBUTE_RO_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera), - KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend), - KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling), + KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name), + KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects), + KX_PYATTRIBUTE_RO_FUNCTION("objects_inactive", KX_Scene, pyattr_get_objects_inactive), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), + KX_PYATTRIBUTE_RO_FUNCTION("cameras", KX_Scene, pyattr_get_cameras), + KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), + KX_PYATTRIBUTE_RO_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera), + KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend), + KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling), KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius), - KX_PYATTRIBUTE_BOOL_RO("dbvt_culling", KX_Scene, m_dbvt_culling), + KX_PYATTRIBUTE_BOOL_RO("dbvt_culling", KX_Scene, m_dbvt_culling), { NULL } //Sentinel }; @@ -1754,6 +1765,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList, "Returns a list of all lights in the scene.\n" ) { + ShowDeprecationWarning("getLightList()", "the lights property"); return m_lightlist->GetProxy(); } @@ -1762,7 +1774,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList, "Returns a list of all game objects in the scene.\n" ) { - // ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work? + ShowDeprecationWarning("getObjectList()", "the objects property"); return m_objectlist->GetProxy(); } @@ -1771,6 +1783,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName, "Returns the name of the scene.\n" ) { + ShowDeprecationWarning("getName()", "the name property"); return PyString_FromString(GetName()); } diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index dbba7723cc5..52a3cd5733e 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -32,8 +32,6 @@ #include "KX_PhysicsEngineEnums.h" -#include "MT_CmMatrix4x4.h" - #include #include #include @@ -191,15 +189,6 @@ protected: */ KX_Camera* m_active_camera; - /** - * The projection and view matrices of this scene - * The projection matrix is computed externally by KX_Engine - * The view mat is stored as a side effect of GetViewMatrix() - * and is totally unnessary. - */ - MT_CmMatrix4x4 m_projectionmat; - MT_CmMatrix4x4 m_viewmat; - /** Desired canvas width set at design time. */ unsigned int m_canvasDesignWidth; /** Desired canvas height set at design time. */ @@ -422,25 +411,6 @@ public: class KX_Camera* ); - /** Return the viewmatrix as used by the last frame. */ - MT_CmMatrix4x4& - GetViewMatrix( - ); - - /** - * Return the projectionmatrix as used by the last frame. This is - * set by hand :) - */ - MT_CmMatrix4x4& - GetProjectionMatrix( - ); - - /** Sets the projection matrix. */ - void - SetProjectionMatrix( - MT_CmMatrix4x4& pmat - ); - /** * Activates new desired canvas width set at design time. * @param width The new desired width. @@ -592,6 +562,9 @@ public: /* attributes */ static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_objects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_objects_inactive(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_lights(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_cameras(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ From d3b20dddd73297c76a2973a55cf3c5b15b8dd30a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 28 Apr 2009 15:28:02 +0000 Subject: [PATCH 087/444] Mathutils - fix own mistake with matrix slicing that would crash blender (from recent commit). - fix 3 memory leaks from ascotan r4717 in the Mathutils.Quaternion(...) function. --- source/blender/python/api2_2x/Mathutils.c | 33 ++++++++++++++++------- source/blender/python/api2_2x/matrix.c | 13 +++++---- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index 9217d94ba1c..9c73ca16e70 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -309,8 +309,8 @@ PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args) { PyObject *listObject = NULL; int size, i; - float vec[4]; - PyObject *v, *f; + float vec[4], f; + PyObject *v; size = PySequence_Length(args); if (size == 1) { @@ -344,16 +344,15 @@ PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args) return NULL; } - f=PyNumber_Float(v); - if(f==NULL) { // parsed item not a number + f= PyFloat_AsDouble(v); + if(f==-1 && PyErr_Occurred()) { // parsed item not a number Py_DECREF(v); Py_XDECREF(listObject); PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); return NULL; } - vec[i]=(float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + vec[i]= f; Py_DECREF(v); } Py_DECREF(listObject); @@ -999,16 +998,24 @@ PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) return NULL; } if(size == 3){ //get angle in axis/angle - n = PyNumber_Float(PySequence_GetItem(args, 1)); + n = PySequence_GetItem(args, 1); if(n == NULL) { // parsed item not a number or getItem fail Py_DECREF(listObject); PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); return NULL; } - angle = PyFloat_AS_DOUBLE(n); + + angle = PyFloat_AsDouble(n); Py_DECREF(n); + + if (angle==-1 && PyErr_Occurred()) { + Py_DECREF(listObject); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } } }else{ + Py_DECREF(listObject); /* assume the list is teh second arg */ listObject = PySequence_GetItem(args, 1); if (size>1 && PySequence_Check(listObject)) { size = PySequence_Length(listObject); @@ -1018,14 +1025,20 @@ PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); return NULL; } - n = PyNumber_Float(PySequence_GetItem(args, 0)); + n = PySequence_GetItem(args, 0); if(n == NULL) { // parsed item not a number or getItem fail Py_DECREF(listObject); PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); return NULL; } - angle = PyFloat_AS_DOUBLE(n); + angle = PyFloat_AsDouble(n); Py_DECREF(n); + + if (angle==-1 && PyErr_Occurred()) { + Py_DECREF(listObject); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } } else { // argument was not a sequence Py_XDECREF(listObject); PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c index a8816ae4baa..659f746468a 100644 --- a/source/blender/python/api2_2x/matrix.c +++ b/source/blender/python/api2_2x/matrix.c @@ -575,9 +575,9 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject * seq) { int i, x, y, size, sub_size = 0; - float mat[16]; + float mat[16], f; PyObject *subseq; - PyObject *m, *f; + PyObject *m; CLAMP(begin, 0, self->rowSize); CLAMP(end, 0, self->rowSize); @@ -613,18 +613,17 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyErr_SetString(PyExc_RuntimeError, "matrix[begin:end] = []: unable to read sequence\n"); return -1; } - - f = PyNumber_Float(m); - if(f == NULL) { /*parsed item not a number*/ + + f = PyFloat_AsDouble(m); /* faster to assume a float and raise an error after */ + if(f == -1 && PyErr_Occurred()) { /*parsed item not a number*/ Py_DECREF(m); Py_DECREF(subseq); PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: sequence argument not a number\n"); return -1; } - mat[(i * self->colSize) + y] = (float)PyFloat_AS_DOUBLE(f); + mat[(i * self->colSize) + y] = f; Py_DECREF(m); - Py_DECREF(subseq); } }else{ Py_DECREF(subseq); From 851e6d9e44cda1bc1e79c6f84f926c53bdd41789 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 28 Apr 2009 17:25:50 +0000 Subject: [PATCH 088/444] Bugfix #18637 Sorting of files didn't take numbers into account propertly, so it ordered files like; 10.jpg 300.jpg 89.jpg 9.jpg Quite simple to solve, almost moved report to the 'todo', but too fun to leave this. :) function name is BLI_natstrcmp() "natural string compare". --- source/blender/blenlib/BLI_blenlib.h | 1 + source/blender/blenlib/intern/storage.c | 2 +- source/blender/blenlib/intern/util.c | 49 +++++++++++++++++++++++++ source/blender/src/filesel.c | 2 +- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 13d5b5fe829..c131dd93c72 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -387,6 +387,7 @@ void BLI_setInterruptCallBack(int (*f)(void)); char *BLI_strcasestr(const char *s, const char *find); int BLI_strcasecmp(const char *s1, const char *s2); int BLI_strncasecmp(const char *s1, const char *s2, int n); +int BLI_natstrcmp(const char *s1, const char *s2); void BLI_timestr(double _time, char *str); /* time var is global */ /** diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 8ba03ad1343..088b5e40a51 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -153,7 +153,7 @@ int BLI_compare(struct direntry *entry1, struct direntry *entry2) if( strcmp(entry2->relname, ".")==0 ) return (1); if( strcmp(entry1->relname, "..")==0 ) return (-1); - return (BLI_strcasecmp(entry1->relname,entry2->relname)); + return (BLI_natstrcmp(entry1->relname,entry2->relname)); } diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 013b9e0bb1b..842ebc4c0a9 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1985,6 +1985,55 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) { return 0; } +/* natural string compare, keeping numbers in order */ +int BLI_natstrcmp(const char *s1, const char *s2) +{ + int d1= 0, d2= 0; + + /* if both chars are numeric, to a strtol(). + then increase string deltas as long they are + numeric, else do a tolower and char compare */ + + while(1) { + char c1 = tolower(s1[d1]); + char c2 = tolower(s2[d2]); + + if( isdigit(c1) && isdigit(c2) ) { + int val1, val2; + + val1= (int)strtol(s1+d1, (char **)NULL, 10); + val2= (int)strtol(s2+d2, (char **)NULL, 10); + + if (val1val2) { + return 1; + } + d1++; + while( isdigit(s1[d1]) ) + d1++; + d2++; + while( isdigit(s2[d2]) ) + d2++; + + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); + } + + if (c1c2) { + return 1; + } else if (c1==0) { + break; + } + d1++; + d2++; + } + +} + + #ifdef WITH_ICONV #include "iconv.h" diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 9800c80b57d..36427fce36b 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -196,7 +196,7 @@ static int compare_name(const void *a1, const void *a2) if( strcmp(entry2->relname, ".")==0 ) return (1); if( strcmp(entry1->relname, "..")==0 ) return (-1); - return (BLI_strcasecmp(entry1->relname,entry2->relname)); + return (BLI_natstrcmp(entry1->relname,entry2->relname)); } static int compare_date(const void *a1, const void *a2) From 35c1b3134b60c5a2fb806fd18f50b70ee582ffe8 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 28 Apr 2009 17:55:48 +0000 Subject: [PATCH 089/444] etch-a-ton bugfix cut and trim didn't set normal properly. --- source/blender/src/editarmature_sketch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/src/editarmature_sketch.c b/source/blender/src/editarmature_sketch.c index 91aadd07392..dbf53bedbf9 100644 --- a/source/blender/src/editarmature_sketch.c +++ b/source/blender/src/editarmature_sketch.c @@ -2230,6 +2230,7 @@ void sk_applyCutGesture(SK_Gesture *gest, SK_Sketch *sketch) pt.type = PT_EXACT; pt.mode = PT_PROJECT; /* take mode from neighbouring points */ VECCOPY(pt.p, isect->p); + VECCOPY(pt.no, isect->stroke->points[isect->before].no); sk_insertStrokePoint(isect->stroke, &pt, isect->after); } @@ -2271,6 +2272,7 @@ void sk_applyTrimGesture(SK_Gesture *gest, SK_Sketch *sketch) pt.type = PT_EXACT; pt.mode = PT_PROJECT; /* take mode from neighbouring points */ VECCOPY(pt.p, isect->p); + VECCOPY(pt.no, isect->stroke->points[isect->before].no); VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p); From 5e66971dd35973d5099974a000beb15fe0905d05 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 28 Apr 2009 18:53:15 +0000 Subject: [PATCH 090/444] add note to Image.save method that all new buffers are saved as Targa --- source/blender/python/api2_2x/doc/Image.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/python/api2_2x/doc/Image.py b/source/blender/python/api2_2x/doc/Image.py index e376b11c4fa..12231ee8bcc 100644 --- a/source/blender/python/api2_2x/doc/Image.py +++ b/source/blender/python/api2_2x/doc/Image.py @@ -373,6 +373,7 @@ class Image: def save(): """ Saves the current image to L{filename} + @note: New images created in Blender will always save as Targa regardless of filename. @note: Saving to a directory that doent exist will raise an error. @note: Saving a packed image will make a unique (numbered) name if the file alredy exists. Remove the file first to be sure it will not be renamed. @returns: None From e4abebfa9153a0aae6eab438b89020c1f5af42ee Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 28 Apr 2009 18:56:48 +0000 Subject: [PATCH 091/444] BGE: reenable object activation for static object, otherwise their physic shape is not updated when they move due to parent relation. --- source/gameengine/Ketsji/KX_BulletPhysicsController.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index 891317e64a1..9e74706e1c0 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -444,7 +444,9 @@ void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) if (!m_bDyna) { - GetCollisionObject()->setCollisionFlags(GetRigidBody()->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + btCollisionObject* object = GetRigidBody(); + object->setActivationState(ACTIVE_TAG); + object->setCollisionFlags(object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } else { if (!nondynaonly) From 2d78dcfb610381a5056eed5f59dd57aa50e444c3 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Tue, 28 Apr 2009 23:26:35 +0000 Subject: [PATCH 092/444] fix so that torque can be applied to DYNAMIC game objects, this fixes the skategirl. Note that skategirl needs a bit higher angular damping, perhaps the conversion formula needs to be tweaked better? --- source/gameengine/Physics/Bullet/CcdPhysicsController.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index b171fbb3c34..961e9096442 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -964,7 +964,14 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque torque = xform.getBasis()*torque; } if (body) + { + //workaround for incompatibility between 'DYNAMIC' game object, and angular factor + //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque + const btVector3& angFac = body->getAngularFactor(); + body->setAngularFactor(1.f); body->applyTorque(torque); + body->setAngularFactor(angFac); + } } } From f004c36e41023b8a4ffa386226589b19c92eb971 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 29 Apr 2009 10:06:38 +0000 Subject: [PATCH 093/444] BGE: speed up mesh conversion by avoiding allocation/deallocation of material object on each face. The speed up is minor on optimized builds but considerable on less optimized builds, good for debugging large scene. --- .../Converter/BL_BlenderDataConversion.cpp | 54 +++++++++++------ source/gameengine/Ketsji/BL_Material.cpp | 5 ++ source/gameengine/Ketsji/BL_Material.h | 1 + .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 50 +++++++++------- source/gameengine/Ketsji/KX_BlenderMaterial.h | 6 +- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 58 +++++++++++-------- source/gameengine/Ketsji/KX_PolygonMaterial.h | 8 +-- .../Rasterizer/RAS_IPolygonMaterial.cpp | 55 ++++++++++++++++++ .../Rasterizer/RAS_IPolygonMaterial.h | 13 ++++- 9 files changed, 183 insertions(+), 67 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index ef3efbcec87..6a570c9e815 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -318,7 +318,8 @@ typedef struct MTF_localLayer }MTF_localLayer; // ------------------------------------ -BL_Material* ConvertMaterial( +bool ConvertMaterial( + BL_Material *material, Material *mat, MTFace* tface, const char *tfaceName, @@ -329,9 +330,7 @@ BL_Material* ConvertMaterial( MTF_localLayer *layers, bool glslmat) { - //this needs some type of manager - BL_Material *material = new BL_Material(); - + material->Initialize(); int numchan = -1, texalpha = 0; bool validmat = (mat!=0); bool validface = (tface!=0); @@ -720,7 +719,7 @@ BL_Material* ConvertMaterial( material->tface = tface; material->material = mat; - return material; + return true; } @@ -781,6 +780,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* meshobj->SetName(mesh->id.name); meshobj->m_sharedvertex_map.resize(totvert); + RAS_IPolyMaterial* polymat = NULL; + STR_String imastr; + // These pointers will hold persistent material structure during the conversion + // to avoid countless allocation/deallocation of memory. + BL_Material* bl_mat = NULL; + KX_BlenderMaterial* kx_blmat = NULL; + KX_PolygonMaterial* kx_polymat = NULL; for (int f=0;fGetMaterials()) { /* do Blender Multitexture and Blender GLSL materials */ @@ -852,7 +856,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* MT_Point2 uv[4]; /* first is the BL_Material */ - bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol, + if (!bl_mat) + bl_mat = new BL_Material(); + ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); visible = ((bl_mat->ras_mode & POLY_VIS)!=0); @@ -873,13 +879,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* uv22 = uv[2]; uv23 = uv[3]; /* then the KX_BlenderMaterial */ - polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer); + if (kx_blmat == NULL) + kx_blmat = new KX_BlenderMaterial(); + kx_blmat->Initialize(scene, bl_mat, skinMesh, lightlayer); + polymat = static_cast(kx_blmat); } else { /* do Texture Face materials */ Image* bima = (tface)? (Image*)tface->tpage: NULL; - STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; + imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; char transp=0; short mode=0, tile=0; @@ -957,9 +966,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bool alpha = (transp == TF_ALPHA || transp == TF_ADD); bool zsort = (mode & TF_ALPHASORT)? alpha: 0; - polymat = new KX_PolygonMaterial(imastr, ma, (int)mface->mat_nr, + if (kx_polymat == NULL) + kx_polymat = new KX_PolygonMaterial(); + kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, tile, tilexrep, tileyrep, mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol); + polymat = static_cast(kx_polymat); if (ma) { polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec; @@ -984,15 +996,17 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* converter->RegisterPolyMaterial(polymat); if(converter->GetMaterials()) { converter->RegisterBlenderMaterial(bl_mat); + // the poly material has been stored in the bucket, next time we must create a new one + bl_mat = NULL; + kx_blmat = NULL; + } else { + // the poly material has been stored in the bucket, next time we must create a new one + kx_polymat = NULL; } } else { - // delete the material objects since they are no longer needed // from now on, use the polygon material from the material bucket - delete polymat; - if(converter->GetMaterials()) { - delete bl_mat; - } polymat = bucket->GetPolyMaterial(); + // keep the material pointers, they will be reused for next face } int nverts = (mface->v4)? 4: 3; @@ -1036,7 +1050,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* delete []layers; dm->release(dm); - + // cleanup material + if (bl_mat) + delete bl_mat; + if (kx_blmat) + delete kx_blmat; + if (kx_polymat) + delete kx_polymat; return meshobj; } diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 022ed71ef7b..c63b9d55306 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -27,6 +27,11 @@ int getNumTexChannels( Material *mat ) } BL_Material::BL_Material() +{ + Initialize(); +} + +void BL_Material::Initialize() { rgb[0] = 0; rgb[1] = 0; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index a0ce37aace0..4f572f95891 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -44,6 +44,7 @@ private: public: // ----------------------------------- BL_Material(); + void Initialize(); int IdMode; unsigned int ras_mode; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 9f11ea11819..70907db608a 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -43,16 +43,30 @@ BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; //static PyObject *gTextureDict = 0; KX_BlenderMaterial::KX_BlenderMaterial( - KX_Scene *scene, - BL_Material *data, - bool skin, - int lightlayer, PyTypeObject *T ) : PyObjectPlus(T), - RAS_IPolyMaterial( - STR_String( data->texname[0] ), - STR_String( data->matname ), // needed for physics! + RAS_IPolyMaterial(), + mMaterial(NULL), + mShader(0), + mBlenderShader(0), + mScene(NULL), + mUserDefBlend(0), + mModified(0), + mConstructed(false), + mPass(0) +{ +} + +void KX_BlenderMaterial::Initialize( + KX_Scene *scene, + BL_Material *data, + bool skin, + int lightlayer) +{ + RAS_IPolyMaterial::Initialize( + data->texname[0], + data->matname, data->materialindex, data->tile, data->tilexrep[0], @@ -62,17 +76,15 @@ KX_BlenderMaterial::KX_BlenderMaterial( ((data->ras_mode &ALPHA)!=0), ((data->ras_mode &ZSORT)!=0), lightlayer - ), - mMaterial(data), - mShader(0), - mBlenderShader(0), - mScene(scene), - mUserDefBlend(0), - mModified(0), - mConstructed(false), - mPass(0) - -{ + ); + mMaterial = data; + mShader = 0; + mBlenderShader = 0; + mScene = scene; + mUserDefBlend = 0; + mModified = 0; + mConstructed = false; + mPass = 0; // -------------------------------- // RAS_IPolyMaterial variables... m_flag |= RAS_BLENDERMAT; @@ -96,7 +108,6 @@ KX_BlenderMaterial::KX_BlenderMaterial( ); } m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(COLLIDER|USE_LIGHT)); - } KX_BlenderMaterial::~KX_BlenderMaterial() @@ -107,7 +118,6 @@ KX_BlenderMaterial::~KX_BlenderMaterial() OnExit(); } - MTFace* KX_BlenderMaterial::GetMTFace(void) const { // fonts on polys diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index eeb919a1bf1..d763ba3ef03 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -24,11 +24,13 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial public: // -------------------------------- KX_BlenderMaterial( + PyTypeObject* T=&Type + ); + void Initialize( class KX_Scene* scene, BL_Material* mat, bool skin, - int lightlayer, - PyTypeObject* T=&Type + int lightlayer ); virtual ~KX_BlenderMaterial(); diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index a8105c1e4f3..a39ff486689 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -51,23 +51,36 @@ #include "KX_PyMath.h" -KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, - Material *material, - int materialindex, - int tile, - int tilexrep, - int tileyrep, - int mode, - int transp, - bool alpha, - bool zsort, - int lightlayer, - struct MTFace* tface, - unsigned int* mcol, - PyTypeObject *T) +KX_PolygonMaterial::KX_PolygonMaterial(PyTypeObject *T) : PyObjectPlus(T), - RAS_IPolyMaterial(texname, - STR_String(material?material->id.name:""), + RAS_IPolyMaterial(), + + m_tface(NULL), + m_mcol(NULL), + m_material(NULL), + m_pymaterial(NULL), + m_pass(0) +{ +} + +void KX_PolygonMaterial::Initialize( + const STR_String &texname, + Material* ma, + int materialindex, + int tile, + int tilexrep, + int tileyrep, + int mode, + int transp, + bool alpha, + bool zsort, + int lightlayer, + struct MTFace* tface, + unsigned int* mcol) +{ + RAS_IPolyMaterial::Initialize( + texname, + ma?ma->id.name:"", materialindex, tile, tilexrep, @@ -76,13 +89,12 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, transp, alpha, zsort, - lightlayer), - m_tface(tface), - m_mcol(mcol), - m_material(material), - m_pymaterial(0), - m_pass(0) -{ + lightlayer); + m_tface = tface; + m_mcol = mcol; + m_material = ma; + m_pymaterial = 0; + m_pass = 0; } KX_PolygonMaterial::~KX_PolygonMaterial() diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index b6f5f373335..89ecb026da9 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -57,8 +57,8 @@ private: mutable int m_pass; public: - - KX_PolygonMaterial(const STR_String &texname, + KX_PolygonMaterial(PyTypeObject *T = &Type); + void Initialize(const STR_String &texname, Material* ma, int materialindex, int tile, @@ -70,8 +70,8 @@ public: bool zsort, int lightlayer, struct MTFace* tface, - unsigned int* mcol, - PyTypeObject *T = &Type); + unsigned int* mcol); + virtual ~KX_PolygonMaterial(); /** diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index e8f451382b9..c10e4040a92 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -36,6 +36,61 @@ #include #endif +void RAS_IPolyMaterial::Initialize( + const STR_String& texname, + const STR_String& matname, + int materialindex, + int tile, + int tilexrep, + int tileyrep, + int mode, + int transp, + bool alpha, + bool zsort, + int lightlayer) +{ + m_texturename = texname; + m_materialname = matname; + m_materialindex = materialindex; + m_tile = tile; + m_tilexrep = tilexrep; + m_tileyrep = tileyrep; + m_drawingmode = mode; + m_transp = transp; + m_alpha = alpha; + m_zsort = zsort; + m_lightlayer = lightlayer; + m_polymatid = m_newpolymatid++; + m_flag = 0; + m_multimode = 0; + m_shininess = 35.0; + m_specular.setValue(0.5,0.5,0.5); + m_specularity = 1.0; + m_diffuse.setValue(0.5,0.5,0.5); +} + +RAS_IPolyMaterial::RAS_IPolyMaterial() + : m_texturename("__Dummy_Texture_Name__"), + m_materialname("__Dummy_Material_Name__"), + m_materialindex(0), + m_tile(0), + m_tilexrep(0), + m_tileyrep(0), + m_drawingmode (0), + m_transp(0), + m_alpha(false), + m_zsort(false), + m_lightlayer(0), + m_polymatid(0), + m_flag(0), + m_multimode(0) +{ + m_shininess = 35.0; + m_specular = MT_Vector3(0.5,0.5,0.5); + m_specularity = 1.0; + m_diffuse = MT_Vector3(0.5,0.5,0.5); +} + RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, int materialindex, diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index dcd8b53402e..35652f528b9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -100,6 +100,7 @@ public: SHADOW =8192 }; + RAS_IPolyMaterial::RAS_IPolyMaterial(); RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, int materialindex, @@ -111,6 +112,17 @@ public: bool alpha, bool zsort, int lightlayer); + void Initialize(const STR_String& texname, + const STR_String& matname, + int materialindex, + int tile, + int tilexrep, + int tileyrep, + int mode, + int transp, + bool alpha, + bool zsort, + int lightlayer); virtual ~RAS_IPolyMaterial() {}; /** @@ -151,7 +163,6 @@ public: virtual void GetMaterialRGBAColor(unsigned char *rgba) const; virtual bool UsesLighting(RAS_IRasterizer *rasty) const; virtual bool UsesObjectColor() const; - /* * PreCalculate texture gen */ From 3bc02088e8d947b6c3efcb567b74e4fca7d40da7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 10:24:12 +0000 Subject: [PATCH 094/444] remove uneeded checks and testMethod from KX_ConstraintWrapper, typo in import_obj --- release/scripts/import_obj.py | 2 +- .../Ketsji/KX_ConstraintWrapper.cpp | 34 ++----------------- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py index 493354601a6..63da4606f38 100644 --- a/release/scripts/import_obj.py +++ b/release/scripts/import_obj.py @@ -587,7 +587,7 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS # so we need to know weather multi_line_face= False - print '\tpassing obj file "%s"...' % filepath, + print '\tparsing obj file "%s"...' % filepath, time_sub= sys.time() file= open(filepath, 'rU') for line in file: #.xreadlines(): diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index 0e6678b8572..cab42f08d2a 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -48,20 +48,12 @@ KX_ConstraintWrapper::KX_ConstraintWrapper( KX_ConstraintWrapper::~KX_ConstraintWrapper() { } -//python integration methods -PyObject* KX_ConstraintWrapper::PyTestMethod(PyObject* args, PyObject* kwds) -{ - Py_RETURN_NONE; -} PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds) { return PyInt_FromLong(m_constraintId); } - - - //python specific stuff PyTypeObject KX_ConstraintWrapper::Type = { PyObject_HEAD_INIT(NULL) @@ -97,35 +89,13 @@ PyObject* KX_ConstraintWrapper::py_getattro_dict() { py_getattro_dict_up(PyObjectPlus); } -int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* pyobj) +int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value) { - int result = 1; - /* what the heck is this supposed to do?, needs attention */ - if (PyList_Check(pyobj)) - { - result = 0; - } - if (PyFloat_Check(pyobj)) - { - result = 0; - - } - if (PyInt_Check(pyobj)) - { - result = 0; - } - if (PyString_Check(pyobj)) - { - result = 0; - } - if (result) - result = PyObjectPlus::py_setattro(attr,pyobj); - return result; + py_setattro_up(PyObjectPlus); }; PyMethodDef KX_ConstraintWrapper::Methods[] = { - {"testMethod",(PyCFunction) KX_ConstraintWrapper::sPyTestMethod, METH_VARARGS}, {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS}, {NULL,NULL} //Sentinel }; From 32b70e333fde4351fd385dab1238ffd74b012663 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 11:16:26 +0000 Subject: [PATCH 095/444] needed this minor change to build on gcc --- source/gameengine/Rasterizer/RAS_IPolygonMaterial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 35652f528b9..1bc03a1db05 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -100,7 +100,7 @@ public: SHADOW =8192 }; - RAS_IPolyMaterial::RAS_IPolyMaterial(); + RAS_IPolyMaterial(); RAS_IPolyMaterial(const STR_String& texname, const STR_String& matname, int materialindex, From 988fbb88dc621d8f41d1b07a729ae5afc24efdaa Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 29 Apr 2009 11:20:07 +0000 Subject: [PATCH 096/444] bugfix #18609 This fixes a commit from Peter, revision 12931, Dec 17 2007 He added quick image scaling code, derived from ppmqscale, http://libdv.sf.net This implementation gave ugly banding. especially visible on dark colors or byte images with very close colors. Solution is to add correct rounding, seems to me normal for such fixed point magic. Optimizing code and keeping quality is tricky dudes! Results for scaling down in sequencer were bad for over a year (2.47 and 2.48 both wrong). --- source/blender/imbuf/intern/scaling.c | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 807b0c84e90..b308915cd62 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -609,34 +609,35 @@ static void shrink_picture_byte( w = (weight1y * weight1x) >> 16; - dst_line1[x].r += (line[0] * w) >> 16; - dst_line1[x].g += (line[1] * w) >> 16; - dst_line1[x].b += (line[2] * w) >> 16; - dst_line1[x].a += (line[3] * w) >> 16; + /* ensure correct rounding, without this you get ugly banding (ton) */ + dst_line1[x].r += (line[0] * w + 32767) >> 16; + dst_line1[x].g += (line[1] * w + 32767) >> 16; + dst_line1[x].b += (line[2] * w + 32767) >> 16; + dst_line1[x].a += (line[3] * w + 32767) >> 16; dst_line1[x].weight += w; w = (weight2y * weight1x) >> 16; - dst_line2[x].r += (line[0] * w) >> 16; - dst_line2[x].g += (line[1] * w) >> 16; - dst_line2[x].b += (line[2] * w) >> 16; - dst_line2[x].a += (line[3] * w) >> 16; + dst_line2[x].r += (line[0] * w + 32767) >> 16; + dst_line2[x].g += (line[1] * w + 32767) >> 16; + dst_line2[x].b += (line[2] * w + 32767) >> 16; + dst_line2[x].a += (line[3] * w + 32767) >> 16; dst_line2[x].weight += w; w = (weight1y * weight2x) >> 16; - dst_line1[x+1].r += (line[0] * w) >> 16; - dst_line1[x+1].g += (line[1] * w) >> 16; - dst_line1[x+1].b += (line[2] * w) >> 16; - dst_line1[x+1].a += (line[3] * w) >> 16; + dst_line1[x+1].r += (line[0] * w + 32767) >> 16; + dst_line1[x+1].g += (line[1] * w + 32767) >> 16; + dst_line1[x+1].b += (line[2] * w + 32767) >> 16; + dst_line1[x+1].a += (line[3] * w + 32767) >> 16; dst_line1[x+1].weight += w; w = (weight2y * weight2x) >> 16; - dst_line2[x+1].r += (line[0] * w) >> 16; - dst_line2[x+1].g += (line[1] * w) >> 16; - dst_line2[x+1].b += (line[2] * w) >> 16; - dst_line2[x+1].a += (line[3] * w) >> 16; + dst_line2[x+1].r += (line[0] * w + 32767) >> 16; + dst_line2[x+1].g += (line[1] * w + 32767) >> 16; + dst_line2[x+1].b += (line[2] * w + 32767) >> 16; + dst_line2[x+1].a += (line[3] * w + 32767) >> 16; dst_line2[x+1].weight += w; x_dst += dx_dst; From f8656d35101317a2b4a00eaf33f6d91d2d28dd7a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 12:43:09 +0000 Subject: [PATCH 097/444] BGE alternative run mode for python controllers. Option to run a function in a module rather then a script from a python controller, this has a number of advantages. - No allocating and freeing the namespace dictionary for every time its triggered (hard to measure the overhead here, but in a test with calling 42240 scripts a second each defining 200 vars, using modules was ~25% faster) - Ability to use external python scripts for game logic. - Convenient debug option that lets you edit scripts while the game engine runs. --- .../blender/makesdna/DNA_controller_types.h | 6 + source/blender/src/buttons_logic.c | 11 +- .../Converter/KX_ConvertControllers.cpp | 51 +++-- .../GameLogic/SCA_PythonController.cpp | 175 +++++++++++++----- .../GameLogic/SCA_PythonController.h | 26 ++- 5 files changed, 193 insertions(+), 76 deletions(-) diff --git a/source/blender/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h index 376f95b0145..b3c82e746c1 100644 --- a/source/blender/makesdna/DNA_controller_types.h +++ b/source/blender/makesdna/DNA_controller_types.h @@ -43,6 +43,9 @@ typedef struct bExpressionCont { typedef struct bPythonCont { struct Text *text; + char module[64]; + int mode; + int flag; /* only used for debug now */ } bPythonCont; typedef struct bController { @@ -77,5 +80,8 @@ typedef struct bController { #define CONT_NEW 4 #define CONT_MASK 8 +/* pyctrl->flag */ +#define CONT_PY_DEBUG 1 + #endif diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index eb65dcc6785..168726c9dab 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1578,7 +1578,16 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+45,yco-24,width-90, 19, &pc->text, ""); + + uiBlockBeginAlign(block); + uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+24,yco-24, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module)"); + if(pc->mode==0) + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+90,yco-24,width-90, 19, &pc->text, "Blender textblock to run as a script"); + else { + uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run eg \"someModule.main\""); + uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restrting, (slow)"); + } + uiBlockEndAlign(block); yco-= ysize; break; diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp index fb100b0a68b..79664ca4622 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.cpp +++ b/source/gameengine/Converter/KX_ConvertControllers.cpp @@ -154,29 +154,38 @@ void BL_ConvertControllers( } case CONT_PYTHON: { - - // we should create a Python controller here - - SCA_PythonController* pyctrl = new SCA_PythonController(gameobj); - gamecontroller = pyctrl; - bPythonCont* pycont = (bPythonCont*) bcontr->data; + SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode); + gamecontroller = pyctrl; + pyctrl->SetDictionary(pythondictionary); - - if (pycont->text) - { - char *buf; - // this is some blender specific code - buf= txt_to_buf(pycont->text); - if (buf) + + if(pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) { + if (pycont->text) { - pyctrl->SetScriptText(STR_String(buf)); - pyctrl->SetScriptName(pycont->text->id.name+2); - MEM_freeN(buf); + char *buf; + // this is some blender specific code + buf= txt_to_buf(pycont->text); + if (buf) + { + pyctrl->SetScriptText(STR_String(buf)); + pyctrl->SetScriptName(pycont->text->id.name+2); + MEM_freeN(buf); + } + } - } - + else { + /* let the controller print any warnings here when importing */ + pyctrl->SetScriptText(STR_String(pycont->module)); + pyctrl->SetScriptName(pycont->module); /* will be something like module.func so using it as the name is OK */ + } + + if(pycont->flag & CONT_PY_DEBUG) { + printf("\nDebuging \"%s\", module for object %s\n\texpect worse performance.\n", pycont->module, blenderobject->id.name+2); + pyctrl->SetDebug(true); + } + LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } @@ -202,9 +211,13 @@ void BL_ConvertControllers( converter->RegisterGameController(gamecontroller, bcontr); if (bcontr->type==CONT_PYTHON) { + SCA_PythonController *pyctrl= static_cast(gamecontroller); /* not strictly needed but gives syntax errors early on and * gives more pradictable performance for larger scripts */ - (static_cast(gamecontroller))->Compile(); + if(pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) + pyctrl->Compile(); + else + pyctrl->Import(); } //done with gamecontroller diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index ab4b5600d3f..39367c1ab9e 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -48,12 +48,17 @@ SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL; SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, + int mode, PyTypeObject* T) : SCA_IController(gameobj, T), m_bytecode(NULL), + m_function(NULL), m_bModified(true), + m_debug(false), + m_mode(mode), m_pythondictionary(NULL) { + } /* @@ -74,15 +79,12 @@ int SCA_PythonController::Release() SCA_PythonController::~SCA_PythonController() { - if (m_bytecode) - { - // - //printf("released python byte script\n"); - Py_DECREF(m_bytecode); - } + //printf("released python byte script\n"); - if (m_pythondictionary) - { + Py_XDECREF(m_bytecode); + Py_XDECREF(m_function); + + if (m_pythondictionary) { // break any circular references in the dictionary PyDict_Clear(m_pythondictionary); Py_DECREF(m_pythondictionary); @@ -95,7 +97,7 @@ CValue* SCA_PythonController::GetReplica() { SCA_PythonController* replica = new SCA_PythonController(*this); // Copy the compiled bytecode if possible. - Py_XINCREF(replica->m_bytecode); + Py_XINCREF(replica->m_function); // this is ok since its not set to NULL replica->m_bModified = replica->m_bytecode == NULL; // The replica->m_pythondictionary is stolen - replace with a copy. @@ -267,58 +269,109 @@ PyAttributeDef SCA_PythonController::Attributes[] = { { NULL } //Sentinel }; -bool SCA_PythonController::Compile() +void SCA_PythonController::ErrorPrint(const char *error_msg) { + // didn't compile, so instead of compile, complain + // something is wrong, tell the user what went wrong + printf("%s - controller \"%s\":\n", error_msg, GetName().Ptr()); + //PyRun_SimpleString(m_scriptText.Ptr()); + PyErr_Print(); + + /* Added in 2.48a, the last_traceback can reference Objects for example, increasing + * their user count. Not to mention holding references to wrapped data. + * This is especially bad when the PyObject for the wrapped data is free'd, after blender + * has alredy dealocated the pointer */ + PySys_SetObject( (char *)"last_traceback", NULL); + PyErr_Clear(); /* just to be sure */ +} + +bool SCA_PythonController::Compile() +{ //printf("py script modified '%s'\n", m_scriptName.Ptr()); + m_bModified= false; // if a script already exists, decref it before replace the pointer to a new script - if (m_bytecode) - { + if (m_bytecode) { Py_DECREF(m_bytecode); m_bytecode=NULL; } + // recompile the scripttext into bytecode m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input); - m_bModified=false; - if (m_bytecode) - { - + if (m_bytecode) { return true; - } - else { - // didn't compile, so instead of compile, complain - // something is wrong, tell the user what went wrong - printf("Python compile error from controller \"%s\": \n", GetName().Ptr()); - //PyRun_SimpleString(m_scriptText.Ptr()); - PyErr_Print(); - - /* Added in 2.48a, the last_traceback can reference Objects for example, increasing - * their user count. Not to mention holding references to wrapped data. - * This is especially bad when the PyObject for the wrapped data is free'd, after blender - * has alredy dealocated the pointer */ - PySys_SetObject( (char *)"last_traceback", NULL); - PyErr_Clear(); /* just to be sure */ - + } else { + ErrorPrint("Python error compiling script"); return false; } } +bool SCA_PythonController::Import() +{ + //printf("py module modified '%s'\n", m_scriptName.Ptr()); + m_bModified= false; + + /* incase we re-import */ + Py_XDECREF(m_function); + m_function= NULL; + + vector module_func = m_scriptText.Explode('.'); + + if(module_func.size() != 2 || module_func[0].Length()==0 || module_func[1].Length()==0) { + printf("Python module name formatting error \"%s\":\n\texpected \"SomeModule.Func\", got \"%s\"", GetName().Ptr(), m_scriptText.Ptr()); + return false; + } + + PyObject *mod = PyImport_ImportModule(module_func[0]); + if(mod && m_debug) { + Py_DECREF(mod); /* getting a new one so dont hold a ref to the old one */ + mod= PyImport_ReloadModule(mod); + } + + if(mod==NULL) { + ErrorPrint("Python module not found"); + return false; + } + Py_DECREF(mod); /* will be added to sys.modules so no need to keep a ref */ + + + PyObject *dict= PyModule_GetDict(mod); + m_function= PyDict_GetItemString(dict, module_func[1]); /* borrow */ + + if(m_function==NULL) { + printf("Python module error \"%s\":\n \"%s\" module fount but function missing\n", GetName().Ptr(), m_scriptText.Ptr()); + return false; + } + + if(!PyCallable_Check(m_function)) { + printf("Python module function error \"%s\":\n \"%s\" not callable", GetName().Ptr(), m_scriptText.Ptr()); + return false; + } + + Py_INCREF(m_function); + Py_INCREF(mod); + + return true; +} + void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) { m_sCurrentController = this; m_sCurrentLogicManager = logicmgr; - if (m_bModified) - { - if (Compile()==false) // sets m_bModified to false - return; - } - if (!m_bytecode) { - return; - } - + PyObject *excdict= NULL; + PyObject* resultobj= NULL; + switch(m_mode) { + case SCA_PYEXEC_SCRIPT: + { + if (m_bModified) + if (Compile()==false) // sets m_bModified to false + return; + if (!m_bytecode) + return; + /* * This part here with excdict is a temporary patch * to avoid python/gameengine crashes when python @@ -337,10 +390,28 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) * should always ensure excdict is cleared). */ - PyObject *excdict= PyDict_Copy(m_pythondictionary); - PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode, - excdict, excdict); - + excdict= PyDict_Copy(m_pythondictionary); + resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode, excdict, excdict); + /* PyRun_SimpleString(m_scriptText.Ptr()); */ + break; + } + case SCA_PYEXEC_MODULE: + { + if (m_bModified || m_debug) + if (Import()==false) // sets m_bModified to false + return; + if (!m_function) + return; + + resultobj = PyObject_CallObject(m_function, NULL); + break; + } + + } /* end switch */ + + + + /* Free the return value and print the error */ if (resultobj) { Py_DECREF(resultobj); @@ -357,14 +428,16 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) * has alredy dealocated the pointer */ PySys_SetObject( (char *)"last_traceback", NULL); PyErr_Clear(); /* just to be sure */ - - //PyRun_SimpleString(m_scriptText.Ptr()); } - - // clear after PyErrPrint - seems it can be using - // something in this dictionary and crash? - PyDict_Clear(excdict); - Py_DECREF(excdict); + + if(excdict) /* Only for SCA_PYEXEC_SCRIPT types */ + { + /* clear after PyErrPrint - seems it can be using + * something in this dictionary and crash? */ + PyDict_Clear(excdict); + Py_DECREF(excdict); + } + m_triggeredSensors.erase(m_triggeredSensors.begin(), m_triggeredSensors.end()); m_sCurrentController = NULL; } diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index f10c4e47ebb..12307632b06 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -42,23 +42,35 @@ class SCA_IObject; class SCA_PythonController : public SCA_IController { Py_Header; - struct _object * m_bytecode; + struct _object * m_bytecode; /* SCA_PYEXEC_SCRIPT only */ + PyObject* m_function; /* SCA_PYEXEC_MODULE only */ bool m_bModified; - + bool m_debug; /* use with SCA_PYEXEC_MODULE for reloading every logic run */ + int m_mode; + protected: STR_String m_scriptText; STR_String m_scriptName; - PyObject* m_pythondictionary; + PyObject* m_pythondictionary; /* for SCA_PYEXEC_SCRIPT only */ + PyObject* m_pythonfunction; /* for SCA_PYEXEC_MODULE only */ + std::vector m_triggeredSensors; + + public: + enum SCA_PyExecMode + { + SCA_PYEXEC_SCRIPT = 0, + SCA_PYEXEC_MODULE, + SCA_PYEXEC_MAX + }; - public: static SCA_PythonController* m_sCurrentController; // protected !!! //for debugging //virtual CValue* AddRef(); //virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap) - SCA_PythonController(SCA_IObject* gameobj,PyTypeObject* T = &Type); + SCA_PythonController(SCA_IObject* gameobj, int mode, PyTypeObject* T = &Type); virtual ~SCA_PythonController(); virtual CValue* GetReplica(); @@ -67,10 +79,14 @@ class SCA_PythonController : public SCA_IController void SetScriptText(const STR_String& text); void SetScriptName(const STR_String& name); void SetDictionary(PyObject* pythondictionary); + void SetDebug(bool debug) { m_debug = debug; } void AddTriggeredSensor(class SCA_ISensor* sensor) { m_triggeredSensors.push_back(sensor); } int IsTriggered(class SCA_ISensor* sensor); bool Compile(); + bool Import(); + void ErrorPrint(const char *error_msg); + static const char* sPyGetCurrentController__doc__; static PyObject* sPyGetCurrentController(PyObject* self); From 3b19b6c33fa5a68309efe99c49fca0df60db02aa Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 29 Apr 2009 15:25:13 +0000 Subject: [PATCH 098/444] 2.5+ file read provision for 2.49 I've managed to find a basic fail-safe method to prevent using the read data with an OK popup. I then still will read the file, but wait for user confirmation to continue, or just free the database. The pupup tells the user that at least animation data will be lost. For background renders of 2.5+ things are more tricky, so here I've added a default failure to read, returning 0, which will typically gracefully quit blender. --- source/blender/blenkernel/intern/blender.c | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 5dcccc56d06..906971f8bae 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -423,18 +423,31 @@ static void setup_app_data(BlendFileData *bfd, char *filename) MEM_freeN(bfd); } -static void handle_subversion_warning(Main *main) +static int handle_subversion_warning(Main *main) { if(main->minversionfile > BLENDER_VERSION || (main->minversionfile == BLENDER_VERSION && main->minsubversionfile > BLENDER_SUBVERSION)) { + extern int okee(char *str, ...); // XXX BAD LEVEL, DO NOT PORT TO 2.5! char str[128]; - - sprintf(str, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile); - error(str); + + if(main->minversionfile >= 250) { + sprintf(str, "You have opened a %d file, key information will get lost, like animation data. Continue?", main->minversionfile); + + if(G.background) { + printf("ERROR: cannot render %d file\n", main->versionfile); + return 0; + } + else + return okee(str); + } + else { + sprintf(str, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile); + error(str); + } } - + return 1; } /* returns: @@ -458,9 +471,14 @@ int BKE_read_file(char *dir, void *type_r) if (type_r) *((BlenFileType*)type_r)= bfd->type; - setup_app_data(bfd, dir); + if(0==handle_subversion_warning(bfd->main)) { + free_main(bfd->main); + MEM_freeN(bfd); + bfd= NULL; + } + else + setup_app_data(bfd, dir); // frees BFD - handle_subversion_warning(G.main); } else { error("Loading %s failed: %s", dir, BLO_bre_as_string(bre)); From f56bfbdd0c25feb815accdd377cf0b743c5d7e19 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 29 Apr 2009 16:07:10 +0000 Subject: [PATCH 099/444] Bugfix from own testing: Blender crashed, when started in debug -d, with compositor, after render. Reason was the BKE_image_print_memlist() which reads the ibuf->rect from all images, but for Image types "VIEWER" that's not valid, this data is coming from other sources. --- source/blender/blenkernel/intern/image.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 01d8ed4d41c..444c7c080ea 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -640,6 +640,11 @@ static uintptr_t image_mem_size(Image *ima) uintptr_t size = 0; size= 0; + + /* viewers have memory depending on other rules, has no valid rect pointer */ + if(ima->source==IMA_SRC_VIEWER) + return 0; + for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) { if(ibuf->rect) size += MEM_allocN_len(ibuf->rect); else if(ibuf->rect_float) size += MEM_allocN_len(ibuf->rect_float); From 133c91dd2f54bbee0343480dc7c711cdbc11b78b Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 29 Apr 2009 16:16:08 +0000 Subject: [PATCH 100/444] Bugfix #18649 Grease pencil, floating panel, "Delete last stroke" crashed when there were no strokes. Simple NULL check added. --- source/blender/src/drawgpencil.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c index 5cabb38887a..4ec9b587b58 100644 --- a/source/blender/src/drawgpencil.c +++ b/source/blender/src/drawgpencil.c @@ -139,12 +139,14 @@ void gp_ui_delstroke_cb (void *gpd, void *gpl) { bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); - if (gpf->framenum != CFRA) return; + if (gpf) { + if (gpf->framenum != CFRA) return; - gpencil_layer_setactive(gpd, gpl); - gpencil_frame_delete_laststroke(gpl, gpf); - - scrarea_queue_winredraw(curarea); + gpencil_layer_setactive(gpd, gpl); + gpencil_frame_delete_laststroke(gpl, gpf); + + scrarea_queue_winredraw(curarea); + } } /* delete active frame of active layer */ From 11ad5f838992857f8bd494bbe0adb0d91963514f Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 29 Apr 2009 16:41:18 +0000 Subject: [PATCH 101/444] Bug, reported by venomgfx: Scrub frames in Sequencer image window stopped working. Was in a commit from Joshua last july, with greasepencil fixes. No idea why he disabled it, doesn't seem to harm gpencil at all (not in sequencer supported). --- source/blender/src/space.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index c6510b780d8..8ff2b526ae8 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -5023,7 +5023,7 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) switch(event) { case LEFTMOUSE: - if(sseq->mainb==0 && view2dmove(event)==0) { + if(sseq->mainb==0 || view2dmove(event)==0) { first= 1; set_special_seq_update(1); From d6c525d624ea98bf6eeac1a7f3483f41fed1ef4f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 16:48:00 +0000 Subject: [PATCH 102/444] attempt to fix for py2.3 --- source/gameengine/GameLogic/SCA_PythonController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 39367c1ab9e..b9f8dde89bf 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -323,7 +323,7 @@ bool SCA_PythonController::Import() return false; } - PyObject *mod = PyImport_ImportModule(module_func[0]); + PyObject *mod = PyImport_ImportModule((char *)module_func[0].Ptr()); if(mod && m_debug) { Py_DECREF(mod); /* getting a new one so dont hold a ref to the old one */ mod= PyImport_ReloadModule(mod); From 81dfdf8374382c766c88bbed421ed70c02565234 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 16:54:45 +0000 Subject: [PATCH 103/444] ifdef's for future py3 support, after this adding py3 can mostly be done with defines or batch renaming funcs (with the exception of CListValue slicing) . No changes for py2.x. --- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 1 + .../Converter/BL_ActionActuator.cpp | 9 ++- .../Converter/BL_ShapeActionActuator.cpp | 9 ++- source/gameengine/Expressions/InputParser.cpp | 19 ++++++ source/gameengine/Expressions/ListValue.cpp | 17 ++++- .../gameengine/Expressions/PyObjectPlus.cpp | 7 +- source/gameengine/Expressions/Value.cpp | 27 +++++++- .../GameLogic/SCA_2DFilterActuator.cpp | 9 ++- .../GameLogic/SCA_ANDController.cpp | 9 ++- .../GameLogic/SCA_ActuatorSensor.cpp | 9 ++- .../gameengine/GameLogic/SCA_AlwaysSensor.cpp | 9 ++- .../gameengine/GameLogic/SCA_DelaySensor.cpp | 9 ++- .../gameengine/GameLogic/SCA_ILogicBrick.cpp | 9 ++- source/gameengine/GameLogic/SCA_IObject.cpp | 9 ++- source/gameengine/GameLogic/SCA_ISensor.cpp | 9 ++- .../GameLogic/SCA_JoystickSensor.cpp | 9 ++- .../GameLogic/SCA_KeyboardSensor.cpp | 9 ++- .../gameengine/GameLogic/SCA_MouseSensor.cpp | 9 ++- .../GameLogic/SCA_NANDController.cpp | 9 ++- .../GameLogic/SCA_NORController.cpp | 9 ++- .../gameengine/GameLogic/SCA_ORController.cpp | 9 ++- .../GameLogic/SCA_PropertyActuator.cpp | 9 ++- .../GameLogic/SCA_PropertySensor.cpp | 9 ++- .../GameLogic/SCA_PythonController.cpp | 9 ++- .../GameLogic/SCA_RandomActuator.cpp | 9 ++- .../gameengine/GameLogic/SCA_RandomSensor.cpp | 9 ++- .../GameLogic/SCA_XNORController.cpp | 9 ++- .../GameLogic/SCA_XORController.cpp | 9 ++- source/gameengine/Ketsji/BL_Shader.cpp | 9 ++- .../KXNetwork/KX_NetworkMessageActuator.cpp | 9 ++- .../KXNetwork/KX_NetworkMessageSensor.cpp | 9 ++- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 9 ++- source/gameengine/Ketsji/KX_CDActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_Camera.cpp | 9 ++- .../gameengine/Ketsji/KX_CameraActuator.cpp | 9 ++- .../Ketsji/KX_ConstraintActuator.cpp | 9 ++- .../Ketsji/KX_ConstraintWrapper.cpp | 9 ++- source/gameengine/Ketsji/KX_GameActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_GameObject.cpp | 9 ++- source/gameengine/Ketsji/KX_IpoActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_Light.cpp | 9 ++- source/gameengine/Ketsji/KX_MeshProxy.cpp | 9 ++- .../gameengine/Ketsji/KX_MouseFocusSensor.cpp | 9 ++- source/gameengine/Ketsji/KX_NearSensor.cpp | 9 ++- .../gameengine/Ketsji/KX_ObjectActuator.cpp | 9 ++- .../gameengine/Ketsji/KX_ParentActuator.cpp | 9 ++- .../Ketsji/KX_PhysicsObjectWrapper.cpp | 9 ++- source/gameengine/Ketsji/KX_PolyProxy.cpp | 9 ++- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 9 ++- .../Ketsji/KX_PyConstraintBinding.cpp | 18 ++++- source/gameengine/Ketsji/KX_PythonInit.cpp | 65 ++++++++++++++++++- source/gameengine/Ketsji/KX_RadarSensor.cpp | 9 ++- source/gameengine/Ketsji/KX_RaySensor.cpp | 9 ++- .../Ketsji/KX_SCA_AddObjectActuator.cpp | 9 ++- .../Ketsji/KX_SCA_DynamicActuator.cpp | 9 ++- .../Ketsji/KX_SCA_EndObjectActuator.cpp | 9 ++- .../Ketsji/KX_SCA_ReplaceMeshActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_Scene.cpp | 9 ++- source/gameengine/Ketsji/KX_SceneActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_SoundActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_StateActuator.cpp | 9 ++- source/gameengine/Ketsji/KX_TouchSensor.cpp | 9 ++- .../gameengine/Ketsji/KX_TrackToActuator.cpp | 9 ++- .../gameengine/Ketsji/KX_VehicleWrapper.cpp | 9 ++- source/gameengine/Ketsji/KX_VertexProxy.cpp | 9 ++- .../Ketsji/KX_VisibilityActuator.cpp | 9 ++- .../VideoTexture/FilterBlueScreen.cpp | 7 +- .../gameengine/VideoTexture/FilterColor.cpp | 21 +++++- .../gameengine/VideoTexture/FilterNormal.cpp | 7 +- .../gameengine/VideoTexture/FilterSource.cpp | 21 +++++- source/gameengine/VideoTexture/ImageBuff.cpp | 7 +- source/gameengine/VideoTexture/ImageMix.cpp | 7 +- .../gameengine/VideoTexture/ImageRender.cpp | 14 +++- .../gameengine/VideoTexture/ImageViewport.cpp | 7 +- source/gameengine/VideoTexture/Texture.cpp | 7 +- .../gameengine/VideoTexture/VideoFFmpeg.cpp | 14 +++- .../gameengine/VideoTexture/blendVideoTex.cpp | 24 ++++++- 77 files changed, 677 insertions(+), 144 deletions(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index e393b6d9af4..0239027f2cb 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -268,6 +268,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat // 'normal' object glMultMatrixd(oglmatrix); } + glMultMatrixd(oglmatrix); } } diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 3ad55f5ee12..ee97e325a8e 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -942,8 +942,13 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, /* ------------------------------------------------------------------------- */ PyTypeObject BL_ActionActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "BL_ActionActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 60d26b9a99f..5fea568dcb2 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -418,8 +418,13 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame) /* Integration hooks ------------------------------------------------------- */ PyTypeObject BL_ShapeActionActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "BL_ShapeActionActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index 834dff7af89..d45a9375dc7 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -658,10 +658,29 @@ static PyMethodDef CParserMethods[] = { NULL,NULL} // Sentinel }; + +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef Expression_module_def = { + {}, /* m_base */ + "Expression", /* m_name */ + 0, /* m_doc */ + 0, /* m_size */ + CParserMethods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif + extern "C" { void initExpressionModule(void) { +#if (PY_VERSION_HEX >= 0x03000000) + PyModule_Create(&Expression_module_def); +#else Py_InitModule("Expression",CParserMethods); +#endif } } diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 3596128f12d..fc6b9299146 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -212,9 +212,15 @@ static PySequenceMethods listvalue_as_sequence = { listvalue_buffer_concat, /*sq_concat*/ NULL, /*sq_repeat*/ listvalue_buffer_item, /*sq_item*/ +#if (PY_VERSION_HEX >= 0x03000000) // TODO, slicing in py3? + NULL, + NULL, + NULL, +#else listvalue_buffer_slice, /*sq_slice*/ - NULL, /*sq_ass_item*/ - NULL /*sq_ass_slice*/ + (ssizeobjargproc)NULL, /*sq_ass_item*/ + NULL, /*sq_ass_slice*/ +#endif }; @@ -229,8 +235,13 @@ static PyMappingMethods instance_as_mapping = { PyTypeObject CListValue::Type = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "CListValue", /*tp_name*/ sizeof(PyObjectPlus_Proxy), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 8bd34cdc73b..e6b49332273 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -56,8 +56,13 @@ PyTypeObject PyObjectPlus::Type = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "PyObjectPlus", /*tp_name*/ sizeof(PyObjectPlus_Proxy), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 088b5cb98a4..fbd86cc4022 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -36,8 +36,13 @@ double CValue::m_sZeroVec[3] = {0.0,0.0,0.0}; #ifndef NO_EXP_PYTHON_EMBEDDING PyTypeObject CValue::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "CValue", sizeof(PyObjectPlus_Proxy), 0, @@ -751,10 +756,28 @@ PyObject* CValue::PyMake(PyObject* ignored,PyObject* args) } */ +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef CValue_module_def = { + {}, /* m_base */ + "CValue", /* m_name */ + 0, /* m_doc */ + 0, /* m_size */ + CValueMethods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif + extern "C" { void initCValue(void) { +#if (PY_VERSION_HEX >= 0x03000000) + PyModule_Create(&CValue_module_def); +#else Py_InitModule("CValue",CValueMethods); +#endif } } diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index ed834587414..fb72eefb4a4 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -108,8 +108,13 @@ void SCA_2DFilterActuator::SetShaderText(STR_String text) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_2DFilterActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_2DFilterActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index ed2372200e9..1b151cbe615 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -107,8 +107,13 @@ CValue* SCA_ANDController::GetReplica() /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_ANDController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_ANDController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index 928060d7394..464797fd776 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -122,8 +122,13 @@ void SCA_ActuatorSensor::Update() /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_ActuatorSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_ActuatorSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index 941f3b55b44..19d19b6e0be 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -105,8 +105,13 @@ bool SCA_AlwaysSensor::Evaluate(CValue* event) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_AlwaysSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_AlwaysSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index 15e805a657c..4752d0eb345 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -131,8 +131,13 @@ bool SCA_DelaySensor::Evaluate(CValue* event) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_DelaySensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_DelaySensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 8439dbac268..84babda1d7a 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -209,8 +209,13 @@ CValue* SCA_ILogicBrick::GetEvent() /* python stuff */ PyTypeObject SCA_ILogicBrick::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_ILogicBrick", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 8e599e6411a..b3c4708978d 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -375,8 +375,13 @@ void SCA_IObject::SetState(unsigned int state) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_IObject::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_IObject", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index b556c14831e..4d69216ed0b 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -393,8 +393,13 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset, /* ----------------------------------------------- */ PyTypeObject SCA_ISensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_ISensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index b9d99177259..34d63a4ee2b 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -266,8 +266,13 @@ bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_JoystickSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_JoystickSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index 5dcdb222713..821d2155d2a 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -612,8 +612,13 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, /* ------------------------------------------------------------------------- */ PyTypeObject SCA_KeyboardSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_KeyboardSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index 65942327e68..46be6ad9e16 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -296,8 +296,13 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, /* ------------------------------------------------------------------------- */ PyTypeObject SCA_MouseSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_MouseSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index ab5c39dc039..4643a42a4be 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -107,8 +107,13 @@ CValue* SCA_NANDController::GetReplica() /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_NANDController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_NANDController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index 918e6a348ae..a0e9fcb239c 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -107,8 +107,13 @@ CValue* SCA_NORController::GetReplica() /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_NORController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_NORController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 034c3ee29cd..87e6d19d008 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -99,8 +99,13 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_ORController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_ORController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index f3ca63066c9..33dc83506f3 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -228,8 +228,13 @@ void SCA_PropertyActuator::Relink(GEN_Map *obj_map) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_PropertyActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_PropertyActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index 7953698c6ef..c78283db423 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -306,8 +306,13 @@ int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_PropertySensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_PropertySensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index b9f8dde89bf..33207950697 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -223,8 +223,13 @@ const char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuato const char SCA_PythonController::GetActuators_doc[] = "getActuator"; PyTypeObject SCA_PythonController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_PythonController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index 91110425f7f..2db871c77cf 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -310,8 +310,13 @@ void SCA_RandomActuator::enforceConstraints() { /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_RandomActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_RandomActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 70a23124929..5c109bac024 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -127,8 +127,13 @@ bool SCA_RandomSensor::Evaluate(CValue* event) /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_RandomSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_RandomSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index 13d50100d6c..947e8b7a68a 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -111,8 +111,13 @@ CValue* SCA_XNORController::GetReplica() /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_XNORController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_XNORController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 6613742a080..d9e41c2b27e 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -111,8 +111,13 @@ CValue* SCA_XORController::GetReplica() /* Integration hooks ------------------------------------------------------- */ PyTypeObject SCA_XORController::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "SCA_XORController", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index 2b3612ec3ae..c5c517c8a65 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -776,8 +776,13 @@ PyAttributeDef BL_Shader::Attributes[] = { }; PyTypeObject BL_Shader::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "BL_Shader", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp index 712f64d5f8f..7f21c490e67 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp @@ -102,8 +102,13 @@ CValue* KX_NetworkMessageActuator::GetReplica() /* Integration hooks -------------------------------------------------- */ PyTypeObject KX_NetworkMessageActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_NetworkMessageActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index d770465e1ea..82e2437064b 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -166,8 +166,13 @@ bool KX_NetworkMessageSensor::IsPositiveTrigger() /* Integration hooks --------------------------------------------------- */ PyTypeObject KX_NetworkMessageSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_NetworkMessageSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 70907db608a..5f08739ea14 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -788,8 +788,13 @@ PyAttributeDef KX_BlenderMaterial::Attributes[] = { }; PyTypeObject KX_BlenderMaterial::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_BlenderMaterial", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index a0b2c73901f..7f8505afa3d 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -155,8 +155,13 @@ bool KX_CDActuator::Update() /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_CDActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SoundActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index bc2c2fc33b0..3ea01cca5ca 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -512,8 +512,13 @@ PyAttributeDef KX_Camera::Attributes[] = { }; PyTypeObject KX_Camera::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_Camera", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 38a68752958..e701a680511 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -369,8 +369,13 @@ bool KX_CameraActuator::string2axischoice(const char *axisString) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_CameraActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_CameraActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index 34102132db8..c9cb8e1b942 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -566,8 +566,13 @@ bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_ConstraintActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_ConstraintActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index cab42f08d2a..c63f9e57ed2 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -56,8 +56,13 @@ PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds //python specific stuff PyTypeObject KX_ConstraintWrapper::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_ConstraintWrapper", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index a46318d0468..48d7dcd84a2 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -206,8 +206,13 @@ bool KX_GameActuator::Update() /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_GameActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_GameActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index ed162238e8a..20113afaae2 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1322,8 +1322,13 @@ PyMappingMethods KX_GameObject::Mapping = { }; PyTypeObject KX_GameObject::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_GameObject", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index df80085d9f2..efe01993b08 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -413,8 +413,13 @@ int KX_IpoActuator::string2mode(char* modename) { /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_IpoActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_IpoActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 498eb7262b5..0f90bfd8a02 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -179,8 +179,13 @@ PyObject* KX_LightObject::py_getattro_dict() { PyTypeObject KX_LightObject::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_LightObject", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 009364a3d7b..eede3a0e832 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -46,8 +46,13 @@ #include "PyObjectPlus.h" PyTypeObject KX_MeshProxy::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_MeshProxy", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index d141aa482c8..9106902ca0e 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -335,8 +335,13 @@ const MT_Vector3& KX_MouseFocusSensor::HitNormal() const /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_MouseFocusSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_MouseFocusSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index 2f1a3af78fa..e7f05555b64 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -269,8 +269,13 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData /* ------------------------------------------------------------------------- */ PyTypeObject KX_NearSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_NearSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index 86ae082523f..e3d7a0f4b71 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -274,8 +274,13 @@ bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_ObjectActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_ObjectActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index ffd7185f235..37d2e50cdb6 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -137,8 +137,13 @@ bool KX_ParentActuator::Update() /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_ParentActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_ParentActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp index c0c15b5599c..c968e50957e 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp @@ -113,8 +113,13 @@ PyAttributeDef KX_PhysicsObjectWrapper::Attributes[] = { //python specific stuff PyTypeObject KX_PhysicsObjectWrapper::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_PhysicsObjectWrapper", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index 33e215387b7..ca38117a9e7 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -39,8 +39,13 @@ #include "KX_PyMath.h" PyTypeObject KX_PolyProxy::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_PolyProxy", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index a39ff486689..918c251599e 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -234,8 +234,13 @@ PyAttributeDef KX_PolygonMaterial::Attributes[] = { }; PyTypeObject KX_PolygonMaterial::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_PolygonMaterial", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 2c65c184a9c..e801e9c5858 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -565,6 +565,19 @@ static struct PyMethodDef physicsconstraints_methods[] = { }; +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef PhysicsConstraints_module_def = { + {}, /* m_base */ + "PhysicsConstraints", /* m_name */ + PhysicsConstraints_module_documentation, /* m_doc */ + 0, /* m_size */ + physicsconstraints_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif PyObject* initPythonConstraintBinding() { @@ -573,10 +586,13 @@ PyObject* initPythonConstraintBinding() PyObject* m; PyObject* d; - +#if (PY_VERSION_HEX >= 0x03000000) + m = PyModule_Create(&PhysicsConstraints_module_def); +#else m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, PhysicsConstraints_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); +#endif // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index f82110c2bd2..22e092e8277 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1073,7 +1073,19 @@ static char Rasterizer_module_documentation[] = "This is the Python API for the game engine of Rasterizer" ; - +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef GameLogic_module_def = { + {}, /* m_base */ + "GameLogic", /* m_name */ + GameLogic_module_documentation, /* m_doc */ + 0, /* m_size */ + game_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack to get gravity hook { @@ -1087,9 +1099,14 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack gUseVisibilityTemp=false; // Create the module and add the functions + +#if (PY_VERSION_HEX >= 0x03000000) + m = PyModule_Create(&GameLogic_module_def); +#else m = Py_InitModule4("GameLogic", game_methods, GameLogic_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); +#endif // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -1498,15 +1515,18 @@ void setSandbox(TPythonSecurityLevel level) */ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv) { +#if (PY_VERSION_HEX < 0x03000000) STR_String pname = progname; Py_SetProgramName(pname.Ptr()); +#endif Py_NoSiteFlag=1; Py_FrozenFlag=1; Py_Initialize(); +#if (PY_VERSION_HEX < 0x03000000) if(argv) /* browser plugins dont currently set this */ PySys_SetArgv(argc, argv); - +#endif //importBlenderModules() setSandbox(level); @@ -1530,8 +1550,10 @@ void exitGamePlayerPythonScripting() */ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie) { +#if (PY_VERSION_HEX < 0x03000000) STR_String pname = progname; Py_SetProgramName(pname.Ptr()); +#endif Py_NoSiteFlag=1; Py_FrozenFlag=1; @@ -1587,6 +1609,19 @@ void exitGamePythonScripting() } +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef Rasterizer_module_def = { + {}, /* m_base */ + "Rasterizer", /* m_name */ + Rasterizer_module_documentation, /* m_doc */ + 0, /* m_size */ + rasterizer_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) { @@ -1599,9 +1634,13 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) PyObject* item; // Create the module and add the functions +#if (PY_VERSION_HEX >= 0x03000000) + m = PyModule_Create(&Rasterizer_module_def); +#else m = Py_InitModule4("Rasterizer", rasterizer_methods, Rasterizer_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); +#endif // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -1651,7 +1690,12 @@ static PyObject* gPyEventToString(PyObject*, PyObject* value) dict = PyModule_GetDict(mod); while (PyDict_Next(dict, &pos, &key, &val)) { +#if (PY_VERSION_HEX >= 0x03000000) + if (PyObject_RichCompareBool(value, val, Py_EQ)) { +#else if (PyObject_Compare(value, val)==0) { +#endif + ret = key; break; } @@ -1693,6 +1737,19 @@ static struct PyMethodDef gamekeys_methods[] = { }; +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef GameKeys_module_def = { + {}, /* m_base */ + "GameKeys", /* m_name */ + GameKeys_module_documentation, /* m_doc */ + 0, /* m_size */ + gamekeys_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif PyObject* initGameKeys() { @@ -1701,9 +1758,13 @@ PyObject* initGameKeys() PyObject* item; // Create the module and add the functions +#if (PY_VERSION_HEX >= 0x03000000) + m = PyModule_Create(&GameKeys_module_def); +#else m = Py_InitModule4("GameKeys", gamekeys_methods, GameKeys_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); +#endif // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index bf4b0f67e03..1959dd52046 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -232,8 +232,13 @@ PyObject* KX_RadarSensor::PyGetConeHeight() { /* Python Integration Hooks */ /* ------------------------------------------------------------------------- */ PyTypeObject KX_RadarSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_RadarSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index ea9356a49d1..43d8806fc68 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -320,8 +320,13 @@ bool KX_RaySensor::Evaluate(CValue* event) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_RaySensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_RaySensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index dd9d63f5cd9..2fd786e44e3 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -166,8 +166,13 @@ void KX_SCA_AddObjectActuator::Relink(GEN_Map *obj_map) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_SCA_AddObjectActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SCA_AddObjectActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index 4bc42686d78..af5631b4403 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -51,8 +51,13 @@ PyTypeObject KX_SCA_DynamicActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SCA_DynamicActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp index a0b411dd3a9..728254e7f48 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -92,8 +92,13 @@ CValue* KX_SCA_EndObjectActuator::GetReplica() /* ------------------------------------------------------------------------- */ PyTypeObject KX_SCA_EndObjectActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SCA_EndObjectActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 8b87253d0a3..730d1ed49e6 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -53,8 +53,13 @@ PyTypeObject KX_SCA_ReplaceMeshActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SCA_ReplaceMeshActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 1c1cc881d17..fd244037722 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1595,8 +1595,13 @@ double KX_Scene::getSuspendedDelta() //Python PyTypeObject KX_Scene::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_Scene", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 4447ff48766..1cce93fbcc5 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -223,8 +223,13 @@ KX_Scene* KX_SceneActuator::FindScene(char * sceneName) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_SceneActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SceneActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index db3d92ffd79..15eb354ee79 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -232,8 +232,13 @@ void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_SoundActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_SoundActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index 71ffa16cb54..2cbb42b3311 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -107,8 +107,13 @@ KX_StateActuator::Update() /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_StateActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_StateActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 2addfc31ff3..f000c16041a 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -246,8 +246,13 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll /* ------------------------------------------------------------------------- */ /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_TouchSensor::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_TouchSensor", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 808bf0a55b5..672b9e739ba 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -425,8 +425,13 @@ bool KX_TrackToActuator::Update(double curtime, bool frame) /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_TrackToActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_TrackToActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 5a0ec3515f6..e43a5caa50a 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -273,8 +273,13 @@ PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* args) //python specific stuff PyTypeObject KX_VehicleWrapper::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_VehicleWrapper", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 629fadff86a..93ff35b5a9d 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -37,8 +37,13 @@ #include "KX_PyMath.h" PyTypeObject KX_VertexProxy::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_VertexProxy", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index ed12a88ad6a..46a1db9378a 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -92,8 +92,13 @@ KX_VisibilityActuator::Update() /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_VisibilityActuator::Type = { - PyObject_HEAD_INIT(NULL) - 0, +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "KX_VisibilityActuator", sizeof(PyObjectPlus_Proxy), 0, diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp index 43d7566102a..6b23105a278 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -135,8 +135,13 @@ static PyGetSetDef filterBSGetSets[] = // define python type PyTypeObject FilterBlueScreenType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterBlueScreen", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index 22ee729b200..5ff1f7f11ce 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -41,8 +41,13 @@ static PyGetSetDef filterGrayGetSets[] = // define python type PyTypeObject FilterGrayType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterGray", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -173,8 +178,13 @@ static PyGetSetDef filterColorGetSets[] = // define python type PyTypeObject FilterColorType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterColor", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -307,8 +317,13 @@ static PyGetSetDef filterLevelGetSets[] = // define python type PyTypeObject FilterLevelType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterLevel", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index a7266967efb..9a2b1e90d5a 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -124,8 +124,13 @@ static PyGetSetDef filterNormalGetSets[] = // define python type PyTypeObject FilterNormalType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterNormal", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp index f3676e93a6d..4c75e14bbac 100644 --- a/source/gameengine/VideoTexture/FilterSource.cpp +++ b/source/gameengine/VideoTexture/FilterSource.cpp @@ -36,8 +36,13 @@ http://www.gnu.org/copyleft/lesser.txt. // define python type PyTypeObject FilterRGB24Type = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterRGB24", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -82,8 +87,13 @@ PyTypeObject FilterRGB24Type = // define python type PyTypeObject FilterRGBA32Type = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterRGBA32", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -128,8 +138,13 @@ PyTypeObject FilterRGBA32Type = // define python type PyTypeObject FilterBGR24Type = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.FilterBGR24", /*tp_name*/ sizeof(PyFilter), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index 19ad17ac643..c8e62aff240 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -123,8 +123,13 @@ static PyGetSetDef imageBuffGetSets[] = // define python type PyTypeObject ImageBuffType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.ImageBuff", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index b07b362818c..2418ba254e4 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -162,8 +162,13 @@ static PyGetSetDef imageMixGetSets[] = // define python type PyTypeObject ImageMixType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.ImageMix", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index f1df47af373..1e3a84c1efb 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -379,8 +379,13 @@ static PyGetSetDef imageRenderGetSets[] = // define python type PyTypeObject ImageRenderType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.ImageRender", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -713,8 +718,13 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj // define python type PyTypeObject ImageMirrorType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.ImageMirror", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index 4c2c81e2208..b808b06eb2b 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -289,8 +289,13 @@ static PyGetSetDef imageViewportGetSets[] = // define python type PyTypeObject ImageViewportType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.ImageViewport", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index fa941f9260e..f1fcbee3041 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -435,8 +435,13 @@ static PyGetSetDef textureGetSets[] = // class Texture declaration PyTypeObject TextureType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.Texture", /*tp_name*/ sizeof(Texture), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 5265b0ecb93..08c02628f05 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -1123,8 +1123,13 @@ static PyGetSetDef videoGetSets[] = // python type declaration PyTypeObject VideoFFmpegType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.VideoFFmpeg", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -1241,8 +1246,13 @@ static PyGetSetDef imageGetSets[] = // python type declaration PyTypeObject ImageFFmpegType = { - PyObject_HEAD_INIT(NULL) +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ 0, /*ob_size*/ +#endif "VideoTexture.ImageFFmpeg", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index c11e7fffecd..8b2a9dc2a5d 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -159,8 +159,25 @@ static void registerAllTypes(void) pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24"); } + +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef VideoTexture_module_def = { + {}, /* m_base */ + "VideoTexture", /* m_name */ + "Module that allows to play video files on textures in GameBlender.", /* m_doc */ + 0, /* m_size */ + moduleMethods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif + PyObject* initVideoTexture(void) { + PyObject * m; + // initialize GL extensions //bgl::InitExtensions(0); @@ -175,9 +192,14 @@ PyObject* initVideoTexture(void) if (PyType_Ready(&TextureType) < 0) return NULL; - PyObject * m = Py_InitModule4("VideoTexture", moduleMethods, +#if (PY_VERSION_HEX >= 0x03000000) + m = PyModule_Create(&VideoTexture_module_def); +#else + m = Py_InitModule4("VideoTexture", moduleMethods, "Module that allows to play video files on textures in GameBlender.", (PyObject*)NULL,PYTHON_API_VERSION); +#endif + if (m == NULL) return NULL; From 70bcdb817b288374554543b3d138615bae01c8d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 17:01:35 +0000 Subject: [PATCH 104/444] was testing this, didnt mean to commit. --- source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 0239027f2cb..e393b6d9af4 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -268,7 +268,6 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat // 'normal' object glMultMatrixd(oglmatrix); } - glMultMatrixd(oglmatrix); } } From 11dcf7461cff32131efe1f22930b0a10e3562842 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 29 Apr 2009 17:41:41 +0000 Subject: [PATCH 105/444] Bugfix #18632 Duplicating an armature, with constraints having a local Ipo, didn't make a copy of this Ipo too, frustrating its drivers too. --- source/blender/blenkernel/intern/object.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0b153c3c065..bffbcf73672 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1169,6 +1169,9 @@ static void copy_object_pose(Object *obn, Object *ob) * is changed to object->proxy_from when evaluating the driver. */ if(con->ipo && !con->ipo->id.lib) { IpoCurve *icu; + + con->ipo= copy_ipo(con->ipo); + for(icu= con->ipo->curve.first; icu; icu= icu->next) { if(icu->driver && icu->driver->ob==ob) icu->driver->ob= obn; From a9aac77ccf6b915e15915ba1e10daebabd79610a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 29 Apr 2009 19:13:32 +0000 Subject: [PATCH 106/444] Win64 fixes - I don't think that they introduced any bugs yet, but I want to be sure. Please report problems. --- source/blender/blenkernel/intern/DerivedMesh.c | 2 +- source/blender/blenkernel/intern/bmfont.c | 2 +- source/blender/blenkernel/intern/customdata.c | 4 ++-- source/blender/blenkernel/intern/displist.c | 2 +- source/blender/blenkernel/intern/exotic.c | 18 +++++++++--------- source/blender/blenkernel/intern/font.c | 2 +- source/blender/blenlib/BLI_vfontdata.h | 2 +- source/blender/src/editfont.c | 6 +++--- source/blender/src/imagepaint.c | 6 +++--- source/blender/src/reeb.c | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 6cf934fa165..ddb7d853f2f 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -909,7 +909,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, glShadeModel(GL_SMOOTH); for (i=0,eve=em->verts.first; eve; eve= eve->next) - eve->tmp.l = (long) i++; + eve->tmp.l = (intptr_t) i++; #define PASSATTRIB(efa, eve, vert) { \ if(attribs.totorco) { \ diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index 0af54b86ed6..09770b2b4ba 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -178,7 +178,7 @@ void detectBitmapFont(ImBuf *ibuf) { unsigned char * rect; unsigned short version; - long i; + int i; if (ibuf != NULL) { // bitmap must have an x size that is a power of two diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 05271aa59a7..6d5b86fa874 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -626,7 +626,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, number++; if(layer->flag & CD_FLAG_NOCOPY) continue; - else if(!(mask & (1 << type))) continue; + else if(!((int)mask & (int)(1 << (int)type))) continue; else if(number < CustomData_number_of_layers(dest, type)) continue; if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE)) @@ -1144,7 +1144,7 @@ void CustomData_set_only_copy(const struct CustomData *data, int i; for(i = 0; i < data->totlayer; ++i) - if(!(mask & (1 << data->layers[i].type))) + if(!((int)mask & (int)(1 << (int)data->layers[i].type))) data->layers[i].flag |= CD_FLAG_NOCOPY; } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 7716d71225e..91eea56c9e7 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -937,7 +937,7 @@ void filldisplist(ListBase *dispbase, ListBase *to) DispList *dlnew=0, *dl; float *f1; int colnr=0, charidx=0, cont=1, tot, a, *index; - long totvert; + intptr_t totvert; if(dispbase==0) return; if(dispbase->first==0) return; diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index ee3fd59fe9f..76ad0cf07c3 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -1131,7 +1131,7 @@ static int iv_finddata(struct IvNode *iv, char *field, int fieldnr) float *fp; int len, stackcount, skipdata=0; char *cpa, terminator, str[64]; - long i; + intptr_t i; len= strlen(field); @@ -2592,7 +2592,7 @@ static void write_videoscape_mesh(Object *ob, char *str) unsigned int kleur[32]; float co[3]; int a; - long tot; + intptr_t tot; char *cp; if(ob && ob->type==OB_MESH); @@ -2642,17 +2642,17 @@ static void write_videoscape_mesh(Object *ob, char *str) if(evl->v4==0) { fprintf(fp, "3 %ld %ld %ld 0x%x\n", - (long int) evl->v1->tmp.l, - (long int) evl->v2->tmp.l, - (long int) evl->v3->tmp.l, + (intptr_t) evl->v1->tmp.l, + (intptr_t) evl->v2->tmp.l, + (intptr_t) evl->v3->tmp.l, kleur[evl->mat_nr]); } else { fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n", - (long int) evl->v1->tmp.l, - (long int) evl->v2->tmp.l, - (long int) evl->v3->tmp.l, - (long int) evl->v4->tmp.l, + (intptr_t) evl->v1->tmp.l, + (intptr_t) evl->v2->tmp.l, + (intptr_t) evl->v3->tmp.l, + (intptr_t) evl->v4->tmp.l, kleur[evl->mat_nr]); } evl= evl->next; diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 52275e507dd..45b52f5af8e 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -1131,7 +1131,7 @@ struct chartrans *text_to_curve(Object *ob, int mode) ct= chartransdata; if (cu->sepchar==0) { for (i= 0; istrinfo[i]); if (info->mat_nr > (ob->totcol)) { /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */ diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h index 8838b1992e4..bd89959801a 100644 --- a/source/blender/blenlib/BLI_vfontdata.h +++ b/source/blender/blenlib/BLI_vfontdata.h @@ -54,7 +54,7 @@ typedef struct VFontData { typedef struct VChar { struct VChar *next, *prev; ListBase nurbsbase; - unsigned long index; + intptr_t index; float resol; float width; float *points; diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c index a3b05a008c8..682125dabb1 100644 --- a/source/blender/src/editfont.c +++ b/source/blender/src/editfont.c @@ -241,7 +241,7 @@ void update_string(Curve *cu) wcs2utf8s(cu->str, textbuf); } -static int insert_into_textbuf(Curve *cu, unsigned long c) +static int insert_into_textbuf(Curve *cu, uintptr_t c) { if (cu->lendata; diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 89dff67585e..b0946e81dce 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -334,7 +334,7 @@ typedef struct UndoTile { typedef struct UndoElem { struct UndoElem *next, *prev; char name[MAXUNDONAME]; - unsigned long undosize; + uintptr_t undosize; ImBuf *ibuf; ListBase tiles; @@ -478,12 +478,12 @@ static void undo_imagepaint_push_begin(char *name) static void undo_imagepaint_push_end() { UndoElem *uel; - unsigned long totmem, maxmem; + uintptr_t totmem, maxmem; if(U.undomemory != 0) { /* limit to maximum memory (afterwards, we can't know in advance) */ totmem= 0; - maxmem= ((unsigned long)U.undomemory)*1024*1024; + maxmem= ((uintptr_t)U.undomemory)*1024*1024; uel= undobase.last; while(uel) { diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c index 67cfce55907..f49071be63c 100644 --- a/source/blender/src/reeb.c +++ b/source/blender/src/reeb.c @@ -2695,7 +2695,7 @@ static float cotan_weight(float *v1, float *v2, float *v3) return Inpf(a, b)/clen; } -void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, long e1, long e2, long e3) +void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, int e1, int e2, int e3) { /* Angle opposite e1 */ float t1= cotan_weight(v1->co, v2->co, v3->co) / e2; From 604f3e08d35464a86a818b9248085e2dbdb4d561 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 29 Apr 2009 19:33:05 +0000 Subject: [PATCH 107/444] Possible fix for bug #18648: one armature disappears when joining armatures. Not sure it actually fixes the problem because I can't test this on Win 64, but this fixes use of unitialized memory at least. Mat4MulMat34 only sets the 3x3 part of the 4x4 matrix, which may lead to a NaN bone roll value. --- source/blender/src/editarmature.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index ec14e2aabe2..e5be396fa47 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -715,6 +715,7 @@ int join_armature(void) VecSubf(delta, curbone->tail, curbone->head); vec_roll_to_mat3(delta, curbone->roll, temp); + Mat4One(premat); /* Mat4MulMat34 only sets 3x3 part */ Mat4MulMat34(premat, temp, mat); Mat4MulVecfl(mat, curbone->head); From 39caa9898c84c59aecc7443dce5ac94f1abd3ade Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 29 Apr 2009 20:09:08 +0000 Subject: [PATCH 108/444] * fix linking problem for mingw with setenv/_putenv_s, here we use putenv("key=val"); --- source/creator/creator.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index a1531fd7180..2b542b13c97 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -538,8 +538,12 @@ int main(int argc, char **argv) BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */ #ifndef DISABLE_SDL -#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS) +#if (defined(WIN32) || defined(WIN64)) +#if defined(FREE_WINDOWS) + putenv("SDL_VIDEODRIVER=dummy"); +#else _putenv_s("SDL_VIDEODRIVER", "dummy"); +#endif #else setenv("SDL_VIDEODRIVER", "dummy", 1); /* initializing the video driver can cause crashes on some systems - Campbell */ #endif From 4d7017b42393951052ca8f805dca5fe1e3e75637 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 29 Apr 2009 20:56:27 +0000 Subject: [PATCH 109/444] * make sure header file agrees with editfont.c (unsigned long -> uintptr_t), following commit by Genscher r19983 --- source/blender/include/BIF_editfont.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/include/BIF_editfont.h b/source/blender/include/BIF_editfont.h index d41f52f3c25..c5a8cd1187b 100644 --- a/source/blender/include/BIF_editfont.h +++ b/source/blender/include/BIF_editfont.h @@ -46,7 +46,7 @@ typedef struct unicodect int end; } unicodect; -void do_textedit(unsigned short event, short val, unsigned long _ascii); +void do_textedit(unsigned short event, short val, uintptr_t _ascii); void make_editText(void); void load_editText(void); void remake_editText(void); From ebf631b3fe70b9fe640129adf06bbd0bab27ef22 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 29 Apr 2009 22:09:28 +0000 Subject: [PATCH 110/444] * instead of using okee() (breaking builds) use error() in 250 subversion handling in 2.49 --- source/blender/blenkernel/intern/blender.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 906971f8bae..73c93abdf4b 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -429,7 +429,6 @@ static int handle_subversion_warning(Main *main) (main->minversionfile == BLENDER_VERSION && main->minsubversionfile > BLENDER_SUBVERSION)) { - extern int okee(char *str, ...); // XXX BAD LEVEL, DO NOT PORT TO 2.5! char str[128]; if(main->minversionfile >= 250) { @@ -437,10 +436,9 @@ static int handle_subversion_warning(Main *main) if(G.background) { printf("ERROR: cannot render %d file\n", main->versionfile); - return 0; } - else - return okee(str); + error(str); + return 0; } else { sprintf(str, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile); @@ -475,6 +473,7 @@ int BKE_read_file(char *dir, void *type_r) free_main(bfd->main); MEM_freeN(bfd); bfd= NULL; + retval= 0; } else setup_app_data(bfd, dir); // frees BFD From 537b0803798674501634c4dfbaeedb97b2ee889c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 29 Apr 2009 23:33:04 +0000 Subject: [PATCH 111/444] missing stdint.h include --- source/blender/include/BIF_editfont.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/include/BIF_editfont.h b/source/blender/include/BIF_editfont.h index c5a8cd1187b..e4401eb66a2 100644 --- a/source/blender/include/BIF_editfont.h +++ b/source/blender/include/BIF_editfont.h @@ -28,6 +28,7 @@ */ #include +#include #ifndef BIF_EDITFONT_H #define BIF_EDITFONT_H From 1e7df5851959db6822bdc2a71b83aa533b0ec117 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 23:39:27 +0000 Subject: [PATCH 112/444] python modules in the game engine could point to builtin modules like GameLogic that was cleared. I added module clearing before there was checks for invalid python objects, so now its not needed for BGE Builtin types at least. also made the builtin modules get re-used if they already exist and clear all user modules when the game engine finishes so with Module-Py-Controllers the referenced modules are at least up to date when pressing Pkey. --- .../python/api2_2x/bpy_internal_import.c | 11 ++- .../python/api2_2x/bpy_internal_import.h | 2 +- source/gameengine/Expressions/InputParser.cpp | 16 +++- source/gameengine/Expressions/Value.cpp | 16 +++- .../Ketsji/KX_PyConstraintBinding.cpp | 15 +++- source/gameengine/Ketsji/KX_PythonInit.cpp | 75 ++++++++++++++----- .../gameengine/VideoTexture/blendVideoTex.cpp | 22 ++++-- 7 files changed, 122 insertions(+), 35 deletions(-) diff --git a/source/blender/python/api2_2x/bpy_internal_import.c b/source/blender/python/api2_2x/bpy_internal_import.c index 1e1454dcd5c..125993cc425 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.c +++ b/source/blender/python/api2_2x/bpy_internal_import.c @@ -272,7 +272,12 @@ PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", blender_reload, METH_VARAR * Its also needed for the BGE Python api so imported scripts are not used between levels * * This clears every modules that has a __file__ attribute (is not a builtin) - * and is a filename only (no path). since pythons bultins include a full path even for win32. + * + * Note that clearing external python modules is important for the BGE otherwise + * it wont reload scripts between loading different blend files or while making the game. + * - use 'clear_all' arg in this case. + * + * Since pythons bultins include a full path even for win32. * even if we remove a python module a reimport will bring it back again. */ @@ -284,7 +289,7 @@ PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", blender_reload, METH_VARAR #endif -void bpy_text_clear_modules(void) +void bpy_text_clear_modules(int clear_all) { PyObject *modules= PySys_GetObject("modules"); @@ -309,7 +314,7 @@ void bpy_text_clear_modules(void) while (PyDict_Next(modules, &pos, &key, &value)) { fname= PyModule_GetFilename(value); if(fname) { - if ((strstr(fname, SEPSTR))==0) { /* no path ? */ + if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */ file_extension = strstr(fname, ".py"); if(file_extension && *(file_extension + 3) == '\0') { /* .py extension ? */ /* now we can be fairly sure its a python import from the blendfile */ diff --git a/source/blender/python/api2_2x/bpy_internal_import.h b/source/blender/python/api2_2x/bpy_internal_import.h index 137818bb0db..7220212f13e 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.h +++ b/source/blender/python/api2_2x/bpy_internal_import.h @@ -37,7 +37,7 @@ PyObject* bpy_text_import( char *name, int *found ); PyObject* bpy_text_reimport( PyObject *module, int *found ); -void bpy_text_clear_modules( void ); /* Clear user modules */ +void bpy_text_clear_modules( int clear_all ); /* Clear user modules */ extern PyMethodDef bpy_import_meth[]; extern PyMethodDef bpy_reload_meth[]; diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index d45a9375dc7..834faf70aae 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -676,11 +676,23 @@ static struct PyModuleDef Expression_module_def = { extern "C" { void initExpressionModule(void) { + PyObject *m; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "Expression" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - PyModule_Create(&Expression_module_def); + PyModule_Create(&Expression_module_def); #else - Py_InitModule("Expression",CParserMethods); + Py_InitModule("Expression",CParserMethods); #endif + } } } diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index fbd86cc4022..373924301ae 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -773,11 +773,23 @@ static struct PyModuleDef CValue_module_def = { extern "C" { void initCValue(void) { + PyObject *m; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "CValue" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - PyModule_Create(&CValue_module_def); + PyModule_Create(&CValue_module_def); #else - Py_InitModule("CValue",CValueMethods); + Py_InitModule("CValue",CValueMethods); #endif + } } } diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index e801e9c5858..0f21b24489d 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -586,13 +586,24 @@ PyObject* initPythonConstraintBinding() PyObject* m; PyObject* d; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "PhysicsConstraints" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&PhysicsConstraints_module_def); + m = PyModule_Create(&PhysicsConstraints_module_def); #else - m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, + m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, PhysicsConstraints_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + } // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 22e092e8277..22960eaed2c 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1098,16 +1098,28 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack gUseVisibilityTemp=false; - // Create the module and add the functions - -#if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&GameLogic_module_def); -#else - m = Py_InitModule4("GameLogic", game_methods, - GameLogic_module_documentation, - (PyObject*)NULL,PYTHON_API_VERSION); -#endif + + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "GameLogic" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions +#if (PY_VERSION_HEX >= 0x03000000) + m = PyModule_Create(&GameLogic_module_def); +#else + m = Py_InitModule4("GameLogic", game_methods, + GameLogic_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); +#endif + } + // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -1562,8 +1574,7 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev bpy_import_main_set(maggie); - /* run this to clear game modules and user modules which - * may contain references to in game data */ + /* clear user defined modules that may contain data from the last run */ clearGameModules(); PyObject* moduleobj = PyImport_AddModule("__main__"); @@ -1583,6 +1594,8 @@ static void clearModule(PyObject *modules, const char *name) static void clearGameModules() { + /* references to invalid BGE data is better supported in 2.49+ so dont clear dicts */ +#if 0 /* Note, user modules could still reference these modules * but since the dict's are cleared their members wont be accessible */ @@ -1597,9 +1610,10 @@ static void clearGameModules() clearModule(modules, "Mathutils"); clearModule(modules, "BGL"); PyErr_Clear(); // incase some of these were alredy removed. +#endif - /* clear user defined modules */ - bpy_text_clear_modules(); + /* clear user defined modules, arg '1' for clear external py modules too */ + bpy_text_clear_modules(1); } void exitGamePythonScripting() @@ -1633,14 +1647,25 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) PyObject* d; PyObject* item; - // Create the module and add the functions + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "Rasterizer" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&Rasterizer_module_def); + m = PyModule_Create(&Rasterizer_module_def); #else - m = Py_InitModule4("Rasterizer", rasterizer_methods, + m = Py_InitModule4("Rasterizer", rasterizer_methods, Rasterizer_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + } // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -1756,15 +1781,25 @@ PyObject* initGameKeys() PyObject* m; PyObject* d; PyObject* item; - - // Create the module and add the functions + + /* Use existing module where possible */ + m = PyImport_ImportModule( "GameKeys" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&GameKeys_module_def); + m = PyModule_Create(&GameKeys_module_def); #else - m = Py_InitModule4("GameKeys", gamekeys_methods, + m = Py_InitModule4("GameKeys", gamekeys_methods, GameKeys_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + } // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 8b2a9dc2a5d..239f43763b8 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -192,13 +192,24 @@ PyObject* initVideoTexture(void) if (PyType_Ready(&TextureType) < 0) return NULL; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "VideoTexture" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&VideoTexture_module_def); + m = PyModule_Create(&VideoTexture_module_def); #else - m = Py_InitModule4("VideoTexture", moduleMethods, - "Module that allows to play video files on textures in GameBlender.", - (PyObject*)NULL,PYTHON_API_VERSION); + m = Py_InitModule4("VideoTexture", moduleMethods, + "Module that allows to play video files on textures in GameBlender.", + (PyObject*)NULL,PYTHON_API_VERSION); #endif + } if (m == NULL) return NULL; @@ -209,9 +220,10 @@ PyObject* initVideoTexture(void) Py_INCREF(&TextureType); PyModule_AddObject(m, (char*)"Texture", (PyObject*)&TextureType); - + // init last error description Exception::m_lastError[0] = '\0'; + return m; } From 6a155b5c078a294654b710e23a1ef3904ef9be5e Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 29 Apr 2009 23:43:12 +0000 Subject: [PATCH 113/444] use BLO_sys_types.h instead, it's windows proof --- source/blender/include/BIF_editfont.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/include/BIF_editfont.h b/source/blender/include/BIF_editfont.h index e4401eb66a2..f8bb708bccd 100644 --- a/source/blender/include/BIF_editfont.h +++ b/source/blender/include/BIF_editfont.h @@ -28,11 +28,12 @@ */ #include -#include #ifndef BIF_EDITFONT_H #define BIF_EDITFONT_H +#include "BLO_sys_types.h" + struct Text; extern char *BIF_lorem; From a625f5e476189499c23e911ef44b2c05b4cb6d70 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Apr 2009 23:59:59 +0000 Subject: [PATCH 114/444] error in last commit --- source/gameengine/Expressions/InputParser.cpp | 2 +- source/gameengine/Expressions/Value.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index 834faf70aae..91a14f97851 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -682,7 +682,7 @@ extern "C" { m = PyImport_ImportModule( "Expression" ); if(m) { Py_DECREF(m); - return m; + //return m; } else { PyErr_Clear(); diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 373924301ae..c50a941f3a9 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -779,7 +779,7 @@ extern "C" { m = PyImport_ImportModule( "CValue" ); if(m) { Py_DECREF(m); - return m; + //return m; } else { PyErr_Clear(); From 1782be5c72cc5cd72a710d5d6cbcf52b38b8b2ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Apr 2009 00:51:11 +0000 Subject: [PATCH 115/444] Not sure why this INCREF is needed since making a replica wont use the m_bytecode so why should it add a user? Removed in 19974 but that crashes YoFrankie so adding back in for now. --- source/gameengine/GameLogic/SCA_PythonController.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 33207950697..d443c1688e4 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -96,7 +96,11 @@ SCA_PythonController::~SCA_PythonController() CValue* SCA_PythonController::GetReplica() { SCA_PythonController* replica = new SCA_PythonController(*this); - // Copy the compiled bytecode if possible. + + /* why is this needed at all??? - m_bytecode is NULL'd below so this doesnt make sense + * but removing it crashes blender (with YoFrankie). so leave in for now - Campbell */ + Py_XINCREF(replica->m_bytecode); + Py_XINCREF(replica->m_function); // this is ok since its not set to NULL replica->m_bModified = replica->m_bytecode == NULL; From 199341ad7be34cc07f784c6be0d9b1e5473c9346 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Apr 2009 02:07:08 +0000 Subject: [PATCH 116/444] 2 BGE bugs from 2.48 fixed - the gp_GamePythonPath relative path variable wasnt updated when loading new files. - missing NULL check for scene crashed blender when it failed to load a file. Both problems dont affect blenderplayer --- .../gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index fee5a4ad899..2337ab49ee9 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -280,6 +280,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, if(blenderdata) { BLI_strncpy(G.sce, blenderdata->name, sizeof(G.sce)); BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); + setGamePythonPath(G.sce); } } // else forget it, we can't find it @@ -309,12 +310,11 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, { int startFrame = blscene->r.cfra; ketsjiengine->SetGame2IpoMode(game2ipo,startFrame); + + // Quad buffered needs a special window. + if (blscene->r.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) + rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->r.stereomode); } - - - // Quad buffered needs a special window. - if (blscene->r.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) - rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->r.stereomode); if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { From 5908e2aa779b0b95a27dad96e2bb8d3be926956a Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 30 Apr 2009 02:41:07 +0000 Subject: [PATCH 117/444] BGE Dome update. Spurious black seams (finally) fixed. The solution is a hack. It's a workaround for another bug (#18655). Now it's working in all modes: fullscreen, maximized screen and gameplayer. * small change to always set the perspective mode as true during dome mode. --- source/gameengine/Ketsji/KX_Dome.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 9565c53e0bf..e4c3d92fbf2 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -147,7 +147,7 @@ KX_Dome::~KX_Dome (void) void KX_Dome::SetViewPort(GLuint viewport[4]) { - if(canvaswidth != m_canvas->GetWidth() || canvasheight != m_canvas->GetHeight()) + if(canvaswidth != m_viewport.GetWidth() || canvasheight != m_viewport.GetHeight()) { m_viewport.SetLeft(viewport[0]); m_viewport.SetBottom(viewport[1]); @@ -200,13 +200,26 @@ void KX_Dome::CalculateImageSize(void) - determine the minimum buffer size - reduce the buffer for better performace - create a power of 2 texture bigger than the buffer +*/ +/* +Blender handles Canvas size differently when in fullscreen mode. +We are manually checking for that. Although it's a hack, it works. + +Bug reported here: #18655 - Inconsistency of pixels in canvas dimensions when in maximized mode (affecting BGE Dome) +http://projects.blender.org/tracker/?func=detail&aid=18655&group_id=9&atid=125 */ canvaswidth = m_canvas->GetWidth(); canvasheight = m_canvas->GetHeight(); + bool fullscreen(false); //XXX HACK + fullscreen = (canvaswidth != m_viewport.GetWidth()); + m_buffersize = (canvaswidth > canvasheight?canvasheight:canvaswidth); m_buffersize = (int)(m_buffersize*m_resbuffer); //reduce buffer size for better performance + + if (fullscreen) //XXX HACK + m_buffersize --; int i = 0; while ((1 << i) <= m_buffersize) @@ -227,6 +240,9 @@ void KX_Dome::CalculateImageSize(void) i++; warp.imageheight = (1 << i); } + //XXX HACK + canvaswidth = m_viewport.GetWidth(); + canvasheight = m_viewport.GetHeight(); } bool KX_Dome::CreateDL(){ @@ -1365,7 +1381,7 @@ void KX_Dome::CalculateFrustum(KX_Camera * cam) /* // manually creating a 90º Field of View Frustum - the original formula: + the original formula: top = tan(fov*3.14159/360.0) * near [for fov in degrees] fov*0.5 = arctan ((top-bottom)*0.5 / near) [for fov in radians] bottom = -top @@ -1913,7 +1929,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) MT_Transform camtrans(cam->GetWorldToCamera()); MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), 1.0); cam->SetModelviewMatrix(viewmat); scene->CalculateVisibleMeshes(m_rasterizer,cam); From 939290b59c52bdd84b9f20083d4dd76ada293ee8 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 30 Apr 2009 03:46:31 +0000 Subject: [PATCH 118/444] BGE 2dFilters: Revert of part of own commit [rev. 19687] Therefore we still need to find a better way to solve this problem: [#18154] 2dFilter and motion blur should run only once to all the scenes: http://projects.blender.org/tracker/?func=detail&aid=18154&group_id=9&atid=127 --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 9bac0f7d758..764c3c2dfec 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -906,9 +906,6 @@ void KX_KetsjiEngine::Render() } } // if(m_rasterizer->Stereo()) - // run the 2dfilters and motion blur once for all the scenes - PostRenderFrame(); - EndFrame(); } @@ -1284,6 +1281,9 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->GetPhysicsEnvironment()->debugDrawWorld(); m_rasterizer->FlushDebugLines(); + + //it's running once for every scene (i.e. overlay scenes have it running twice). That's not the ideal. + PostRenderFrame(); } void KX_KetsjiEngine::PostRenderFrame() From b5b24ee521866637871e7555d4294c0936a0664d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Apr 2009 08:01:31 +0000 Subject: [PATCH 119/444] BGE Python sys.path for the blenderplayer and blender sys.path is the search path for python modules. This is useful so people making games can put all their scripts in a folder and be sure they will always load into the BGE. for each blend file a scripts directory is added to the path /home/me/foo.blend will look for modules in... /home/me/scripts/*.py It could also default to look for modules in the same directory as the blend file but I think this is messy. Added a note in the tooltip about //scripts so its not such a hidden feature. This works by storing the original sys.path, then adding the paths for the blendfile and all its libs, when a new blendfile is loaded, the original sys.path is restored before adding the blendfiles paths again so the sys.path wont get junk in it. One problem with this - when using linked libs the module names must be unique else it will load the wrong module for one of the controllers. also fixed 2 bugs - sys.path in the blenderplayer was growing by 1 for every file load in blenderplayer - the relative path (gp_GamePythonPath), wasnt being set when loading files in the blenderlayer (as I wrongly said in the last commit). --- source/blender/src/buttons_logic.c | 6 +- .../gameengine/GamePlayer/ghost/GPG_ghost.cpp | 2 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 120 +++++++++++++++++- 3 files changed, 123 insertions(+), 5 deletions(-) diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 168726c9dab..54b48de716f 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1580,12 +1580,12 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco uiBlockBeginAlign(block); - uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+24,yco-24, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module)"); + uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+24,yco-24, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)"); if(pc->mode==0) uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+90,yco-24,width-90, 19, &pc->text, "Blender textblock to run as a script"); else { - uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run eg \"someModule.main\""); - uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restrting, (slow)"); + uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run eg \"someModule.main\", internal texts and //scripts/*.py on the filesystem can be used"); + uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restrting"); } uiBlockEndAlign(block); diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 64e70ce37c3..7c47d2353a6 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -704,10 +704,10 @@ int main(int argc, char** argv) BLI_strncpy(pathname, maggie->name, sizeof(pathname)); BLI_strncpy(G.sce, maggie->name, sizeof(G.sce)); + setGamePythonPath(G.sce); if (firstTimeRunning) { - setGamePythonPath(G.sce); firstTimeRunning = false; if (fullScreen) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 22960eaed2c..b17d4042bb6 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -80,6 +80,10 @@ #include "KX_PythonInitTypes.h" +/* we only need this to get a list of libraries from the main struct */ +#include "DNA_ID.h" +#include "BKE_main.h" + extern "C" { #include "Mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use. #include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ @@ -110,6 +114,7 @@ static KX_Scene* gp_KetsjiScene = NULL; static KX_KetsjiEngine* gp_KetsjiEngine = NULL; static RAS_IRasterizer* gp_Rasterizer = NULL; static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = ""; +static PyObject *gp_OrigPythonSysPath= NULL; void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) { @@ -1522,11 +1527,111 @@ void setSandbox(TPythonSecurityLevel level) } } +/* Explanation of + * + * - backupPySysPath() : stores sys.path in gp_OrigPythonSysPath + * - initPySysPath(main) : initializes the blendfile and library paths + * - restorePySysPath() : restores sys.path from gp_OrigPythonSysPath + * + * These exist so the //scripts folder can always be used to import modules from. + * the reason we need a few functions for this is that python is not only used by the game engine + * so we cant just add to sys.path all the time, it would leave pythons state in a mess. + * It would also be incorrect since loading blend files for new levels etc would alwasy add to sys.path + * + * To play nice with blenders python, the sys.path is backed up and the current blendfile along + * with all its lib paths are added to the sys path. + * When loading a new blendfile, the original sys.path is restored and the new paths are added over the top. + */ + +/** + * So we can have external modules mixed with our blend files. + */ +static void backupPySysPath(void) +{ + PyObject *sys_path= PySys_GetObject("path"); /* should never fail */ + + /* just incase its set */ + Py_XDECREF(gp_OrigPythonSysPath); + gp_OrigPythonSysPath= NULL; + + gp_OrigPythonSysPath = PyList_GetSlice(sys_path, 0, INT_MAX); /* copy the list */ +} + +/* for initPySysPath only, + * takes a blend path and adds a scripts dir from it + * + * "/home/me/foo.blend" -> "/home/me/scripts" + */ +static void initPySysPath__append(PyObject *sys_path, char *filename) +{ + PyObject *item; + char expanded[FILE_MAXDIR + FILE_MAXFILE] = "//"; + + BLI_convertstringcode(expanded, filename); + BLI_join_dirfile(expanded, expanded, "scripts"); /* double checked and using the dir twice is safe */ + + item= PyString_FromString(expanded); + + if(PySequence_Index(sys_path, item) == -1) { + PyList_Insert(sys_path, 0, item); + } + + Py_DECREF(item); +} +static void initPySysPath(Main *maggie) +{ + PyObject *sys_path= PySys_GetObject("path"); /* should never fail */ + + if (gp_OrigPythonSysPath==NULL) { + /* backup */ + backupPySysPath(); + } + else { + /* get the original sys path when the BGE started */ + PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath); + } + + Library *lib= (Library *)maggie->library.first; + + while(lib) { + initPySysPath__append(sys_path, lib->name); + lib= (Library *)lib->id.next; + } + + initPySysPath__append(sys_path, gp_GamePythonPath); + +// fprintf(stderr, "\nNew Path: %d ", PyList_Size(sys_path)); +// PyObject_Print(sys_path, stderr, 0); +} + +static void restorePySysPath(void) +{ + if (gp_OrigPythonSysPath==NULL) + return; + + PyObject *sys_path= PySys_GetObject("path"); /* should never fail */ + + PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath); + Py_DECREF(gp_OrigPythonSysPath); + gp_OrigPythonSysPath= NULL; + +// fprintf(stderr, "\nRestore Path: %d ", PyList_Size(sys_path)); +// PyObject_Print(sys_path, stderr, 0); +} + /** * Python is not initialised. */ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv) { + /* Yet another gotcha in the py api + * Cant run PySys_SetArgv more then once because this adds the + * binary dir to the sys.path each time. + * Id have thaught python being totally restarted would make this ok but + * somehow it remembers the sys.path - Campbell + */ + static bool first_time = true; + #if (PY_VERSION_HEX < 0x03000000) STR_String pname = progname; Py_SetProgramName(pname.Ptr()); @@ -1536,7 +1641,7 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur Py_Initialize(); #if (PY_VERSION_HEX < 0x03000000) - if(argv) /* browser plugins dont currently set this */ + if(argv && first_time) /* browser plugins dont currently set this */ PySys_SetArgv(argc, argv); #endif //importBlenderModules() @@ -1546,6 +1651,10 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur bpy_import_main_set(maggie); + initPySysPath(maggie); + + first_time = false; + PyObject* moduleobj = PyImport_AddModule("__main__"); return PyModule_GetDict(moduleobj); } @@ -1553,10 +1662,16 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur void exitGamePlayerPythonScripting() { //clearGameModules(); // were closing python anyway + + /* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */ + restorePySysPath(); /* get back the original sys.path and clear the backup */ + Py_Finalize(); bpy_import_main_set(NULL); } + + /** * Python is already initialized. */ @@ -1574,6 +1689,8 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev bpy_import_main_set(maggie); + initPySysPath(maggie); + /* clear user defined modules that may contain data from the last run */ clearGameModules(); @@ -1619,6 +1736,7 @@ static void clearGameModules() void exitGamePythonScripting() { clearGameModules(); + restorePySysPath(); /* get back the original sys.path and clear the backup */ bpy_import_main_set(NULL); } From 81ea467091996dab41a10af1111cd85fd34d1d69 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 30 Apr 2009 08:02:26 +0000 Subject: [PATCH 120/444] BGE fux #17796: Glsl + bones + set smooth = bug on vertext groups. --- source/gameengine/Converter/BL_MeshDeformer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index 80112346c72..b6a59774636 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -47,6 +47,7 @@ #include "GEN_Map.h" #include "STR_HashedString.h" +#include "BLI_arithb.h" bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*) { @@ -166,6 +167,7 @@ void BL_MeshDeformer::RecalcNormals() fnor[0]= n1[1]*n2[2] - n1[2]*n2[1]; fnor[1]= n1[2]*n2[0] - n1[0]*n2[2]; fnor[2]= n1[0]*n2[1] - n1[1]*n2[0]; + Normalize(fnor); /* add to vertices for smooth normals */ float *vn1 = m_transnors[v1.getOrigIndex()]; From de2cc4d14d1b7a7b47cbbf01db7c980d929a7846 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 30 Apr 2009 10:11:37 +0000 Subject: [PATCH 121/444] Second trial to get an OK menu work to allow people to decide whether or not to use a 2.5+ saved file in 2.49. Apparently the msvc linker was choking on it? --- source/blender/blenkernel/BKE_bad_level_calls.h | 1 + source/blender/blenkernel/bad_level_call_stubs/stubs.c | 1 + source/blender/blenkernel/intern/blender.c | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 0962a174a8e..71f8aee8e99 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -92,6 +92,7 @@ int pytype_is_pynode(struct PyObject *pyob); struct Oops; void free_oops(struct Oops *oops); void error(char *str, ...); +int okee(char *str, ...); /* anim.c */ extern struct ListBase editNurb; diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 341379de1d9..3012c19ff02 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -160,6 +160,7 @@ void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTa void free_oops(struct Oops *oops){} void exit_posemode(int freedata){} void error(char *str, ...){} +int okee(char *str, ...){} /* anim.c */ ListBase editNurb; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 73c93abdf4b..107953138c6 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -431,14 +431,14 @@ static int handle_subversion_warning(Main *main) char str[128]; + /* XXX DO NOT PORT OVER TO 2.5 BRANCH! */ if(main->minversionfile >= 250) { sprintf(str, "You have opened a %d file, key information will get lost, like animation data. Continue?", main->minversionfile); if(G.background) { printf("ERROR: cannot render %d file\n", main->versionfile); } - error(str); - return 0; + return okee(str); } else { sprintf(str, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile); From a8a0af4f6a506e43dd9ecb26e805db937e4f44ea Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 30 Apr 2009 10:18:50 +0000 Subject: [PATCH 122/444] SCons * add missing arguments --- tools/btools.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/btools.py b/tools/btools.py index dd04a366b1b..96048a545ff 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -36,6 +36,8 @@ def validate_arguments(args, bc): 'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG', 'BF_FFMPEG_INC', 'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB', 'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH', + 'WITH_BF_OPENJPEG', 'BF_OPENJPEG', 'BF_OPENJPEG_INC', 'BF_OPENJPEG_LIB', 'BF_OPENJPEG_LIBPATH', + 'WITH_BF_REDCODE', 'BF_REDCODE', 'BF_REDCODE_INC', 'BF_REDCODE_LIB', 'BF_REDCODE_LIBPATH', 'WITH_BF_PNG', 'BF_PNG', 'BF_PNG_INC', 'BF_PNG_LIB', 'BF_PNG_LIBPATH', 'BF_TIFF', 'BF_TIFF_INC', 'BF_TIFF_LIB', 'BF_TIFF_LIBPATH', 'WITH_BF_ZLIB', 'BF_ZLIB', 'BF_ZLIB_INC', 'BF_ZLIB_LIB', 'BF_ZLIB_LIBPATH', @@ -95,7 +97,7 @@ def validate_arguments(args, bc): if (k in opts_list) or (k in arg_list): okdict[k] = v elif k in opts_list_split: - okdict[k] = v.split() # "" have alredy been stripped + okdict[k] = v.split() # "" have already been stripped else: print '\t'+bc.WARNING+'Invalid argument: '+bc.ENDC+k+'='+v From b14dc8f3d97d6010c842e9137034d3ff3747e68a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Apr 2009 10:41:39 +0000 Subject: [PATCH 123/444] enable game engine and player by default --- config/linux2-config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index 5bd9a4c8084..c1b9d7d2ebd 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -78,7 +78,8 @@ BF_FTGL = '#extern/bFTGL' BF_FTGL_INC = '${BF_FTGL}/include' BF_FTGL_LIB = 'extern_ftgl' -WITH_BF_GAMEENGINE=False +WITH_BF_GAMEENGINE = True +WITH_BF_PLAYER = True WITH_BF_ODE = False BF_ODE = LIBDIR + '/ode' From fdf6ea916db3225e2cee437cdb19b3fbee84db41 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Apr 2009 12:45:13 +0000 Subject: [PATCH 124/444] added Geometry as a BGE module, removed its dependency on gen_utils.c --- source/blender/python/api2_2x/Blender.c | 2 +- source/blender/python/api2_2x/Geometry.c | 128 +++++++++++------- source/blender/python/api2_2x/Geometry.h | 2 +- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 2 + .../GamePlayer/ghost/GPG_Application.cpp | 1 + source/gameengine/Ketsji/CMakeLists.txt | 1 + source/gameengine/Ketsji/KX_PythonInit.cpp | 9 +- source/gameengine/Ketsji/KX_PythonInit.h | 1 + source/gameengine/Ketsji/SConscript | 1 + 9 files changed, 96 insertions(+), 51 deletions(-) diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 2e44f0635e5..fd316eb484f 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -1092,7 +1092,7 @@ void M_Blender_Init(void) PyDict_SetItemString(dict, "Mesh", Mesh_Init()); PyDict_SetItemString(dict, "Metaball", Metaball_Init()); PyDict_SetItemString(dict, "Mathutils", Mathutils_Init("Blender.Mathutils")); - PyDict_SetItemString(dict, "Geometry", Geometry_Init()); + PyDict_SetItemString(dict, "Geometry", Geometry_Init("Blender.Geometry")); PyDict_SetItemString(dict, "Modifier", Modifier_Init()); PyDict_SetItemString(dict, "NMesh", NMesh_Init()); PyDict_SetItemString(dict, "Node", Node_Init()); diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index 89c63870d59..d568472c838 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -38,9 +38,6 @@ #include "BKE_displist.h" #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" - -/* needed for EXPP_ReturnPyObjError and EXPP_check_sequence_consistency */ -#include "gen_utils.h" #include "BKE_utildefines.h" #include "BLI_boxpack2d.h" @@ -76,13 +73,32 @@ struct PyMethodDef M_Geometry_methods[] = { {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc}, {NULL, NULL, 0, NULL} }; + +#if (PY_VERSION_HEX >= 0x03000000) +static struct PyModuleDef M_Geometry_module_def = { + {}, /* m_base */ + "Geometry", /* m_name */ + M_Geometry_doc, /* m_doc */ + 0, /* m_size */ + M_Geometry_methods, /* m_methods */ + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ +}; +#endif + /*----------------------------MODULE INIT-------------------------*/ -PyObject *Geometry_Init(void) +PyObject *Geometry_Init(const char *from) { PyObject *submodule; - - submodule = Py_InitModule3("Blender.Geometry", - M_Geometry_methods, M_Geometry_doc); + +#if (PY_VERSION_HEX >= 0x03000000) + submodule = PyModule_Create(&M_Geometry_module_def); +#else + submodule = Py_InitModule3(from, M_Geometry_methods, M_Geometry_doc); +#endif + return (submodule); } @@ -92,7 +108,7 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) { PyObject *tri_list; /*return this list of tri's */ PyObject *polyLine, *polyVec; - int i, len_polylines, len_polypoints; + int i, len_polylines, len_polypoints, ls_error = 0; /* display listbase */ ListBase dispbase={NULL, NULL}; @@ -105,8 +121,8 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) if(!PySequence_Check(polyLineSeq)) { - return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected a sequence of poly lines" ); + PyErr_SetString( PyExc_TypeError, "expected a sequence of poly lines" ); + return NULL; } len_polylines = PySequence_Size( polyLineSeq ); @@ -116,19 +132,20 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) if (!PySequence_Check(polyLine)) { freedisplist(&dispbase); Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/ - return EXPP_ReturnPyObjError( PyExc_TypeError, - "One or more of the polylines is not a sequence of Mathutils.Vector's" ); + PyErr_SetString( PyExc_TypeError, "One or more of the polylines is not a sequence of Mathutils.Vector's" ); + return NULL; } len_polypoints= PySequence_Size( polyLine ); if (len_polypoints>0) { /* dont bother adding edges as polylines */ +#if 0 if (EXPP_check_sequence_consistency( polyLine, &vector_Type ) != 1) { freedisplist(&dispbase); Py_DECREF(polyLine); - return EXPP_ReturnPyObjError( PyExc_TypeError, - "A point in one of the polylines is not a Mathutils.Vector type" ); + PyErr_SetString( PyExc_TypeError, "A point in one of the polylines is not a Mathutils.Vector type" ); + return NULL; } - +#endif dl= MEM_callocN(sizeof(DispList), "poly disp"); BLI_addtail(&dispbase, dl); dl->type= DL_INDEX3; @@ -141,13 +158,17 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) for( index = 0; indexvec[0]; - fp[1] = ((VectorObject *)polyVec)->vec[1]; - if( ((VectorObject *)polyVec)->size > 2 ) - fp[2] = ((VectorObject *)polyVec)->vec[2]; - else - fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ + if(VectorObject_Check(polyVec)) { + fp[0] = ((VectorObject *)polyVec)->vec[0]; + fp[1] = ((VectorObject *)polyVec)->vec[1]; + if( ((VectorObject *)polyVec)->size > 2 ) + fp[2] = ((VectorObject *)polyVec)->vec[2]; + else + fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */ + } + else { + ls_error= 1; + } totpoints++; Py_DECREF(polyVec); @@ -156,7 +177,12 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) Py_DECREF(polyLine); } - if (totpoints) { + if(ls_error) { + freedisplist(&dispbase); /* possible some dl was allocated */ + PyErr_SetString( PyExc_TypeError, "A point in one of the polylines is not a Mathutils.Vector type" ); + return NULL; + } + else if (totpoints) { /* now make the list to return */ filldisplist(&dispbase, &dispbase); @@ -167,8 +193,8 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) tri_list= PyList_New(dl->parts); if( !tri_list ) { freedisplist(&dispbase); - return EXPP_ReturnPyObjError( PyExc_RuntimeError, - "Geometry.PolyFill failed to make a new list" ); + PyErr_SetString( PyExc_RuntimeError, "Geometry.PolyFill failed to make a new list" ); + return NULL; } index= 0; @@ -181,6 +207,7 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) freedisplist(&dispbase); } else { /* no points, do this so scripts dont barf */ + freedisplist(&dispbase); /* possible some dl was allocated */ tri_list= PyList_New(0); } @@ -197,9 +224,10 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) &vector_Type, &line_a2, &vector_Type, &line_b1, &vector_Type, &line_b2) - ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 4 vector types\n" ) ); + ) { + PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" ); + return NULL; + } a1x= line_a1->vec[0]; a1y= line_a1->vec[1]; @@ -293,10 +321,10 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args &vector_Type, &pt, &vector_Type, &line_1, &vector_Type, &line_2) - ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 3 vector types\n" ) ); - + ) { + PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" ); + return NULL; + } /* accept 2d verts */ if (pt->size==3) { VECCOPY(pt_in, pt->vec);} else { pt_in[2]=0.0; VECCOPY2D(pt_in, pt->vec) } @@ -325,9 +353,10 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args &vector_Type, &tri_p1, &vector_Type, &tri_p2, &vector_Type, &tri_p3) - ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 4 vector types\n" ) ); + ) { + PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" ); + return NULL; + } return PyInt_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec)); } @@ -342,9 +371,10 @@ static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args ) &vector_Type, &quad_p2, &vector_Type, &quad_p3, &vector_Type, &quad_p4) - ) - return ( EXPP_ReturnPyObjError - ( PyExc_TypeError, "expected 5 vector types\n" ) ); + ) { + PyErr_SetString( PyExc_TypeError, "expected 5 vector types\n" ); + return NULL; + } return PyInt_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec)); } @@ -357,9 +387,10 @@ static int boxPack_FromPyObject(PyObject * value, boxPack **boxarray ) /* Error checking must alredy be done */ - if( !PyList_Check( value ) ) - return EXPP_ReturnIntError( PyExc_TypeError, - "can only back a list of [x,y,x,w]" ); + if( !PyList_Check( value ) ) { + PyErr_SetString( PyExc_TypeError, "can only back a list of [x,y,x,w]" ); + return -1; + } len = PyList_Size( value ); @@ -370,8 +401,8 @@ static int boxPack_FromPyObject(PyObject * value, boxPack **boxarray ) list_item = PyList_GET_ITEM( value, i ); if( !PyList_Check( list_item ) || PyList_Size( list_item ) < 4 ) { MEM_freeN(*boxarray); - return EXPP_ReturnIntError( PyExc_TypeError, - "can only back a list of [x,y,x,w]" ); + PyErr_SetString( PyExc_TypeError, "can only back a list of [x,y,x,w]" ); + return -1; } box = (*boxarray)+i; @@ -381,8 +412,8 @@ static int boxPack_FromPyObject(PyObject * value, boxPack **boxarray ) if (!PyNumber_Check(item_1) || !PyNumber_Check(item_2)) { MEM_freeN(*boxarray); - return EXPP_ReturnIntError( PyExc_TypeError, - "can only back a list of 2d boxes [x,y,x,w]" ); + PyErr_SetString( PyExc_TypeError, "can only back a list of 2d boxes [x,y,x,w]" ); + return -1; } box->w = (float)PyFloat_AsDouble( item_1 ); @@ -418,9 +449,10 @@ static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * boxlist ) int len; int error; - if(!PyList_Check(boxlist)) - return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected a sequence of boxes [[x,y,w,h], ... ]" ); + if(!PyList_Check(boxlist)) { + PyErr_SetString( PyExc_TypeError, "expected a sequence of boxes [[x,y,w,h], ... ]" ); + return NULL; + } len = PyList_Size( boxlist ); diff --git a/source/blender/python/api2_2x/Geometry.h b/source/blender/python/api2_2x/Geometry.h index e9e365cc9ae..ebfb054c54a 100644 --- a/source/blender/python/api2_2x/Geometry.h +++ b/source/blender/python/api2_2x/Geometry.h @@ -34,6 +34,6 @@ #include #include "Mathutils.h" -PyObject *Geometry_Init( void ); +PyObject *Geometry_Init( const char *from ); #endif /* EXPP_Geometry_H */ diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 2337ab49ee9..641938253b7 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -368,6 +368,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, initGameKeys(); initPythonConstraintBinding(); initMathutils(); + initGeometry(); initBGL(); #ifdef WITH_FFMPEG initVideoTexture(); @@ -671,6 +672,7 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, initGameKeys(); initPythonConstraintBinding(); initMathutils(); + initGeometry(); initBGL(); #ifdef WITH_FFMPEG initVideoTexture(); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 907ba99e63b..af8b94857b9 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -693,6 +693,7 @@ bool GPG_Application::startEngine(void) initGameKeys(); initPythonConstraintBinding(); initMathutils(); + initGeometry(); initBGL(); #ifdef WITH_FFMPEG initVideoTexture(); diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index c4623b5b6fe..abc2b44825e 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -28,6 +28,7 @@ FILE(GLOB SRC *.cpp) SET(SRC ${SRC} ../../../source/blender/python/api2_2x/Mathutils.c + ../../../source/blender/python/api2_2x/Geometry.c ../../../source/blender/python/api2_2x/constant.c ../../../source/blender/python/api2_2x/euler.c ../../../source/blender/python/api2_2x/matrix.c diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index b17d4042bb6..f5d32e36fc5 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -86,6 +86,7 @@ extern "C" { #include "Mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use. + #include "Geometry.h" // Blender.Geometry module copied here so the blenderlayer can use. #include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ #include "BGL.h" } @@ -1407,7 +1408,7 @@ PyObject *KXpy_import(PyObject *self, PyObject *args) /* quick hack for GamePython modules TODO: register builtin modules properly by ExtendInittab */ if (!strcmp(name, "GameLogic") || !strcmp(name, "GameKeys") || !strcmp(name, "PhysicsConstraints") || - !strcmp(name, "Rasterizer") || !strcmp(name, "Mathutils") || !strcmp(name, "BGL")) { + !strcmp(name, "Rasterizer") || !strcmp(name, "Mathutils") || !strcmp(name, "BGL") || !strcmp(name, "Geometry")) { return PyImport_ImportModuleEx(name, globals, locals, fromlist); } @@ -1725,6 +1726,7 @@ static void clearGameModules() clearModule(modules, "GameKeys"); clearModule(modules, "VideoTexture"); clearModule(modules, "Mathutils"); + clearModule(modules, "Geometry"); clearModule(modules, "BGL"); PyErr_Clear(); // incase some of these were alredy removed. #endif @@ -2051,6 +2053,11 @@ PyObject* initMathutils() return Mathutils_Init("Mathutils"); // Use as a top level module in BGE } +PyObject* initGeometry() +{ + return Geometry_Init("Geometry"); // Use as a top level module in BGE +} + PyObject* initBGL() { return BGL_Init("BGL"); // Use as a top level module in BGE diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 11360197b95..3253ac8f711 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -45,6 +45,7 @@ PyObject* initGameKeys(); PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas); PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie, int argc, char** argv); PyObject* initMathutils(); +PyObject* initGeometry(); PyObject* initBGL(); PyObject* initVideoTexture(void); void exitGamePlayerPythonScripting(); diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index d97f13b0758..dd7297080e5 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -9,6 +9,7 @@ defs = '' # Mathutils C files. sources.extend([\ '#source/blender/python/api2_2x/Mathutils.c',\ + '#source/blender/python/api2_2x/Geometry.c',\ '#source/blender/python/api2_2x/constant.c',\ '#source/blender/python/api2_2x/euler.c',\ '#source/blender/python/api2_2x/matrix.c',\ From 8570071e4075b51262ad2adae4881ca3077916bb Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 30 Apr 2009 15:27:38 +0000 Subject: [PATCH 125/444] supporting warp data files with tabs instead of spaces. --- source/gameengine/Ketsji/KX_Dome.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index e4c3d92fbf2..3802f260391 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -434,6 +434,8 @@ i ranges from 0 to 1, if negative don't draw that mesh node return false; } columns = lines[1].Explode(' '); + if(columns.size() == 1) + columns = lines[1].Explode('\t'); if(columns.size() !=2){ printf("Error: Warp Mesh File incorrect. The second line should contain: width height.\n"); @@ -453,6 +455,8 @@ i ranges from 0 to 1, if negative don't draw that mesh node for(i=2; i-2 < (warp.n_width*warp.n_height); i++){ columns = lines[i].Explode(' '); + if(columns.size() == 1) + columns = lines[i].Explode('\t'); if (columns.size() == 5){ nodeX = (i-2)%warp.n_width; From 2ec50d7bb282c3962d752771ceed8cb152f956a9 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 30 Apr 2009 19:00:17 +0000 Subject: [PATCH 126/444] BGE bug #18091: Hitbox of object X doesn't move along when object X is parented to object Y. --- .../Ketsji/KX_BulletPhysicsController.cpp | 19 +++++++++++-------- .../Ketsji/KX_BulletPhysicsController.h | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index 9e74706e1c0..300a7906e81 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -21,9 +21,13 @@ KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInf : KX_IPhysicsController(dyna,compound,(PHY_IPhysicsController*)this), CcdPhysicsController(ci), m_savedCollisionFlags(0), +m_savedCollisionFilterGroup(0), +m_savedCollisionFilterMask(0), +m_savedMass(0.0), +m_savedDyna(false), +m_suspended(false), m_bulletChildShape(NULL) { - } KX_BulletPhysicsController::~KX_BulletPhysicsController () @@ -337,8 +341,7 @@ void KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* c void KX_BulletPhysicsController::SetMass(MT_Scalar newmass) { btRigidBody *body = GetRigidBody(); - if (body && body->getActivationState() != DISABLE_SIMULATION && - newmass>MT_EPSILON && GetMass()>MT_EPSILON) + if (body && !m_suspended && newmass>MT_EPSILON && GetMass()>MT_EPSILON) { btVector3 grav = body->getGravity(); btVector3 accel = grav / GetMass(); @@ -356,7 +359,7 @@ void KX_BulletPhysicsController::SetMass(MT_Scalar newmass) void KX_BulletPhysicsController::SuspendDynamics(bool ghost) { btRigidBody *body = GetRigidBody(); - if (body && body->getActivationState() != DISABLE_SIMULATION) + if (body && !m_suspended) { btBroadphaseProxy* handle = body->getBroadphaseHandle(); m_savedCollisionFlags = body->getCollisionFlags(); @@ -364,8 +367,7 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost) m_savedDyna = m_bDyna; m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; m_savedCollisionFilterMask = handle->m_collisionFilterMask; - m_savedActivationState = body->getActivationState(); - body->forceActivationState(DISABLE_SIMULATION); + m_suspended = true; GetPhysicsEnvironment()->updateCcdPhysicsController(this, 0.0, btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), @@ -378,15 +380,16 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost) void KX_BulletPhysicsController::RestoreDynamics() { btRigidBody *body = GetRigidBody(); - if (body && body->getActivationState() == DISABLE_SIMULATION) + if (body && m_suspended) { GetPhysicsEnvironment()->updateCcdPhysicsController(this, m_savedMass, m_savedCollisionFlags, m_savedCollisionFilterGroup, m_savedCollisionFilterMask); - body->forceActivationState(m_savedActivationState); + body->activate(); m_bDyna = m_savedDyna; + m_suspended = false; } } diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 2174f0db499..9d2afad1a5c 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -14,6 +14,7 @@ private: short int m_savedCollisionFilterMask; MT_Scalar m_savedMass; bool m_savedDyna; + bool m_suspended; btCollisionShape* m_bulletChildShape; public: From 36d0e2649ee8bc95d68e5d8e5317aee4e82e44bf Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 30 Apr 2009 20:02:22 +0000 Subject: [PATCH 127/444] BGE bug fix: when a dynamic object is parented to a compound shape and then unparented, it jumps at the position it had before the parenting. --- source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 3e1e0294321..a0bf0448e3e 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -533,6 +533,12 @@ void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctr { btCollisionObject* obj = ctrl->GetCollisionObject(); obj->setUserPointer(ctrl); + // update the position of the object from the user + if (ctrl->GetMotionState()) + { + btTransform xform = CcdPhysicsController::GetTransformFromMotionState(ctrl->GetMotionState()); + ctrl->SetCenterOfMassTransform(xform); + } m_dynamicsWorld->addCollisionObject(obj, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask()); } From bb3fa18a95b898cd52437d03839e531140972941 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 1 May 2009 04:55:40 +0000 Subject: [PATCH 128/444] add blendfile dirs to the sys.path without the scripts subdir --- source/blender/python/api2_2x/Geometry.c | 2 +- source/blender/src/buttons_logic.c | 2 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index d568472c838..80869889af7 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -59,7 +59,7 @@ static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args ); static char M_Geometry_doc[] = "The Blender Geometry module\n\n"; static char M_Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles"; static char M_Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None"; -static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - takes a point and a line and returns a (Vector, Bool) for the point on the line, and the bool so you can know if the point was between the 2 points"; +static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - takes a point and a line and returns a (Vector, float) for the point on the line, and the bool so you can know if the point was between the 2 points"; static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triangle, only the x and y are used from the vectors"; static char M_Geometry_PointInQuad2D_doc[] = "(pt, quad_p1, quad_p2, quad_p3, quad_p4) - takes 5 vectors, one is the point and the next 4 define the quad, only the x and y are used from the vectors"; static char M_Geometry_BoxPack2D_doc[] = ""; diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 54b48de716f..941ed5ebe12 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1584,7 +1584,7 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco if(pc->mode==0) uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+90,yco-24,width-90, 19, &pc->text, "Blender textblock to run as a script"); else { - uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run eg \"someModule.main\", internal texts and //scripts/*.py on the filesystem can be used"); + uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run eg \"someModule.main\", internal texts external python files can be used"); uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restrting"); } uiBlockEndAlign(block); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index f5d32e36fc5..d774d8ed5f8 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1534,7 +1534,7 @@ void setSandbox(TPythonSecurityLevel level) * - initPySysPath(main) : initializes the blendfile and library paths * - restorePySysPath() : restores sys.path from gp_OrigPythonSysPath * - * These exist so the //scripts folder can always be used to import modules from. + * These exist so the current blend dir "//" can always be used to import modules from. * the reason we need a few functions for this is that python is not only used by the game engine * so we cant just add to sys.path all the time, it would leave pythons state in a mess. * It would also be incorrect since loading blend files for new levels etc would alwasy add to sys.path @@ -1569,7 +1569,6 @@ static void initPySysPath__append(PyObject *sys_path, char *filename) char expanded[FILE_MAXDIR + FILE_MAXFILE] = "//"; BLI_convertstringcode(expanded, filename); - BLI_join_dirfile(expanded, expanded, "scripts"); /* double checked and using the dir twice is safe */ item= PyString_FromString(expanded); From 742ddade1245973980d58ef3781226c7390506a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 1 May 2009 14:19:56 +0000 Subject: [PATCH 129/444] [#18654] different behaviour if script is called from (1) Menu (2) TextEditor (3) ScriptsWindow [including crash!] bugfix, simple NULL check --- source/blender/python/api2_2x/Draw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 57b3869d775..7e3f57da60d 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -915,12 +915,12 @@ static PyObject *Method_Exit( PyObject * self ) exit_pydraw( sc, 0 ); script = sc->script; - - /* remove our lock to the current namespace */ - script->flags &= ~SCRIPT_GUI; - script->scriptname[0] = '\0'; - script->scriptarg[0] = '\0'; - + if(script) { /* in very rare cases this can be NULL, (when saving and loading see bug #18654)*/ + /* remove our lock to the current namespace */ + script->flags &= ~SCRIPT_GUI; + script->scriptname[0] = '\0'; + script->scriptarg[0] = '\0'; + } Py_RETURN_NONE; } From 1c6cd47f2b93ba05c54f82c9363f269c71e28cda Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 1 May 2009 15:19:47 +0000 Subject: [PATCH 130/444] Fix linking issue with gameplayer. Kent --- source/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Makefile b/source/Makefile index b190118bc38..7374ef3e7d6 100644 --- a/source/Makefile +++ b/source/Makefile @@ -261,6 +261,7 @@ SPLIB += $(OCGDIR)/blender/readblenfile/$(DEBUG_DIR)libreadblenfile.a # can I just not check them? nm claims they aren't... SPLIB += $(OCGDIR)/blender/blenkernel/blenkernel_blc/$(DEBUG_DIR)libblenkernel_blc.a SPLIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a +SPLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a # These three need to be explicitly mentioned on the cl, because # if they are offered as a lib, they are optimized away. (nzc) From 672492f563e148dc608965c5d0011413fbfae0eb Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 1 May 2009 16:35:06 +0000 Subject: [PATCH 131/444] BGE: New function GameLogic.setMaxLogicFrame() to allow better control over the time spent on logic. This function sets the maximum number of logic frame executed per render frame. Valid values: 1..5 This function is useful to control the amount of processing consumed by logic. By default, up to 5 logic frames can be executed per render frame. This is fine as long as the time spent on logic is negligible compared to the render time. If it's not the case, the default value will drag the performance of the game down by executing unnecessary logic frames that take up most of the CPU time. You can avoid that by lowering the value with this function. The drawback is less precision in the logic system to physics and I/O activity. Note that it does not affect the physics system: physics will still run at full frame rate (actually up to 5 times the ticrate). You can further control the render frame rate with GameLogic.setLogicTicRate(). --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 31 +++- source/gameengine/Ketsji/KX_KetsjiEngine.h | 9 ++ source/gameengine/Ketsji/KX_PythonInit.cpp | 17 +++ .../Physics/BlOde/OdePhysicsEnvironment.cpp | 2 +- .../Physics/BlOde/OdePhysicsEnvironment.h | 2 +- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 135 ++++++++---------- .../Physics/Bullet/CcdPhysicsEnvironment.h | 2 +- .../Physics/Dummy/DummyPhysicsEnvironment.cpp | 2 +- .../Physics/Dummy/DummyPhysicsEnvironment.h | 2 +- .../Physics/Sumo/SumoPhysicsEnvironment.cpp | 2 +- .../Physics/Sumo/SumoPhysicsEnvironment.h | 2 +- .../Physics/common/PHY_IPhysicsEnvironment.h | 2 +- source/gameengine/PyDoc/GameLogic.py | 17 ++- 13 files changed, 138 insertions(+), 87 deletions(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 764c3c2dfec..d6747bd1ba4 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -97,6 +97,7 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { }; double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE; +int KX_KetsjiEngine::m_maxLogicFrame = 5; double KX_KetsjiEngine::m_anim_framerate = 25.0; double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; @@ -399,6 +400,7 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo) m_firstframe = true; m_bInitialized = true; m_ticrate = DEFAULT_LOGIC_TIC_RATE; + m_maxLogicFrame = 5; if (m_game2ipo) { @@ -511,7 +513,8 @@ void KX_KetsjiEngine::EndFrame() bool KX_KetsjiEngine::NextFrame() { - + double timestep = 1.0/m_ticrate; + double framestep = timestep; // static hidden::Clock sClock; m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(),true); @@ -520,7 +523,7 @@ m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(),true); //sClock.reset(); if (m_bFixedTime) - m_clockTime += 1./m_ticrate; + m_clockTime += timestep; else { @@ -554,18 +557,24 @@ else { // printf("framedOut: %d\n",frames); - m_frameTime+=(frames-frameOut)*(1.0/m_ticrate); + m_frameTime+=(frames-frameOut)*timestep; frames = frameOut; } bool doRender = frames>0; + if (frames > m_maxLogicFrame) + { + framestep = (frames*timestep)/m_maxLogicFrame; + frames = m_maxLogicFrame; + } + while (frames) { - m_frameTime += 1.0/m_ticrate; + m_frameTime += framestep; for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit) // for each scene, call the proceed functions @@ -644,7 +653,7 @@ else // Perform physics calculations on the scene. This can involve // many iterations of the physics solver. - scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,1.0/m_ticrate);//m_deltatimerealDeltaTime); + scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,timestep,framestep);//m_deltatimerealDeltaTime); m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); SG_SetActiveStage(SG_STAGE_PHYSICS2_UPDATE); @@ -717,7 +726,7 @@ else // Perform physics calculations on the scene. This can involve // many iterations of the physics solver. m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); - scene->GetPhysicsEnvironment()->proceedDeltaTime(m_clockTime,0.f); + scene->GetPhysicsEnvironment()->proceedDeltaTime(m_clockTime,timestep,timestep); // Update scenegraph after physics step. This maps physics calculations // into node positions. m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); @@ -1729,6 +1738,16 @@ void KX_KetsjiEngine::SetTicRate(double ticrate) m_ticrate = ticrate; } +int KX_KetsjiEngine::GetMaxLogicFrame() +{ + return m_maxLogicFrame; +} + +void KX_KetsjiEngine::SetMaxLogicFrame(int frame) +{ + m_maxLogicFrame = frame; +} + double KX_KetsjiEngine::GetAnimFrameRate() { return m_anim_framerate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index a8ccd6100d7..791c5d24daa 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -103,6 +103,7 @@ private: double m_previousClockTime;//previous clock time double m_remainingTime; + static int m_maxLogicFrame; /* maximum number of consecutive logic frame */ static double m_ticrate; static double m_anim_framerate; /* for animation playback only - ipo and action */ @@ -283,6 +284,14 @@ public: * Sets the number of logic updates per second. */ static void SetTicRate(double ticrate); + /** + * Gets the maximum number of logic frame before render frame + */ + static int KX_KetsjiEngine::GetMaxLogicFrame(); + /** + * Sets the maximum number of logic frame before render frame + */ + static void KX_KetsjiEngine::SetMaxLogicFrame(int frame); /** * Gets the framerate for playing animations. (actions and ipos) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index d774d8ed5f8..01c1382a6d1 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -288,6 +288,21 @@ static PyObject* gPyGetLogicTicRate(PyObject*) return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate()); } +static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args) +{ + int frame; + if (!PyArg_ParseTuple(args, "i:setMaxLogicFrame", &frame)) + return NULL; + + KX_KetsjiEngine::SetMaxLogicFrame(frame); + Py_RETURN_NONE; +} + +static PyObject* gPyGetMaxLogicFrame(PyObject*) +{ + return PyInt_FromLong(KX_KetsjiEngine::GetMaxLogicFrame()); +} + static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args) { float ticrate; @@ -479,6 +494,8 @@ static struct PyMethodDef game_methods[] = { {"setGravity",(PyCFunction) gPySetGravity, METH_O, (PY_METHODCHAR)"set Gravitation"}, {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS, (PY_METHODCHAR)"get audio spectrum"}, {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (PY_METHODCHAR)"stop using the audio dsp (for performance reasons)"}, + {"getMaxLogicFrame", (PyCFunction) gPyGetMaxLogicFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of logic frame per render frame"}, + {"setMaxLogicFrame", (PyCFunction) gPySetMaxLogicFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of logic frame per render frame"}, {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the logic tic rate"}, {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (PY_METHODCHAR)"Sets the logic tic rate"}, {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the physics tic rate"}, diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp index 2e8ee31058f..54e97858b7f 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp +++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp @@ -75,7 +75,7 @@ float ODEPhysicsEnvironment::getFixedTimeStep() -bool ODEPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep1) +bool ODEPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep1,float interval) { float deltaTime = timeStep1; diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h index 2e4709cf420..82e26e01460 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h +++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h @@ -44,7 +44,7 @@ public: // Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep); + virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); virtual float getFixedTimeStep(); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index a0bf0448e3e..bcf83e25d84 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -623,7 +623,7 @@ void CcdPhysicsEnvironment::debugDrawWorld() m_dynamicsWorld->debugDrawWorld(); } -bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) +bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep,float interval) { std::set::iterator it; int i; @@ -633,14 +633,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) (*it)->SynchronizeMotionStates(timeStep); } - processFhSprings(curTime,timeStep); - float subStep = timeStep / float(m_numTimeSubSteps); - for (i=0;istepSimulation(subStep,20,1./240.);//perform always a full simulation step - m_dynamicsWorld->stepSimulation(subStep,0);//perform always a full simulation step - } + i = m_dynamicsWorld->stepSimulation(interval,25,subStep);//perform always a full simulation step + processFhSprings(curTime,i*subStep); for (it=m_controllers.begin(); it!=m_controllers.end(); it++) { @@ -692,9 +687,11 @@ public: }; -void CcdPhysicsEnvironment::processFhSprings(double curTime,float timeStep) +void CcdPhysicsEnvironment::processFhSprings(double curTime,float interval) { std::set::iterator it; + // dynamic of Fh spring is based on a timestep of 1/60 + int numIter = (int)(interval*60.0001f); for (it=m_controllers.begin(); it!=m_controllers.end(); it++) { @@ -706,8 +703,6 @@ void CcdPhysicsEnvironment::processFhSprings(double curTime,float timeStep) //printf("has Fh or RotFh\n"); //re-implement SM_FhObject.cpp using btCollisionWorld::rayTest and info from ctrl->getConstructionInfo() //send a ray from {0.0, 0.0, 0.0} towards {0.0, 0.0, -10.0}, in local coordinates - - CcdPhysicsController* parentCtrl = ctrl->getParentCtrl(); btRigidBody* parentBody = parentCtrl?parentCtrl->GetRigidBody() : 0; btRigidBody* cl_object = parentBody ? parentBody : body; @@ -754,82 +749,78 @@ void CcdPhysicsEnvironment::processFhSprings(double curTime,float timeStep) btVector3 normal = resultCallback.m_hitNormalWorld; normal.normalize(); - - if (ctrl->getConstructionInfo().m_do_fh) + for (int i=0; igetCenterOfMassPosition() - + rayDirLocal * resultCallback.m_closestHitFraction; - - - - - lspot -= hit_object->getCenterOfMassPosition(); - btVector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocityInLocalPoint(lspot); - btScalar rel_vel_ray = ray_dir.dot(rel_vel); - btScalar spring_extent = 1.0 - distance / hitObjShapeProps.m_fh_distance; - - btScalar i_spring = spring_extent * hitObjShapeProps.m_fh_spring; - btScalar i_damp = rel_vel_ray * hitObjShapeProps.m_fh_damping; - - cl_object->setLinearVelocity(cl_object->getLinearVelocity() + (-(i_spring + i_damp) * ray_dir)); - if (hitObjShapeProps.m_fh_normal) + if (ctrl->getConstructionInfo().m_do_fh) { - cl_object->setLinearVelocity(cl_object->getLinearVelocity()+(i_spring + i_damp) *(normal - normal.dot(ray_dir) * ray_dir)); - } - - btVector3 lateral = rel_vel - rel_vel_ray * ray_dir; - - - if (ctrl->getConstructionInfo().m_do_anisotropic) { - //Bullet basis contains no scaling/shear etc. - const btMatrix3x3& lcs = cl_object->getCenterOfMassTransform().getBasis(); - btVector3 loc_lateral = lateral * lcs; - const btVector3& friction_scaling = cl_object->getAnisotropicFriction(); - loc_lateral *= friction_scaling; - lateral = lcs * loc_lateral; + btVector3 lspot = cl_object->getCenterOfMassPosition() + + rayDirLocal * resultCallback.m_closestHitFraction; + + + + + lspot -= hit_object->getCenterOfMassPosition(); + btVector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocityInLocalPoint(lspot); + btScalar rel_vel_ray = ray_dir.dot(rel_vel); + btScalar spring_extent = 1.0 - distance / hitObjShapeProps.m_fh_distance; + + btScalar i_spring = spring_extent * hitObjShapeProps.m_fh_spring; + btScalar i_damp = rel_vel_ray * hitObjShapeProps.m_fh_damping; + + cl_object->setLinearVelocity(cl_object->getLinearVelocity() + (-(i_spring + i_damp) * ray_dir)); + if (hitObjShapeProps.m_fh_normal) + { + cl_object->setLinearVelocity(cl_object->getLinearVelocity()+(i_spring + i_damp) *(normal - normal.dot(ray_dir) * ray_dir)); + } + + btVector3 lateral = rel_vel - rel_vel_ray * ray_dir; + + + if (ctrl->getConstructionInfo().m_do_anisotropic) { + //Bullet basis contains no scaling/shear etc. + const btMatrix3x3& lcs = cl_object->getCenterOfMassTransform().getBasis(); + btVector3 loc_lateral = lateral * lcs; + const btVector3& friction_scaling = cl_object->getAnisotropicFriction(); + loc_lateral *= friction_scaling; + lateral = lcs * loc_lateral; + } + + btScalar rel_vel_lateral = lateral.length(); + + if (rel_vel_lateral > SIMD_EPSILON) { + btScalar friction_factor = hit_object->getFriction();//cl_object->getFriction(); + + btScalar max_friction = friction_factor * btMax(btScalar(0.0), i_spring); + + btScalar rel_mom_lateral = rel_vel_lateral / cl_object->getInvMass(); + + btVector3 friction = (rel_mom_lateral > max_friction) ? + -lateral * (max_friction / rel_vel_lateral) : + -lateral; + + cl_object->applyCentralImpulse(friction); + } } - btScalar rel_vel_lateral = lateral.length(); - if (rel_vel_lateral > SIMD_EPSILON) { - btScalar friction_factor = hit_object->getFriction();//cl_object->getFriction(); + if (ctrl->getConstructionInfo().m_do_rot_fh) { + btVector3 up2 = cl_object->getWorldTransform().getBasis().getColumn(2); - btScalar max_friction = friction_factor * btMax(btScalar(0.0), i_spring); + btVector3 t_spring = up2.cross(normal) * hitObjShapeProps.m_fh_spring; + btVector3 ang_vel = cl_object->getAngularVelocity(); - btScalar rel_mom_lateral = rel_vel_lateral / cl_object->getInvMass(); + // only rotations that tilt relative to the normal are damped + ang_vel -= ang_vel.dot(normal) * normal; - btVector3 friction = (rel_mom_lateral > max_friction) ? - -lateral * (max_friction / rel_vel_lateral) : - -lateral; + btVector3 t_damp = ang_vel * hitObjShapeProps.m_fh_damping; - cl_object->applyCentralImpulse(friction); + cl_object->setAngularVelocity(cl_object->getAngularVelocity() + (t_spring - t_damp)); } } - - - if (ctrl->getConstructionInfo().m_do_rot_fh) { - btVector3 up2 = cl_object->getWorldTransform().getBasis().getColumn(2); - - btVector3 t_spring = up2.cross(normal) * hitObjShapeProps.m_fh_spring; - btVector3 ang_vel = cl_object->getAngularVelocity(); - - // only rotations that tilt relative to the normal are damped - ang_vel -= ang_vel.dot(normal) * normal; - - btVector3 t_damp = ang_vel * hitObjShapeProps.m_fh_damping; - - cl_object->setAngularVelocity(cl_object->getAngularVelocity() + (t_spring - t_damp)); - } - } - - } - - } } - } void CcdPhysicsEnvironment::setDebugMode(int debugMode) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index f861621ae37..5f9fb9511d6 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -114,7 +114,7 @@ protected: virtual void beginFrame(); virtual void endFrame() {}; /// Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep); + virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); virtual void debugDrawWorld(); // virtual bool proceedDeltaTimeOneStep(float timeStep); diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp index ba196b5cf55..e41574ff181 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp @@ -57,7 +57,7 @@ void DummyPhysicsEnvironment::endFrame() -bool DummyPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) +bool DummyPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep,float interval) { //step physics simulation, typically perform diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 4e15e6ec130..397a1ba4218 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -48,7 +48,7 @@ public: virtual void beginFrame(); virtual void endFrame(); // Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep); + virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); virtual float getFixedTimeStep(); diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp index 3be5e027345..cc6d5654ec9 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp @@ -81,7 +81,7 @@ float SumoPhysicsEnvironment::getFixedTimeStep() } -bool SumoPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) +bool SumoPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep,float interval) { bool result = false; diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h index 418a361a065..c2b443a2b38 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h @@ -54,7 +54,7 @@ public: virtual void beginFrame(); virtual void endFrame(); // Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep); + virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); virtual float getFixedTimeStep(); diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 9a4500c3214..a3605669f70 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -89,7 +89,7 @@ class PHY_IPhysicsEnvironment virtual void beginFrame() = 0; virtual void endFrame() = 0; /// Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep)=0; + virtual bool proceedDeltaTime(double curTime,float timeStep,float interval)=0; ///draw debug lines (make sure to call this during the render phase, otherwise lines are not drawn properly) virtual void debugDrawWorld(){} virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)=0; diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 74e7f852018..85e94e63416 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -360,6 +360,21 @@ def stopDSP(): Only the fmod sound driver supports this. DSP can be computationally expensive. """ +def getMaxLogicFrame(): + """ + Gets the maximum number of logic frame per render frame. + + @return: The maximum number of logic frame per render frame + @rtype: interger + """ +def setMaxLogicFrame(maxlogic): + """ + Sets the maximum number of logic frame that are executed per render frame. + This does not affect the physic system that still runs at full frame rate. + + @param maxlogic: The new maximum number of logic frame per render frame. Valid values: 1..5 + @type maxlogic: integer + """ def getLogicTicRate(): """ Gets the logic update frequency. @@ -372,7 +387,7 @@ def setLogicTicRate(ticrate): Sets the logic update frequency. The logic update frequency is the number of times logic bricks are executed every second. - The default is 30 Hz. + The default is 60 Hz. @param ticrate: The new logic update frequency (in Hz). @type ticrate: float From e13a089d918cbe3709f544ccebbb718a452ac6fa Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 1 May 2009 19:02:23 +0000 Subject: [PATCH 132/444] BGE: work around a problem with DBVT culling when graphic objects are rescaled. This happens when objects with very diverse scale are instantiated with dupligroup. The problem remains when the objects are rescaled during the game. The effect of the problem is an inefficient culling: objects can have a bounding box larger than needed. Patch to fix the problem is filed at Bullet forum. --- source/gameengine/Ketsji/KX_GameObject.cpp | 29 +++++++++++++++++++ source/gameengine/Ketsji/KX_GameObject.h | 4 +++ source/gameengine/Ketsji/KX_Scene.cpp | 7 ++++- .../Physics/Bullet/CcdGraphicController.cpp | 11 ++++++- .../Physics/Bullet/CcdGraphicController.h | 4 +++ .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 2 +- .../Physics/common/PHY_IGraphicController.h | 1 + 7 files changed, 55 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 20113afaae2..fa95a89135b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -331,6 +331,35 @@ void KX_GameObject::ProcessReplica() } +static void setGraphicController_recursive(SG_Node* node, bool v) +{ + NodeList& children = node->GetSGChildren(); + + for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) + { + SG_Node* childnode = (*childit); + KX_GameObject *clientgameobj = static_cast( (*childit)->GetSGClientObject()); + if (clientgameobj != NULL) // This is a GameObject + clientgameobj->ActivateGraphicController(v, false); + + // if the childobj is NULL then this may be an inverse parent link + // so a non recursive search should still look down this node. + setGraphicController_recursive(childnode, v); + } +} + + +void KX_GameObject::ActivateGraphicController(bool active, bool recurse) +{ + if (m_pGraphicController) + { + m_pGraphicController->Activate(active); + } + if (recurse) + { + setGraphicController_recursive(GetSGNode(), active); + } +} CValue* KX_GameObject::GetReplica() diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index fe9f39a6ed3..14ed713ecfa 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -385,6 +385,10 @@ public: { m_pGraphicController = graphiccontroller; } + /* + * @add/remove the graphic controller to the physic system + */ + void ActivateGraphicController(bool active, bool recurse); /** * @section Coordinate system manipulation functions diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index fd244037722..36486440c00 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -717,10 +717,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) // set the orientation after position for softbody! MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation(); replica->NodeSetLocalOrientation(newori); - + // update scenegraph for entire tree of children replica->GetSGNode()->UpdateWorldData(0); replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox()); replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius()); + // we can now add the graphic controller to the physic engine + replica->ActivateGraphicController(true,true); + // done with replica replica->Release(); } @@ -831,6 +834,8 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, replica->GetSGNode()->UpdateWorldData(0); replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox()); replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius()); + // the size is correct, we can add the graphic controller to the physic engine + replica->ActivateGraphicController(true,true); // now replicate logic vector::iterator git; diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp index 2d1f841af0c..2dbbb7fa4a0 100644 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp +++ b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp @@ -118,8 +118,17 @@ PHY_IGraphicController* CcdGraphicController::GetReplica(class PHY_IMotionState* replica->m_motionState = motionState; replica->m_newClientInfo = NULL; replica->m_handle = NULL; - m_phyEnv->addCcdGraphicController(replica); + // don't add the graphic controller now: work around a bug in Bullet with rescaling, + // (the scale of the controller is not yet defined). + //m_phyEnv->addCcdGraphicController(replica); return replica; } +void CcdGraphicController::Activate(bool active) +{ + if (active) + m_phyEnv->addCcdGraphicController(this); + else + m_phyEnv->removeCcdGraphicController(this); +} diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h index 8f44a623371..b0626f902c2 100644 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.h +++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h @@ -55,6 +55,10 @@ public: * Updates the Aabb based on the motion state */ virtual bool SetGraphicTransform(); + /** + * Add/remove to environment + */ + virtual void Activate(bool active); // client info for culling virtual void* getNewClientInfo() { return m_newClientInfo; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index bcf83e25d84..03c9d13a7dd 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -579,7 +579,7 @@ void CcdPhysicsEnvironment::refreshCcdPhysicsController(CcdPhysicsController* ct void CcdPhysicsEnvironment::addCcdGraphicController(CcdGraphicController* ctrl) { - if (m_cullingTree) + if (m_cullingTree && !ctrl->getBroadphaseHandle()) { btVector3 minAabb; btVector3 maxAabb; diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h index 8acc5c2f9d3..470d42cb84a 100644 --- a/source/gameengine/Physics/common/PHY_IGraphicController.h +++ b/source/gameengine/Physics/common/PHY_IGraphicController.h @@ -47,6 +47,7 @@ class PHY_IGraphicController : public PHY_IController SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') */ virtual bool SetGraphicTransform()=0; + virtual void Activate(bool active=true)=0; virtual void setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax)=0; virtual void setLocalAabb(const float* aabbMin,const float* aabbMax)=0; From 07abb9dee2aba5ed161c22f3ec45031f9fdb183a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 1 May 2009 20:34:23 +0000 Subject: [PATCH 133/444] BGE performance: - Vast performance increase when removing scene containing large number of objects: the sensor/controller map was updated for each deleted object, causing massive slow down when the number of objects was large (O(n^2)). - Use reference when scanning the sensor map => avoid useless copy. - Remove dynamically the object bounding box from the DBVT when the object is invisible => faster culling. --- .../gameengine/GameLogic/SCA_LogicManager.cpp | 29 +++++++++++++------ .../gameengine/GameLogic/SCA_LogicManager.h | 8 +++-- source/gameengine/Ketsji/KX_GameObject.cpp | 2 ++ source/gameengine/Ketsji/KX_KetsjiEngine.h | 4 +-- source/gameengine/Ketsji/KX_Scene.cpp | 2 ++ 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index b584b37180f..0b549ded474 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -79,6 +79,13 @@ SCA_LogicManager::~SCA_LogicManager() m_activeActuators.clear(); } +// this function is a performance helper when the scene is destoyed +// without it, the map updated for each object... a massive slow down when there are +// large number of objects. By clearing the map upfront we avoid the waster of time. +void SCA_LogicManager::RemoveSensorMap() +{ + m_sensorcontrollermapje.clear(); +} /* // this kind of fixes bug 398 but breakes games, so better leave it out for now. @@ -171,12 +178,16 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) { - controllerlist contlist = m_sensorcontrollermapje[sensor]; - for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++) + sensormap_t::const_iterator mit = m_sensorcontrollermapje.find(sensor); + if (mit != m_sensorcontrollermapje.end()) { - (*c)->UnlinkSensor(sensor); + const controllerlist& contlist = mit->second; + for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++) + { + (*c)->UnlinkSensor(sensor); + } + m_sensorcontrollermapje.erase(sensor); } - m_sensorcontrollermapje.erase(sensor); sensor->UnregisterToManager(); } @@ -184,7 +195,7 @@ void SCA_LogicManager::RemoveController(SCA_IController* controller) { controller->UnlinkAllSensors(); controller->UnlinkAllActuators(); - std::map::iterator sit; + sensormap_t::iterator sit; for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) { (*sit).second.remove(controller); @@ -197,10 +208,10 @@ void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator) m_removedActuators.push_back(SmartActuatorPtr(actuator,0)); // take care that no controller can use this actuator again ! - std::map::const_iterator sit; + sensormap_t::const_iterator sit; for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) { - controllerlist contlist = (*sit).second; + const controllerlist& contlist = sit->second; for (list::const_iterator c= contlist.begin();!(c==contlist.end());c++) { (*c)->UnlinkActuator(actuator); @@ -237,8 +248,8 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime) !(is==m_activatedsensors.end());is++) { SCA_ISensor* sensor = *is; - controllerlist contlist = m_sensorcontrollermapje[sensor]; - for (list::const_iterator c= contlist.begin(); + const controllerlist& contlist = m_sensorcontrollermapje[sensor]; + for (list::const_iterator c= contlist.begin(); !(c==contlist.end());c++) { SCA_IController* contr = *c;//controllerarray->at(c); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index 50383879d8f..17971c219e5 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -47,7 +47,8 @@ #include "KX_HashedPtr.h" using namespace std; -typedef list controllerlist; +typedef std::list controllerlist; +typedef std::map sensormap_t; /** * This manager handles sensor, controllers and actuators. @@ -101,7 +102,7 @@ class SCA_LogicManager set m_activeActuators; set m_triggeredControllerSet; - map m_sensorcontrollermapje; + sensormap_t m_sensorcontrollermapje; // need to find better way for this // also known as FactoryManager... @@ -116,6 +117,9 @@ class SCA_LogicManager public: SCA_LogicManager(); virtual ~SCA_LogicManager(); + // can ONLY be used during scene destruction, avoid massive slow down when scene has many many objects + void RemoveSensorMap(); + //void SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;} void RegisterEventManager(SCA_EventManager* eventmgr); void RegisterToSensor(SCA_IController* controller, diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fa95a89135b..22b9c940178 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -628,6 +628,8 @@ KX_GameObject::SetVisible( { if (GetSGNode()) { m_bVisible = v; + if (m_pGraphicController) + m_pGraphicController->Activate(m_bVisible); if (recursive) setVisible_recursive(GetSGNode(), v); } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 791c5d24daa..528465b6c2c 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -287,11 +287,11 @@ public: /** * Gets the maximum number of logic frame before render frame */ - static int KX_KetsjiEngine::GetMaxLogicFrame(); + static int GetMaxLogicFrame(); /** * Sets the maximum number of logic frame before render frame */ - static void KX_KetsjiEngine::SetMaxLogicFrame(int frame); + static void SetMaxLogicFrame(int frame); /** * Gets the framerate for playing animations. (actions and ipos) diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 36486440c00..171ed5d130f 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -208,6 +208,8 @@ KX_Scene::~KX_Scene() // It's still there but we remove all properties here otherwise some // reference might be hanging and causing late release of objects RemoveAllDebugProperties(); + // early removal of sensor map to avoid massive slow down when there are many objects + m_logicmgr->RemoveSensorMap(); while (GetRootParentList()->GetCount() > 0) { From ef20036b847396940de475c16e364661690c63a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 May 2009 02:40:11 +0000 Subject: [PATCH 134/444] BGE Py API patch from Mitchell Stokes, adds extra attributes and docs --- .../Converter/BL_ActionActuator.cpp | 1 - .../gameengine/GameLogic/SCA_ILogicBrick.cpp | 2 +- source/gameengine/Ketsji/KX_GameActuator.cpp | 2 +- .../gameengine/Ketsji/KX_ParentActuator.cpp | 2 +- source/gameengine/Ketsji/KX_ParentActuator.h | 1 + source/gameengine/Ketsji/KX_PythonInit.cpp | 25 +++++++++++++++++++ source/gameengine/Ketsji/KX_SceneActuator.cpp | 4 +-- source/gameengine/PyDoc/GameLogic.py | 18 +++++++++++++ source/gameengine/PyDoc/KX_GameActuator.py | 2 ++ source/gameengine/PyDoc/KX_ParentActuator.py | 2 ++ source/gameengine/PyDoc/KX_SceneActuator.py | 2 ++ source/gameengine/PyDoc/SCA_ILogicBrick.py | 2 ++ 12 files changed, 57 insertions(+), 6 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index ee97e325a8e..8b8e6b54320 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -1015,7 +1015,6 @@ PyAttributeDef BL_ActionActuator::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("continue", BL_ActionActuator, m_end_reset), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime), KX_PYATTRIBUTE_SHORT_RW_CHECK("type",0,100,false,BL_ActionActuator,m_playtype,CheckType), - //KX_PYATTRIBUTE_TODO("channel"), { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 84babda1d7a..c138ae46283 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -254,7 +254,7 @@ PyMethodDef SCA_ILogicBrick::Methods[] = { PyAttributeDef SCA_ILogicBrick::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("owner", SCA_ILogicBrick, pyattr_get_owner), KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Ueber_Priority), - //KX_PYATTRIBUTE_TODO("name"), + KX_PYATTRIBUTE_STRING_RO("name", SCA_ILogicBrick, m_name), {NULL} //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 48d7dcd84a2..9588e14d360 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -253,7 +253,7 @@ PyMethodDef KX_GameActuator::Methods[] = PyAttributeDef KX_GameActuator::Attributes[] = { KX_PYATTRIBUTE_STRING_RW("file",0,100,false,KX_GameActuator,m_filename), - //KX_PYATTRIBUTE_TODO("mode"), + KX_PYATTRIBUTE_INT_RW("mode", KX_GAME_NODEF+1, KX_GAME_MAX-1, true, KX_GameActuator, m_mode), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 37d2e50cdb6..f55ffd4f69a 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -178,7 +178,7 @@ PyMethodDef KX_ParentActuator::Methods[] = { PyAttributeDef KX_ParentActuator::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object), - //KX_PYATTRIBUTE_TODO("mode"), + KX_PYATTRIBUTE_INT_RW("mode", KX_PARENT_NODEF+1, KX_PARENT_MAX-1, true, KX_ParentActuator, m_mode), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index a9bf7304bc8..6af0888e2ba 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -57,6 +57,7 @@ class KX_ParentActuator : public SCA_IActuator KX_PARENT_NODEF = 0, KX_PARENT_SET, KX_PARENT_REMOVE, + KX_PARENT_MAX }; diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 01c1382a6d1..afc1fc5d1f8 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -49,6 +49,9 @@ #include "KX_KetsjiEngine.h" #include "KX_RadarSensor.h" #include "KX_RaySensor.h" +#include "KX_SceneActuator.h" +#include "KX_GameActuator.h" +#include "KX_ParentActuator.h" #include "KX_SCA_DynamicActuator.h" #include "SCA_IInputDevice.h" @@ -1359,6 +1362,28 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_LOCAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCAL); KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_DOROTFH, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DOROTFH); + /* Game Actuator Modes */ + KX_MACRO_addTypesToDict(d, KX_GAME_LOAD, KX_GameActuator::KX_GAME_LOAD); + KX_MACRO_addTypesToDict(d, KX_GAME_START, KX_GameActuator::KX_GAME_START); + KX_MACRO_addTypesToDict(d, KX_GAME_RESTART, KX_GameActuator::KX_GAME_RESTART); + KX_MACRO_addTypesToDict(d, KX_GAME_QUIT, KX_GameActuator::KX_GAME_QUIT); + KX_MACRO_addTypesToDict(d, KX_GAME_SAVECFG, KX_GameActuator::KX_GAME_SAVECFG); + KX_MACRO_addTypesToDict(d, KX_GAME_LOADCFG, KX_GameActuator::KX_GAME_LOADCFG); + + /* Scene Actuator Modes */ + KX_MACRO_addTypesToDict(d, KX_SCENE_RESTART, KX_SceneActuator::KX_SCENE_RESTART); + KX_MACRO_addTypesToDict(d, KX_SCENE_SET_SCENE, KX_SceneActuator::KX_SCENE_SET_SCENE); + KX_MACRO_addTypesToDict(d, KX_SCENE_SET_CAMERA, KX_SceneActuator::KX_SCENE_SET_CAMERA); + KX_MACRO_addTypesToDict(d, KX_SCENE_ADD_FRONT_SCENE, KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE); + KX_MACRO_addTypesToDict(d, KX_SCENE_ADD_BACK_SCENE, KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE); + KX_MACRO_addTypesToDict(d, KX_SCENE_REMOVE_SCENE, KX_SceneActuator::KX_SCENE_REMOVE_SCENE); + KX_MACRO_addTypesToDict(d, KX_SCENE_SUSPEND, KX_SceneActuator::KX_SCENE_SUSPEND); + KX_MACRO_addTypesToDict(d, KX_SCENE_RESUME, KX_SceneActuator::KX_SCENE_RESUME); + + /* Parent Actuator Modes */ + KX_MACRO_addTypesToDict(d, KX_PARENT_SET, KX_ParentActuator::KX_PARENT_SET); + KX_MACRO_addTypesToDict(d, KX_PARENT_REMOVE, KX_ParentActuator::KX_PARENT_REMOVE); + // Check for errors if (PyErr_Occurred()) { diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 1cce93fbcc5..eed1bb8027b 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -275,8 +275,8 @@ PyMethodDef KX_SceneActuator::Methods[] = PyAttributeDef KX_SceneActuator::Attributes[] = { KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName), KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera), - //KX_PYATTRIBUTE_TODO("useRestart"), - //KX_PYATTRIBUTE_TODO("mode"), + KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart), + KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode), { NULL } //Sentinel }; diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 85e94e63416..708dc29f137 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -187,6 +187,24 @@ Documentation for the GameLogic Module. @var KX_DYN_DISABLE_RIGID_BODY: See L{KX_SCA_DynamicActuator} @var KX_DYN_SET_MASS: See L{KX_SCA_DynamicActuator} +@group Game Actuator: KX_GAME_LOAD, KX_GAME_START, KX_GAME_RESTART, KX_GAME_QUIT, KX_GAME_SAVECFG, KX_GAME_LOADCFG +@var KX_Game_LOAD: See L{KX_GameActuator} +@var KX_Game_START: See L{KX_GameActuator} +@var KX_Game_RESTART: See L{KX_GameActuator} +@var KX_Game_QUIT: See L{KX_GameActuator} +@var KX_Game_SAVECFG: See L{KX_GameActuator} +@var KX_Game_LOADCFG: See L{KX_GameActuator} + +@group Scene Actuator: KX_SCENE_RESTART, KX_SCENE_SET_SCENE, KX_SCENE_SET_CAMERA, KX_SCENE_ADD_FRONT_SCENE, KX_SCENE_ADD_BACK_SCENE, KX_SCENE_REMOVE_SCENE, KX_SCENE_SUSPEND, KX_SCENE_RESUME +KX_SCENE_RESTART: See L{KX_SceneActuator} +KX_SCENE_SET_SCENE: See L{KX_SceneActuator} +KX_SCENE_SET_CAMERA: See L{KX_SceneActuator} +KX_SCENE_ADD_FRONT_SCENE: See L{KX_SceneActuator} +KX_SCENE_ADD_BACK_SCENE: See L{KX_SceneActuator} +KX_SCENE_REMOVE_SCENE: See L{KX_SceneActuator} +KX_SCENE_SUSPEND: See L{KX_SceneActuator} +KX_SCENE_RESUME: See L{KX_SceneActuator} + @group Input Status: KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED @var KX_INPUT_NONE: See L{SCA_MouseSensor} @var KX_INPUT_JUST_ACTIVATED: See L{SCA_MouseSensor} diff --git a/source/gameengine/PyDoc/KX_GameActuator.py b/source/gameengine/PyDoc/KX_GameActuator.py index fc5bd6005fc..0b329419ad7 100644 --- a/source/gameengine/PyDoc/KX_GameActuator.py +++ b/source/gameengine/PyDoc/KX_GameActuator.py @@ -10,6 +10,8 @@ class KX_GameActuator(SCA_IActuator): @ivar file: the new .blend file to load @type file: string. + @ivar mode: The mode of this actuator + @type mode: int from 0 to 5 L{GameLogic.Game Actuator} """ def getFile(): """ diff --git a/source/gameengine/PyDoc/KX_ParentActuator.py b/source/gameengine/PyDoc/KX_ParentActuator.py index 2f5d9515d0b..1e2bfe60a4f 100644 --- a/source/gameengine/PyDoc/KX_ParentActuator.py +++ b/source/gameengine/PyDoc/KX_ParentActuator.py @@ -7,6 +7,8 @@ class KX_ParentActuator(SCA_IActuator): The parent actuator can set or remove an objects parent object. @ivar object: the object this actuator sets the parent too. @type object: KX_GameObject or None + @ivar mode: The mode of this actuator + @type mode: int from 0 to 1 L{GameLogic.Parent Actuator} """ def setObject(object): """ diff --git a/source/gameengine/PyDoc/KX_SceneActuator.py b/source/gameengine/PyDoc/KX_SceneActuator.py index 6e27257533e..2429cd6fb80 100644 --- a/source/gameengine/PyDoc/KX_SceneActuator.py +++ b/source/gameengine/PyDoc/KX_SceneActuator.py @@ -18,6 +18,8 @@ class KX_SceneActuator(SCA_IActuator): @ivar camera: the camera to change to. When setting the attribute, you can use either a L{KX_Camera} or the name of the camera. @type camera: L{KX_Camera} on read, string or L{KX_Camera} on write + @type mode: The mode of the actuator + @type mode: int from 0 to 5 L{GameLogic.Scene Actuator} """ def setUseRestart(flag): """ diff --git a/source/gameengine/PyDoc/SCA_ILogicBrick.py b/source/gameengine/PyDoc/SCA_ILogicBrick.py index 2bfe407204a..a96e77c3249 100644 --- a/source/gameengine/PyDoc/SCA_ILogicBrick.py +++ b/source/gameengine/PyDoc/SCA_ILogicBrick.py @@ -11,6 +11,8 @@ class SCA_ILogicBrick(CValue): @type executePriority: int @ivar owner: The game object this logic brick is attached to (read only). @type owner: L{KX_GameObject} or None in exceptional cases. + @ivar name: The name of this logic brick (read only). + @type name: string @group Deprecated: getOwner, setExecutePriority, getExecutePriority """ From 41f42099acba137bbc6411341819fa1c8cd6d769 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 May 2009 04:53:01 +0000 Subject: [PATCH 135/444] BGE Py API patch from Mitchell Stokes, add distance attribute to the radar sensor, dont use 'continue' because its a python keyword. removed (ssizeobjargproc) it breaks py2.3 --- source/gameengine/Converter/BL_ActionActuator.cpp | 2 +- source/gameengine/Expressions/ListValue.cpp | 2 +- source/gameengine/Ketsji/KX_RadarSensor.cpp | 1 + source/gameengine/PyDoc/BL_ActionActuator.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 8b8e6b54320..646a65d347b 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -1012,7 +1012,7 @@ PyAttributeDef BL_ActionActuator::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ActionActuator, m_localtime, CheckFrame), KX_PYATTRIBUTE_STRING_RW("property", 0, 31, false, BL_ActionActuator, m_propname), KX_PYATTRIBUTE_STRING_RW("frameProperty", 0, 31, false, BL_ActionActuator, m_framepropname), - KX_PYATTRIBUTE_BOOL_RW("continue", BL_ActionActuator, m_end_reset), + KX_PYATTRIBUTE_BOOL_RW("useContinue", BL_ActionActuator, m_end_reset), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime), KX_PYATTRIBUTE_SHORT_RW_CHECK("type",0,100,false,BL_ActionActuator,m_playtype,CheckType), { NULL } //Sentinel diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index fc6b9299146..027d2594336 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -218,7 +218,7 @@ static PySequenceMethods listvalue_as_sequence = { NULL, #else listvalue_buffer_slice, /*sq_slice*/ - (ssizeobjargproc)NULL, /*sq_ass_item*/ + NULL, /*sq_ass_item*/ NULL, /*sq_ass_slice*/ #endif }; diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 1959dd52046..4532224a81e 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -280,6 +280,7 @@ PyMethodDef KX_RadarSensor::Methods[] = { PyAttributeDef KX_RadarSensor::Attributes[] = { KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneOrigin", KX_RadarSensor, m_cone_origin, 3), KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneTarget", KX_RadarSensor, m_cone_target, 3), + KX_PYATTRIBUTE_FLOAT_RO("distance", KX_RadarSensor, m_coneheight), KX_PYATTRIBUTE_FLOAT_RW("angle", 0, 360, KX_RadarSensor, m_coneradius), KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RadarSensor, m_axis), {NULL} //Sentinel diff --git a/source/gameengine/PyDoc/BL_ActionActuator.py b/source/gameengine/PyDoc/BL_ActionActuator.py index 480681dc14a..455f83d5ce7 100644 --- a/source/gameengine/PyDoc/BL_ActionActuator.py +++ b/source/gameengine/PyDoc/BL_ActionActuator.py @@ -29,7 +29,7 @@ class BL_ActionActuator(SCA_IActuator): @type blendTime: float @ivar type: The operation mode of the actuator. KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND @type type: integer - @ivar continue: The actions continue option, True or False. + @ivar useContinue: The actions continue option, True or False. When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. @type: boolean From 40fc1d2af74257ee45ae1b5bf7564b3b5768eb80 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 May 2009 15:09:06 +0000 Subject: [PATCH 136/444] BGE PyController module type. - Added support for any number of attributes, this means packages are supported automatically. so as well as "myModule.myFunc" you can do "myPackage.myModule.myFunc", nested packages work too. - pass the controller to the python function as an argument for functions that take 1 arg, this check is only done at startup so it wont slow things down. added support for --- .../GameLogic/SCA_PythonController.cpp | 61 +++++++++++++++---- .../GameLogic/SCA_PythonController.h | 2 + 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index d443c1688e4..bf4c2475a64 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -53,6 +53,7 @@ SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, : SCA_IController(gameobj, T), m_bytecode(NULL), m_function(NULL), + m_function_argc(0), m_bModified(true), m_debug(false), m_mode(mode), @@ -325,14 +326,14 @@ bool SCA_PythonController::Import() Py_XDECREF(m_function); m_function= NULL; - vector module_func = m_scriptText.Explode('.'); + vector py_function_path = m_scriptText.Explode('.'); - if(module_func.size() != 2 || module_func[0].Length()==0 || module_func[1].Length()==0) { - printf("Python module name formatting error \"%s\":\n\texpected \"SomeModule.Func\", got \"%s\"", GetName().Ptr(), m_scriptText.Ptr()); + if(py_function_path.size() < 2) { + printf("Python module name formatting error \"%s\":\n\texpected \"SomeModule.Func\", got \"%s\"\n", GetName().Ptr(), m_scriptText.Ptr()); return false; } - PyObject *mod = PyImport_ImportModule((char *)module_func[0].Ptr()); + PyObject *mod = PyImport_ImportModule((char *)py_function_path[0].Ptr()); if(mod && m_debug) { Py_DECREF(mod); /* getting a new one so dont hold a ref to the old one */ mod= PyImport_ReloadModule(mod); @@ -342,24 +343,50 @@ bool SCA_PythonController::Import() ErrorPrint("Python module not found"); return false; } - Py_DECREF(mod); /* will be added to sys.modules so no need to keep a ref */ + /* 'mod' will be DECREF'd as 'base' + * 'm_function' will be left holding a reference that the controller owns */ + PyObject *base= mod; - PyObject *dict= PyModule_GetDict(mod); - m_function= PyDict_GetItemString(dict, module_func[1]); /* borrow */ + for(unsigned int i=1; i < py_function_path.size(); i++) { + m_function = PyObject_GetAttrString(base, py_function_path[i].Ptr()); + Py_DECREF(base); + base = m_function; /* for the next loop if there is on */ + + if(m_function==NULL) { + PyErr_Clear(); /* print our own error below */ + break; + } + } if(m_function==NULL) { - printf("Python module error \"%s\":\n \"%s\" module fount but function missing\n", GetName().Ptr(), m_scriptText.Ptr()); + printf("Python module error \"%s\":\n \"%s\" module found but function missing\n", GetName().Ptr(), m_scriptText.Ptr()); return false; } if(!PyCallable_Check(m_function)) { - printf("Python module function error \"%s\":\n \"%s\" not callable", GetName().Ptr(), m_scriptText.Ptr()); + Py_DECREF(m_function); + printf("Python module function error \"%s\":\n \"%s\" not callable\n", GetName().Ptr(), m_scriptText.Ptr()); return false; } - Py_INCREF(m_function); - Py_INCREF(mod); + m_function_argc = 0; /* rare cases this could be a function that isnt defined in python, assume zero args */ + if (PyFunction_Check(m_function)) { + PyObject *py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(m_function), "co_argcount"); + if(py_arg_count) { + m_function_argc = PyLong_AsLong(py_arg_count); + Py_DECREF(py_arg_count); + } + else { + PyErr_Clear(); /* unlikely to fail but just incase */ + } + } + + if(m_function_argc > 1) { + Py_DECREF(m_function); + printf("Python module function has \"%s\":\n \"%s\" takes %d args, should be zero or 1 controller arg\n", GetName().Ptr(), m_scriptText.Ptr(), m_function_argc); + return false; + } return true; } @@ -412,7 +439,15 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) if (!m_function) return; - resultobj = PyObject_CallObject(m_function, NULL); + PyObject *args= NULL; + + if(m_function_argc==1) { + args = PyTuple_New(1); + PyTuple_SET_ITEM(args, 0, GetProxy()); + } + + resultobj = PyObject_CallObject(m_function, args); + Py_XDECREF(args); break; } @@ -428,7 +463,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) else { // something is wrong, tell the user what went wrong - printf("Python script error from controller \"%s\": \n", GetName().Ptr()); + printf("Python script error from controller \"%s\":\n", GetName().Ptr()); PyErr_Print(); /* Added in 2.48a, the last_traceback can reference Objects for example, increasing diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 12307632b06..587e6264d8c 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -44,9 +44,11 @@ class SCA_PythonController : public SCA_IController Py_Header; struct _object * m_bytecode; /* SCA_PYEXEC_SCRIPT only */ PyObject* m_function; /* SCA_PYEXEC_MODULE only */ + int m_function_argc; bool m_bModified; bool m_debug; /* use with SCA_PYEXEC_MODULE for reloading every logic run */ int m_mode; + protected: STR_String m_scriptText; From 490dad89d555458b0fa1f5309b2912115ab94be1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 May 2009 19:46:54 +0000 Subject: [PATCH 137/444] fix for a painting bug where disabled culling & occlusion would not paint onto backfaces also use the math floating point functions sqrt -> sqrtf, fmod -> fmodf etc. --- source/blender/src/imagepaint.c | 67 ++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index b0946e81dce..ad155dc27a1 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -672,8 +672,8 @@ static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y) { /* use */ - *x = (float)fmod(uv[0], 1.0f); - *y = (float)fmod(uv[1], 1.0f); + *x = (float)fmodf(uv[0], 1.0f); + *y = (float)fmodf(uv[1], 1.0f); if (*x < 0.0f) *x += 1.0f; if (*y < 0.0f) *y += 1.0f; @@ -895,7 +895,7 @@ static int line_isect_y(const float p1[2], const float p2[2], const float y_leve return ISECT_TRUE_P2; } - y_diff= fabs(p1[1]-p2[1]); /* yuck, horizontal line, we cant do much here */ + y_diff= fabsf(p1[1]-p2[1]); /* yuck, horizontal line, we cant do much here */ if (y_diff < 0.000001f) { *x_isect = (p1[0]+p2[0]) * 0.5f; @@ -928,7 +928,7 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve return ISECT_TRUE_P2; } - x_diff= fabs(p1[0]-p2[0]); /* yuck, horizontal line, we cant do much here */ + x_diff= fabsf(p1[0]-p2[0]); /* yuck, horizontal line, we cant do much here */ if (x_diff < 0.000001) { /* yuck, vertical line, we cant do much here */ *y_isect = (p1[0]+p2[0]) * 0.5f; @@ -955,11 +955,11 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve static int cmp_uv(const float vec2a[2], const float vec2b[2]) { /* if the UV's are not between 0.0 and 1.0 */ - float xa = (float)fmod(vec2a[0], 1.0f); - float ya = (float)fmod(vec2a[1], 1.0f); + float xa = (float)fmodf(vec2a[0], 1.0f); + float ya = (float)fmodf(vec2a[1], 1.0f); - float xb = (float)fmod(vec2b[0], 1.0f); - float yb = (float)fmod(vec2b[1], 1.0f); + float xb = (float)fmodf(vec2b[0], 1.0f); + float yb = (float)fmodf(vec2b[1], 1.0f); if (xa < 0.0f) xa += 1.0f; if (ya < 0.0f) ya += 1.0f; @@ -967,7 +967,7 @@ static int cmp_uv(const float vec2a[2], const float vec2b[2]) if (xb < 0.0f) xb += 1.0f; if (yb < 0.0f) yb += 1.0f; - return ((fabs(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabs(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0; + return ((fabsf(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0; } @@ -1106,7 +1106,7 @@ static float angleToLength(float angle) return 1.0f; } else { - return fabs(1.0f / cos(angle * (M_PI/180.0f))); + return fabsf(1.0f / cosf(angle * (M_PI/180.0f))); } } @@ -1587,7 +1587,7 @@ static int line_clip_rect2f( { /* first account for horizontal, then vertical lines */ /* horiz */ - if (fabs(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { + if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* is the line out of range on its Y axis? */ if (l1[1] < rect->ymin || l1[1] > rect->ymax) { return 0; @@ -1598,7 +1598,7 @@ static int line_clip_rect2f( } - if (fabs(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ + if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ if (BLI_in_rctf(rect, l1[0], l1[1])) { VECCOPY2D(l1_clip, l1); VECCOPY2D(l2_clip, l2); @@ -1615,7 +1615,7 @@ static int line_clip_rect2f( CLAMP(l2_clip[0], rect->xmin, rect->xmax); return 1; } - else if (fabs(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { + else if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* is the line out of range on its X axis? */ if (l1[0] < rect->xmin || l1[0] > rect->xmax) { return 0; @@ -1626,7 +1626,7 @@ static int line_clip_rect2f( return 0; } - if (fabs(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ + if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ if (BLI_in_rctf(rect, l1[0], l1[1])) { VECCOPY2D(l1_clip, l1); VECCOPY2D(l2_clip, l2); @@ -2111,7 +2111,7 @@ static void project_bucket_clip_face( for(i=0; i<(*tot); i++) { v2_clipSS[0] = isectVCosSS[i][0] - cent[0]; v2_clipSS[1] = isectVCosSS[i][1] - cent[1]; - isectVCosSS[i][2] = atan2(v1_clipSS[0]*v2_clipSS[1] - v1_clipSS[1]*v2_clipSS[0], v1_clipSS[0]*v2_clipSS[0]+v1_clipSS[1]*v2_clipSS[1]); + isectVCosSS[i][2] = atan2f(v1_clipSS[0]*v2_clipSS[1] - v1_clipSS[1]*v2_clipSS[0], v1_clipSS[0]*v2_clipSS[0]+v1_clipSS[1]*v2_clipSS[1]); } if (flip) qsort(isectVCosSS, *tot, sizeof(float)*3, float_z_sort_flip); @@ -2119,7 +2119,7 @@ static void project_bucket_clip_face( /* remove doubles */ /* first/last check */ - if (fabs(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE && fabs(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) { + if (fabsf(isectVCosSS[0][0]-isectVCosSS[(*tot)-1][0]) < PROJ_GEOM_TOLERANCE && fabsf(isectVCosSS[0][1]-isectVCosSS[(*tot)-1][1]) < PROJ_GEOM_TOLERANCE) { (*tot)--; } @@ -2134,8 +2134,8 @@ static void project_bucket_clip_face( while (doubles==TRUE) { doubles = FALSE; for(i=1; i<(*tot); i++) { - if (fabs(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE && - fabs(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE) + if (fabsf(isectVCosSS[i-1][0]-isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE && + fabsf(isectVCosSS[i-1][1]-isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE) { int j; for(j=i+1; j<(*tot); j++) { @@ -2263,6 +2263,19 @@ int IsectPoly2Df(const float pt[2], float uv[][2], const int tot) return 1; } +static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot) +{ + int i; + int side = (SIDE_OF_LINE(uv[tot-1], uv[0], pt) > 0.0f); + + for (i=1; i 0.0f) != side) + return 0; + + } + + return 1; +} /* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket. * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */ @@ -2306,6 +2319,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float uv_clip[8][2]; int uv_clip_tot; const short is_ortho = ps->is_ortho; + const short do_backfacecull = ps->do_backfacecull; vCo[0] = ps->dm_mvert[mf->v1].co; vCo[1] = ps->dm_mvert[mf->v2].co; @@ -2364,8 +2378,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i v1coSS = ps->screenCoords[ (*(&mf->v1 + i1)) ]; v2coSS = ps->screenCoords[ (*(&mf->v1 + i2)) ]; v3coSS = ps->screenCoords[ (*(&mf->v1 + i3)) ]; - - + /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/ project_bucket_clip_face( is_ortho, bucket_bounds, @@ -2373,8 +2386,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i uv1co, uv2co, uv3co, uv_clip, &uv_clip_tot ); - - + /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */ /* if (uv_clip_tot>6) { @@ -2396,7 +2408,10 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i //uv[0] = (((float)x) + 0.5f) / ibuf->x; uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */ - if (IsectPoly2Df(uv, uv_clip, uv_clip_tot)) { + /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work, + * could check the poly direction but better to do this */ + if( (do_backfacecull && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) || + (do_backfacecull==0 && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot))) { has_x_isect = has_isect = 1; @@ -3689,12 +3704,12 @@ static void *do_projectpaint_thread(void *ph_v) projPixel = (ProjPixel *)node->link; - /*dist = Vec2Lenf(projPixel->projCoSS, pos);*/ /* correct but uses a sqrt */ + /*dist = Vec2Lenf(projPixel->projCoSS, pos);*/ /* correct but uses a sqrtf */ dist_nosqrt = Vec2Lenf_nosqrt(projPixel->projCoSS, pos); - /*if (dist < s->brush->size) {*/ /* correct but uses a sqrt */ + /*if (dist < s->brush->size) {*/ /* correct but uses a sqrtf */ if (dist_nosqrt < brush_size_sqared) { - falloff = brush_sample_falloff_noalpha(ps->brush, sqrt(dist_nosqrt)); + falloff = brush_sample_falloff_noalpha(ps->brush, sqrtf(dist_nosqrt)); if (falloff > 0.0f) { if (ps->is_texbrush) { brush_sample_tex(ps->brush, projPixel->projCoSS, rgba); From 6b0f7c741ec11f5ac63cde6af85efac992787ab4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 May 2009 21:11:48 +0000 Subject: [PATCH 138/444] [#18191] VSE: when moving a project containing a relative path Audio RAM strip, it is still pointing old file Its a bit silly its not using the name from the file selector alredy (which has been made relative), but this fixes the bug. --- source/blender/src/editseq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index e2211e56fca..5dcfae30960 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -1183,6 +1183,10 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile, strncpy(str, sfile->dir, FILE_MAXDIR-1); strncat(str, sfile->file, FILE_MAXFILE-1); + if(sfile->flag & FILE_STRINGCODE) { + BLI_makestringcode(G.sce, str); + } + sound= sound_new_sound(str); if (!sound || sound->sample->type == SAMPLE_INVALID) { error("Unsupported audio format"); From b0ec497f39cb7aa7df1f7936418b443aeefbaade Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 May 2009 09:03:47 +0000 Subject: [PATCH 139/444] [#18492] Old 3dView painting does't work anymore. use flag the wrong way --- source/blender/src/drawview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index cd40b5e0ae2..203c9869022 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -978,7 +978,7 @@ void backdrawview3d(int test) #endif if( G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT ); - else if ((G.f & G_TEXTUREPAINT) && G.scene->toolsettings && (G.scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0); + else if ((G.f & G_TEXTUREPAINT) && G.scene->toolsettings && (G.scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)); else if(G.obedit && G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)); else { G.vd->flag &= ~V3D_NEEDBACKBUFDRAW; From 22b501c7917e8e209aab2dee02101286b7ecc45f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 May 2009 09:21:58 +0000 Subject: [PATCH 140/444] fixes for bugs submitted by BGE users, fixes by myself and Mitchell Stokes - when the attribute check function failed it didnt set an error raising a SystemError instead - Rasterizer.getMaterialMode would never return KX_BLENDER_MULTITEX_MATERIAL - PropertySensor value attribute checking function was always returning a fail. - Vertex Self Shadow python script didnt update for meshes with modifiers. --- release/scripts/vertexpaint_selfshadow_ao.py | 4 ++++ source/gameengine/Expressions/PyObjectPlus.cpp | 4 ++++ source/gameengine/GameLogic/SCA_PropertySensor.cpp | 3 +-- source/gameengine/Ketsji/KX_PythonInit.cpp | 2 +- source/gameengine/Ketsji/KX_SceneActuator.cpp | 4 ++-- source/gameengine/PyDoc/KX_SceneActuator.py | 6 ++++-- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/release/scripts/vertexpaint_selfshadow_ao.py b/release/scripts/vertexpaint_selfshadow_ao.py index 95ba7d2fb23..d641fd12111 100644 --- a/release/scripts/vertexpaint_selfshadow_ao.py +++ b/release/scripts/vertexpaint_selfshadow_ao.py @@ -180,6 +180,10 @@ def main(): t= sys.time() vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY) + + if ob.modifiers: + me.update() + print 'done in %.6f' % (sys.time()-t) if __name__=='__main__': main() diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index e6b49332273..107b12b7159 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -519,6 +519,10 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { if ((*attrdef->m_checkFunction)(self, attrdef) != 0) { + // if the checing function didnt set an error then set a generic one here so we dont set an error with no exception + if (PyErr_Occurred()==0) + PyErr_Format(PyExc_AttributeError, "type check error for attribute \"%s\", reasion unknown", attrdef->m_name); + // post check returned an error, restore values UNDO_AND_ERROR: if (undoBuffer) diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index c78283db423..e8a291b0a92 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -295,9 +295,8 @@ CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername) int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*) { - bool result = true; /* There is no type checking at this moment, unfortunately... */ - return result; + return 0; } /* ------------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index afc1fc5d1f8..18fd990dc51 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1004,7 +1004,7 @@ static PyObject* gPyGetMaterialType(PyObject*) { int flag; - if(G.fileflags & (G_FILE_GAME_MAT|G_FILE_GAME_MAT_GLSL)) + if(G.fileflags & G_FILE_GAME_MAT_GLSL) flag = KX_BLENDER_GLSL_MATERIAL; else if(G.fileflags & G_FILE_GAME_MAT) flag = KX_BLENDER_MULTITEX_MATERIAL; diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index eed1bb8027b..64edb6cd6d5 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -363,7 +363,7 @@ const char KX_SceneActuator::SetUseRestart_doc[] = "\tSet flag to 1 to restart the scene.\n" ; PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args) { - ShowDeprecationWarning("setUseRestart()", "(no replacement)"); + ShowDeprecationWarning("setUseRestart()", "the useRestart property"); int boolArg; if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg)) @@ -384,7 +384,7 @@ const char KX_SceneActuator::GetUseRestart_doc[] = "\tReturn whether the scene will be restarted.\n" ; PyObject* KX_SceneActuator::PyGetUseRestart() { - ShowDeprecationWarning("getUseRestart()", "(no replacement)"); + ShowDeprecationWarning("getUseRestart()", "the useRestart property"); return PyInt_FromLong(!(m_restart == 0)); } diff --git a/source/gameengine/PyDoc/KX_SceneActuator.py b/source/gameengine/PyDoc/KX_SceneActuator.py index 2429cd6fb80..8e806c2c50e 100644 --- a/source/gameengine/PyDoc/KX_SceneActuator.py +++ b/source/gameengine/PyDoc/KX_SceneActuator.py @@ -18,12 +18,14 @@ class KX_SceneActuator(SCA_IActuator): @ivar camera: the camera to change to. When setting the attribute, you can use either a L{KX_Camera} or the name of the camera. @type camera: L{KX_Camera} on read, string or L{KX_Camera} on write + @ivar useRestart: Set flag to True to restart the sene + @type useRestart: bool @type mode: The mode of the actuator @type mode: int from 0 to 5 L{GameLogic.Scene Actuator} """ def setUseRestart(flag): """ - DEPRECATED + DEPRECATED: use the useRestart property instead Set flag to True to restart the scene. @type flag: boolean @@ -46,7 +48,7 @@ class KX_SceneActuator(SCA_IActuator): """ def getUseRestart(): """ - DEPRECATED + DEPRECATED: use the useRestart property instead Returns True if the scene will be restarted. @rtype: boolean From 12a5c03d1602b478b9f1c23bbc80129a957b0bdb Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 3 May 2009 11:25:09 +0000 Subject: [PATCH 141/444] Bugfix #18671 Texture Nodes: the option to use nodes was also visible for textures on world, lamp, brush. Since it only works for Materials now, I've made the button disappear then. --- source/blender/src/buttons_shading.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index a129698cce3..1e4f6dab843 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -1705,7 +1705,8 @@ static void texture_panel_texture(MTex *actmtex, Material *ma, World *wrld, Lamp uiDefButS(block, MENU, B_TEXTYPE, textypes, 160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type"); } - uiDefButC(block, TOG, B_TEX_USENODES, "Nodes", 160, 100, 140, 25, &tex->use_nodes, 0.0f, 0.0f, 0, 0, ""); + if(ma) + uiDefButC(block, TOG, B_TEX_USENODES, "Nodes", 160, 100, 140, 25, &tex->use_nodes, 0.0f, 0.0f, 0, 0, ""); } else { From b89126dbe85501c54d9041ce5e4adb5c626d9c04 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 3 May 2009 12:06:43 +0000 Subject: [PATCH 142/444] Bugfix #18676 Map a texture to Material Ambient factor didn't work. Probably not since 2.42 or so... :) --- source/blender/render/intern/source/texture.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 61e9d9cf412..d41f68c021a 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -2031,6 +2031,10 @@ void do_material_tex(ShadeInput *shi) shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, varfac, mtex->blendtype, flip); if(shi->amb<0.0) shi->amb= 0.0; else if(shi->amb>1.0) shi->amb= 1.0; + + shi->ambr= shi->amb*R.wrld.ambr; + shi->ambg= shi->amb*R.wrld.ambg; + shi->ambb= shi->amb*R.wrld.ambb; } } } From c35299363fe411537f4e579e9c449233a4e6b412 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 3 May 2009 13:17:37 +0000 Subject: [PATCH 143/444] Fix for bug #18659: glsl math material node, "tangent" option didn't work. --- source/blender/nodes/intern/SHD_nodes/SHD_math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/intern/SHD_nodes/SHD_math.c index 050c2cdcc95..645f95686d7 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_math.c @@ -197,7 +197,7 @@ bNodeStack **out) static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { static char *names[] = {"math_add", "math_subtract", "math_multiply", - "math_divide", "math_sine", "math_cosine", "math_tangnet", "math_asin", + "math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin", "math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max", "math_round", "math_less_than", "math_greater_than"}; From 56b8ce2ec17ea555dc2042ab3d843384b9d1e7cd Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 3 May 2009 13:22:26 +0000 Subject: [PATCH 144/444] Bugfix 18671 revisted Node editor didn't support editing non-material texture node trees. Campbell pointed me to fact it's been used already, like for brush painting. However, this only worked via linking the texture to a material... hackish stuff. Now the Node Editor supports all other Textures too, with three extra icon buttons to define which. - Active Object: for textures linked to Materials or Lamps - World: textures from Scene world. - Brush: textures from active Brush The latter can only be set and used when in Paint or Sculpt mode: - Paint mode: in Image window, Paint Tool panel, set active brush - Sculpt mode: in EditButtons, Texture panel, select empty slot, add texture. Note that refreshes of previews in Node Editor is not always happening on switching contextes. Just click a socket to refresh view. --- source/blender/makesdna/DNA_space_types.h | 8 ++++- source/blender/src/buttons_shading.c | 3 +- source/blender/src/editnode.c | 41 +++++++++++++++++++---- source/blender/src/header_node.c | 21 +++++++++++- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 735e1c4f195..d14acc12693 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -356,7 +356,8 @@ typedef struct SpaceNode { float xof, yof; /* offset for drawing the backdrop */ struct bNodeTree *nodetree, *edittree; - int treetype, pad; /* treetype: as same nodetree->type */ + int treetype; /* treetype: as same nodetree->type */ + short texfrom, pad; /* texfrom object, world or brush */ struct bGPdata *gpd; /* grease-pencil data */ } SpaceNode; @@ -366,6 +367,11 @@ typedef struct SpaceNode { #define SNODE_BACKDRAW 2 #define SNODE_DISPGP 4 +/* snode->texfrom */ +#define SNODE_TEX_OBJECT 0 +#define SNODE_TEX_WORLD 1 +#define SNODE_TEX_BRUSH 2 + typedef struct SpaceImaSel { SpaceLink *next, *prev; int spacetype; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 1e4f6dab843..a129698cce3 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -1705,8 +1705,7 @@ static void texture_panel_texture(MTex *actmtex, Material *ma, World *wrld, Lamp uiDefButS(block, MENU, B_TEXTYPE, textypes, 160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type"); } - if(ma) - uiDefButC(block, TOG, B_TEX_USENODES, "Nodes", 160, 100, 140, 25, &tex->use_nodes, 0.0f, 0.0f, 0, 0, ""); + uiDefButC(block, TOG, B_TEX_USENODES, "Nodes", 160, 100, 140, 25, &tex->use_nodes, 0.0f, 0.0f, 0, 0, ""); } else { diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index f5de20891b4..f0046a960e9 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "DNA_action_types.h" +#include "DNA_brush_types.h" #include "DNA_color_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" @@ -583,14 +584,42 @@ void snode_set_context(SpaceNode *snode) snode->nodetree= G.scene->nodetree; } else if(snode->treetype==NTREE_TEXTURE) { - if(ob) { - Tex *tx= give_current_texture(ob, ob->actcol); - if(tx) { - snode->from= (ID*)ob; /* please check this; i have no idea what 'from' is. */ - snode->id= &tx->id; - snode->nodetree= tx->nodetree; + Tex *tx= NULL; + + if(snode->texfrom==SNODE_TEX_OBJECT) { + if(ob) { + tx= give_current_texture(ob, ob->actcol); + snode->from= (ID *)ob; } } + else if(snode->texfrom==SNODE_TEX_WORLD) { + tx= give_current_world_texture(); + snode->from= (ID *)G.scene->world; + } + else { + MTex *mtex= NULL; + + if(G.f & G_SCULPTMODE) { + SculptData *sd= &G.scene->sculptdata; + if(sd->texact != -1) + mtex= sd->mtex[sd->texact]; + } + else { + Brush *br= G.scene->toolsettings->imapaint.brush; + if(br) + mtex= br->mtex[br->texact]; + } + + if(mtex) { + snode->from= (ID *)G.scene; + tx= mtex->tex; + } + } + + if(tx) { + snode->id= &tx->id; + snode->nodetree= tx->nodetree; + } } /* find editable group */ diff --git a/source/blender/src/header_node.c b/source/blender/src/header_node.c index 2bd028766d1..c23913bb97c 100644 --- a/source/blender/src/header_node.c +++ b/source/blender/src/header_node.c @@ -756,8 +756,26 @@ void node_buttons(ScrArea *sa) uiDefIconButI(block, ROW, B_REDR, ICON_TEXTURE_DEHLT, xco,2,XIC,YIC-2, &(snode->treetype), 2, 2, 0, 0, "Texture Nodes"); xco+= 2*XIC; + uiBlockEndAlign(block); + if(snode->treetype==NTREE_TEXTURE) { + + uiBlockBeginAlign(block); + uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco,2,XIC,YIC-2, + &(snode->texfrom), 3, SNODE_TEX_OBJECT, 0, 0, "Texture Nodes from Object"); + xco+= XIC; + uiDefIconButS(block, ROW, B_REDR, ICON_WORLD_DEHLT, xco,2,XIC,YIC-2, + &(snode->texfrom), 3, SNODE_TEX_WORLD, 0, 0, "Texture Nodes from World"); + xco+= XIC; + uiDefIconButS(block, ROW, B_REDR, ICON_TPAINT_DEHLT, xco,2,XIC,YIC-2, + &(snode->texfrom), 3, SNODE_TEX_BRUSH, 0, 0, "Texture Nodes from Active Brush or Sculpt Data"); + xco+= 2*XIC; + + uiBlockEndAlign(block); + + } + /* find and set the context */ snode_set_context(snode); @@ -785,8 +803,9 @@ void node_buttons(ScrArea *sa) else if(snode->treetype==NTREE_TEXTURE) { if(snode->from) { + /* can't use unlink etc here, code requires buttons context */ xco= std_libbuttons(block, xco, 0, 0, NULL, B_TEXBROWSE, ID_TE, 1, snode->id, snode->from, &(snode->menunr), - B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); + 0, 0, 0, B_AUTOTEXNAME, B_KEEPDATA); if(snode->id) { Tex *tx= (Tex *)snode->id; From 03a0770df57835ca3551642fc6ba879bdde9564a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 3 May 2009 17:48:32 +0000 Subject: [PATCH 145/444] Bugfix #17929 Old bug (2.42): when using node material, transparent shadow did not work. It was missing to set the proper 'pass flag'. Do note an important difference with non-node materials for 'transparent shadow'. If there are no nodes, it uses the color from the unshaded material. When it has nodes, it uses the color output from the entire node tree, which is typically from shaded materials. The latter is because node shaders have no support for shade passes yet (it only outputs rgb + a). --- source/blender/render/intern/source/rayshade.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index c6dd8d6890e..97ac8666181 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -262,13 +262,14 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shade_input_set_shade_texco(shi); - if(is->mode==RE_RAY_SHADOW_TRA) + if(is->mode==RE_RAY_SHADOW_TRA) { if(shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ } else shade_color(shi, shr); + } else { if(shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); @@ -1292,15 +1293,8 @@ static void ray_trace_shadow_tra(Isect *is, int thread, int depth, int traflag) shi.depth= 1; /* only used to indicate tracing */ shi.mask= 1; shi.thread= thread; - - /*shi.osatex= 0; - shi.thread= shi.sample= 0; - shi.lay= 0; - shi.passflag= 0; - shi.combinedflag= 0; - shi.do_preview= 0; - shi.light_override= NULL; - shi.mat_override= NULL;*/ + shi.passflag= SCE_PASS_COMBINED; + shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ shade_ray(is, &shi, &shr); if (traflag & RAY_TRA) From 8a83aff9f56c5b8f8240847835578f1a23e2e9cf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 May 2009 17:52:03 +0000 Subject: [PATCH 146/444] [#18678] Swizzle properties for Mathutils.Vector patch from Alex Fraser (z0r) eg. - vec.xyz = vec.zyx - vec.xy = vec.zw - vec.xxy = vec.wzz - vec.yzyz = vec.yxyx See http://en.wikipedia.org/wiki/Swizzling_(computer_graphics) made some minor modifications to this patch. tested access times and adding 336 attributes to vectors doesn't make a noticeable differences to speed of existing axis attributes (x,y,z,w) - thanks to python dict lookups. --- source/blender/python/BPY_interface.c | 2 + source/blender/python/api2_2x/Mathutils.c | 15 +- source/blender/python/api2_2x/Mathutils.h | 2 + .../blender/python/api2_2x/doc/Mathutils.py | 17 +- source/blender/python/api2_2x/vector.c | 311 +++++++++++++++++- source/blender/python/api2_2x/vector.h | 4 + source/gameengine/Ketsji/KX_PythonInit.cpp | 3 + 7 files changed, 347 insertions(+), 7 deletions(-) diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index d86c317ee7e..1c98d6a5a59 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -286,6 +286,8 @@ void BPY_end_python( void ) free_libblock( &G.main->script, script ); } + Mathutils_Free(NULL); + Py_Finalize( ); BPyMenu_RemoveAllEntries( ); /* freeing bpymenu mem */ diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index 9c73ca16e70..83a58193a8b 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -107,6 +107,11 @@ struct PyMethodDef M_Mathutils_methods[] = { /*----------------------------MODULE INIT-------------------------*/ /* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */ +void Mathutils_Free(void * closure) +{ + Vector_Free(); +} + #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef M_Mathutils_module_def = { {}, /* m_base */ @@ -117,7 +122,7 @@ static struct PyModuleDef M_Mathutils_module_def = { 0, /* m_reload */ 0, /* m_traverse */ 0, /* m_clear */ - 0, /* m_free */ + Mathutils_Free, /* m_free */ }; #endif @@ -126,10 +131,13 @@ PyObject *Mathutils_Init(const char *from) PyObject *submodule; //seed the generator for the rand function - BLI_srand((unsigned int) (PIL_check_seconds_timer() * - 0x7FFFFFFF)); + BLI_srand((unsigned int) (PIL_check_seconds_timer() * 0x7FFFFFFF)); /* needed for getseters */ + if(!(vector_Type.tp_flags & Py_TPFLAGS_READY)) + if (Vector_Init() != 0) /* setup dynamic getset array */ + return NULL; + if( PyType_Ready( &vector_Type ) < 0 ) return NULL; if( PyType_Ready( &matrix_Type ) < 0 ) @@ -147,6 +155,7 @@ PyObject *Mathutils_Init(const char *from) return (submodule); } + //-----------------------------METHODS---------------------------- //----------------column_vector_multiplication (internal)--------- //COLUMN VECTOR Multiplication (Matrix X Vector) diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index 7406c5c4810..ec6c3f548d9 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -38,6 +38,8 @@ #include "euler.h" PyObject *Mathutils_Init( const char * from ); +void Mathutils_Free(void *); + PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); PyObject *quat_rotation(PyObject *arg1, PyObject *arg2); diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index 524d1fb6d4c..fc0c4ed10fa 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -400,6 +400,7 @@ class Vector: The Vector object ================= This object gives access to Vectors in Blender. + @group Axises: x, y, z, w @ivar x: The x value. @ivar y: The y value. @ivar z: The z value (if any). @@ -420,6 +421,16 @@ class Vector: - -vec @note: You can access a vector object like a sequence - x = vector[0] + - vec_a[:] vec_b + - vec2d[:] vec3d[:2] + @note: Vectors support 'swizzle' operations + - vec.xyz = vec.zyx + - vec.xy = vec.zw + - vec.xxy = vec.wzz + - vec.yzyz = vec.yxyx + + See U{http://en.wikipedia.org/wiki/Swizzling_(computer_graphics)} + @attention: Vector data can be wrapped or non-wrapped. When a object is wrapped it means that the object will give you direct access to the data inside of blender. Modification of this object will directly change the data inside of blender. To copy a wrapped object @@ -535,6 +546,7 @@ class Euler: The Euler object ================ This object gives access to Eulers in Blender. + @group Axises: x, y, z, w @ivar x: The heading value in degrees. @ivar y: The pitch value in degrees. @ivar z: The roll value in degrees. @@ -596,7 +608,7 @@ class Euler: """ Return a matrix representation of the euler. @rtype: Matrix object - @return: A roation matrix representation of the euler. + @return: A 3x3 roation matrix representation of the euler. """ def toQuat(): @@ -611,6 +623,7 @@ class Quaternion: The Quaternion object ===================== This object gives access to Quaternions in Blender. + @group Axises: x, y, z, w @ivar w: The w value. @ivar x: The x value. @ivar y: The y value. @@ -716,7 +729,7 @@ class Quaternion: """ Return a matrix representation of the quaternion. @rtype: Matrix object - @return: A rotation matrix representation of the quaternion. + @return: A 3x3 rotation matrix representation of the quaternion. """ class Matrix: diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index dd53cca9054..bef2917b0fa 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -20,7 +20,7 @@ * All rights reserved. * * - * Contributor(s): Willian P. Germano & Joseph Gilbert, Ken Hughes + * Contributor(s): Willian P. Germano, Joseph Gilbert, Ken Hughes, Alex Fraser, Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ @@ -31,6 +31,24 @@ #include "BKE_utildefines.h" #include "BLI_arithb.h" +#define MAX_DIMENSIONS 4 +/* Swizzle axes get packed into a single value that is used as a closure. Each + axis uses SWIZZLE_BITS_PER_AXIS bits. The first bit (SWIZZLE_VALID_AXIS) is + used as a sentinel: if it is unset, the axis is not valid. */ +#define SWIZZLE_BITS_PER_AXIS 3 +#define SWIZZLE_VALID_AXIS 0x4 +#define SWIZZLE_AXIS 0x3 + + +/* An array of getseters, some of which have members on the stack and some on + the heap. + + Vector_dyn_getseters: The getseter structures. Terminated with a NULL sentinel. + Vector_dyn_names: All the names of the getseters that were allocated on the heap. + Each name is terminated with a null character, but there is + currently no way to find the length of this array. */ +PyGetSetDef* Vector_dyn_getseters = NULL; +char* Vector_dyn_names = NULL; /*-------------------------DOC STRINGS ---------------------------*/ char Vector_Zero_doc[] = "() - set all values in the vector to 0"; @@ -42,6 +60,7 @@ char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; char Vector_reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; char Vector_copy_doc[] = "() - return a copy of the vector"; +char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order"; /*-----------------------METHOD DEFINITIONS ----------------------*/ struct PyMethodDef Vector_methods[] = { {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc}, @@ -1121,7 +1140,287 @@ static PyGetSetDef Vector_getseters[] = { {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; +/* 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. */ +static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) +{ + size_t axisA; + size_t axisB; + float vec[MAX_DIMENSIONS]; + unsigned int swizzleClosure; + + /* Unpack the axes from the closure into an array. */ + axisA = 0; + swizzleClosure = (unsigned int) closure; + while (swizzleClosure & SWIZZLE_VALID_AXIS) + { + axisB = swizzleClosure & SWIZZLE_AXIS; + vec[axisA] = self->vec[axisB]; + swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; + axisA++; + } + + return newVectorObject(vec, axisA, Py_NEW); +} +/* Set the items of this vector using a swizzle. + - If value is a vector or list this operates like an array copy, except that + the destination is effectively re-ordered as defined by the swizzle. At + most min(len(source), len(dest)) values will be copied. + - If the value is scalar, it is copied to all axes listed in the swizzle. + - If an axis appears more than once in the swizzle, the final occurrance is + the one that determines its value. + + Returns 0 on success and -1 on failure. On failure, the vector will be + unchanged. */ +static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closure) +{ + VectorObject *vecVal; + PyObject *item; + size_t listLen; + float scalarVal; + + size_t axisB; + size_t axisA; + unsigned int swizzleClosure; + + float vecTemp[MAX_DIMENSIONS]; + + /* Check that the closure can be used with this vector: even 2D vectors have + swizzles defined for axes z and w, but they would be invalid. */ + swizzleClosure = (unsigned int) closure; + while (swizzleClosure & SWIZZLE_VALID_AXIS) + { + axisA = swizzleClosure & SWIZZLE_AXIS; + if (axisA >= self->size) + { + PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n"); + return -1; + } + swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; + } + + if (VectorObject_Check(value)) + { + /* Copy vector contents onto swizzled axes. */ + vecVal = (VectorObject*) value; + axisB = 0; + swizzleClosure = (unsigned int) closure; + while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < vecVal->size) + { + axisA = swizzleClosure & SWIZZLE_AXIS; + vecTemp[axisA] = vecVal->vec[axisB]; + + swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; + axisB++; + } + memcpy(self->vec, vecTemp, axisB * sizeof(float)); + return 0; + } + else if (PyList_Check(value)) + { + /* Copy list contents onto swizzled axes. */ + listLen = PyList_Size(value); + swizzleClosure = (unsigned int) closure; + axisB = 0; + while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < listLen) + { + item = PyList_GetItem(value, axisB); + if (!PyNumber_Check(item)) + { + PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n"); + return -1; + } + scalarVal = (float)PyFloat_AsDouble(item); + + axisA = swizzleClosure & SWIZZLE_AXIS; + vecTemp[axisA] = scalarVal; + + swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; + axisB++; + } + memcpy(self->vec, vecTemp, axisB * sizeof(float)); + return 0; + } + else if (PyNumber_Check(value)) + { + /* Assign the same value to each axis. */ + scalarVal = (float)PyFloat_AsDouble(value); + swizzleClosure = (unsigned int) closure; + while (swizzleClosure & SWIZZLE_VALID_AXIS) + { + axisA = swizzleClosure & SWIZZLE_AXIS; + self->vec[axisA] = scalarVal; + + swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; + } + return 0; + } + else + { + PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." ); + return -1; + } +} + +/* Create a getseter that operates on the axes defined in swizzle. + Parameters: + gsd: An empty PyGetSetDef object. This will be modified. + swizzle: An array of axis indices. + dimensions: The number of axes to swizzle. Must be >= 2 and <= + MAX_DIMENSIONS. + name: A pointer to string that the name will be stored in. This is + purely to reduce the number of allocations. Before this function + returns, name will be advanced to the point immediately after + the name of the new getseter. Therefore, do not attempt to read + its contents. */ +static void Vector_createSwizzleGetSeter +( + PyGetSetDef *gsd, + unsigned short *swizzle, + size_t dimensions, + char **name +) +{ + const char axes[] = {'x', 'y', 'z', 'w'}; + unsigned int closure; + int i; + + /* Convert the index array into named axes. Store the name in the string + that was passed in, and make the getseter structure point to the same + address. */ + gsd->name = *name; + for (i = 0; i < dimensions; i++) + gsd->name[i] = axes[swizzle[i]]; + gsd->name[i] = '\0'; + /* Advance the name pointer to the next available address. */ + (*name) = (*name) + dimensions + 1; + + gsd->get = (getter)Vector_getSwizzle; + gsd->set = (setter)Vector_setSwizzle; + + gsd->doc = Vector_swizzle_doc; + + /* Pack the axes into a single value to use as the closure. Pack these in + in reverse so they come out in the right order when unpacked. */ + closure = 0; + for (i = MAX_DIMENSIONS - 1; i >= 0; i--) + { + closure = closure << SWIZZLE_BITS_PER_AXIS; + if (i < dimensions) + closure = closure | swizzle[i] | SWIZZLE_VALID_AXIS; + } + gsd->closure = (void*) closure; +} + +/* Create and append all implicit swizzle getseters to an existing array of + getseters. + Parameters: + Vector_getseters: + A null-terminated array of getseters that have been manually + defined. + resGds: The resultant array of getseters. This will be a combination of + static and manually-defined getseters. Use Vector_DelGetseters + to free this array. + + Returns: 0 on success, -1 on failure. On failure, resGsd will be left + untouched. */ +static int Vector_AppendSwizzleGetseters(void) +{ + int len; + int len_orig; + int len_names; + unsigned int i; + unsigned short swizzle[MAX_DIMENSIONS]; + char *name; + + /* Count the explicit getseters. */ + for (len_orig = 0; Vector_getseters[len_orig].name != NULL; len_orig++); + + /* Then there are 4^4 + 4^3 + 4^2 = 336 swizzles. */ + len = len_orig + 336 + 1; /* Plus one sentinel. */ + + /* That means 4^4 names of length 4 + 1, 4^3 names of length 3 + 1, and 4^2 + names of length 2 + 1 (including a null character at the end of each) + = (4^4) * 5 + (4^3) * 4 + (4^2) * 3 + = 1584 */ + len_names = 1584; + + if(Vector_dyn_getseters) { /* Should never happen */ + PyMem_Del(Vector_dyn_getseters); + Vector_dyn_getseters= NULL; + } + Vector_dyn_getseters = PyMem_New(PyGetSetDef, len * sizeof(PyGetSetDef)); + if (Vector_dyn_getseters == NULL) { + PyErr_SetString(PyExc_MemoryError, "Could not allocate memory for swizzle getseters."); + return -1; + } + memset(Vector_dyn_getseters, 0, len * sizeof(PyGetSetDef)); + + if(Vector_dyn_names) { /* Should never happen */ + PyMem_Del(Vector_dyn_names); + Vector_dyn_getseters= NULL; + } + Vector_dyn_names = PyMem_New(char, len_names * sizeof(char)); + if (Vector_dyn_names == NULL) { + PyErr_SetString(PyExc_MemoryError, "Could not allocate memory for swizzle getseter names."); + PyMem_Del(Vector_dyn_getseters); + return -1; + } + memset(Vector_dyn_names, 0, len_names * sizeof(char)); + + /* Do a shallow copy of the getseters. A deep clone can't be done because + we don't know how much memory each closure needs. */ + memcpy(Vector_dyn_getseters, Vector_getseters, len_orig * sizeof(PyGetSetDef)); + + /* Create the swizzle functions. The pointer for name will be advanced by + Vector_createSwizzleGetSeter. */ + name = Vector_dyn_names; + i = len_orig; + for (swizzle[0] = 0; swizzle[0] < MAX_DIMENSIONS; swizzle[0]++) + { + for (swizzle[1] = 0; swizzle[1] < MAX_DIMENSIONS; swizzle[1]++) + { + Vector_createSwizzleGetSeter(&Vector_dyn_getseters[i++], swizzle, 2, &name); + for (swizzle[2] = 0; swizzle[2] < MAX_DIMENSIONS; swizzle[2]++) + { + Vector_createSwizzleGetSeter(&Vector_dyn_getseters[i++], swizzle, 3, &name); + for (swizzle[3] = 0; swizzle[3] < MAX_DIMENSIONS; swizzle[3]++) + { + Vector_createSwizzleGetSeter(&Vector_dyn_getseters[i++], swizzle, 4, &name); + } + } + } + } + + /* No need to add a sentinel - memory was initialised to zero above. */ + vector_Type.tp_getset = Vector_dyn_getseters; + + return 0; +} + +/* Delete an array of getseters that was created by + Vector_AppendSwizzleGetseters. It is safe to call this even if the structure + members are NULL. */ +static void Vector_DelGetseters(void) +{ + /* Free strings that were allocated on the heap. */ + if (Vector_dyn_names != NULL) { + PyMem_Del(Vector_dyn_names); + Vector_dyn_names = NULL; + } + + /* Free the structure arrays themselves. */ + if (Vector_dyn_getseters != NULL) { + PyMem_Del(Vector_dyn_getseters); + Vector_dyn_getseters = NULL; + } + + /* for the blenderplayer that will initialize multiple times :| */ + vector_Type.tp_getset = Vector_getseters; + vector_Type.tp_flags = 0; /* maybe python does this when finalizing? - wont hurt anyway */ +} /* Note Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing @@ -1189,7 +1488,7 @@ PyTypeObject vector_Type = { /*** Attribute descriptor and subclassing stuff ***/ Vector_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ - Vector_getseters, /* struct PyGetSetDef *tp_getset; */ + Vector_getseters, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ NULL, /* PyObject *tp_dict; */ NULL, /* descrgetfunc tp_descr_get; */ @@ -1268,3 +1567,11 @@ PyObject *Vector_Negate(VectorObject * self) /*################################################################### ###########################DEPRECATED##############################*/ +int Vector_Init(void) +{ + return Vector_AppendSwizzleGetseters(); +} + +void Vector_Free() { + Vector_DelGetseters(); +} diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h index 9ec2eff8047..16a4a1f462a 100644 --- a/source/blender/python/api2_2x/vector.h +++ b/source/blender/python/api2_2x/vector.h @@ -43,6 +43,10 @@ typedef struct { short wrapped; /* is wrapped data? */ } VectorObject; +void Vector_Free(void); +int Vector_Init(void); + + /*prototypes*/ PyObject *Vector_Zero( VectorObject * self ); PyObject *Vector_Normalize( VectorObject * self ); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 18fd990dc51..e4252b55fb1 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1708,6 +1708,9 @@ void exitGamePlayerPythonScripting() /* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */ restorePySysPath(); /* get back the original sys.path and clear the backup */ + /* Modules that need freeing */ + Mathutils_Free(NULL); + Py_Finalize(); bpy_import_main_set(NULL); } From d85bbb8070f5d37c58694d8cb1378b4439b7eda8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 3 May 2009 19:47:13 +0000 Subject: [PATCH 147/444] on second thought its less trouble to make a python script that makes all the getset's in the array, apologies to Alex for suggesting this be dynamic :/ included python script to print out getsets as a comment --- source/blender/python/BPY_interface.c | 2 - source/blender/python/api2_2x/Mathutils.c | 12 +- source/blender/python/api2_2x/Mathutils.h | 1 - source/blender/python/api2_2x/vector.c | 614 ++++++++++++++------- source/blender/python/api2_2x/vector.h | 4 - source/gameengine/Ketsji/KX_PythonInit.cpp | 3 - 6 files changed, 410 insertions(+), 226 deletions(-) diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 1c98d6a5a59..1f35ebad9f7 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -285,8 +285,6 @@ void BPY_end_python( void ) next_script = script->id.next; free_libblock( &G.main->script, script ); } - - Mathutils_Free(NULL); Py_Finalize( ); diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index 83a58193a8b..8f99723e12d 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -107,11 +107,6 @@ struct PyMethodDef M_Mathutils_methods[] = { /*----------------------------MODULE INIT-------------------------*/ /* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */ -void Mathutils_Free(void * closure) -{ - Vector_Free(); -} - #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef M_Mathutils_module_def = { {}, /* m_base */ @@ -122,7 +117,7 @@ static struct PyModuleDef M_Mathutils_module_def = { 0, /* m_reload */ 0, /* m_traverse */ 0, /* m_clear */ - Mathutils_Free, /* m_free */ + 0, /* m_free */ }; #endif @@ -133,11 +128,6 @@ PyObject *Mathutils_Init(const char *from) //seed the generator for the rand function BLI_srand((unsigned int) (PIL_check_seconds_timer() * 0x7FFFFFFF)); - /* needed for getseters */ - if(!(vector_Type.tp_flags & Py_TPFLAGS_READY)) - if (Vector_Init() != 0) /* setup dynamic getset array */ - return NULL; - if( PyType_Ready( &vector_Type ) < 0 ) return NULL; if( PyType_Ready( &matrix_Type ) < 0 ) diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index ec6c3f548d9..b511f2046a6 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -38,7 +38,6 @@ #include "euler.h" PyObject *Mathutils_Init( const char * from ); -void Mathutils_Free(void *); PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index bef2917b0fa..f4504a13f72 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -39,17 +39,6 @@ #define SWIZZLE_VALID_AXIS 0x4 #define SWIZZLE_AXIS 0x3 - -/* An array of getseters, some of which have members on the stack and some on - the heap. - - Vector_dyn_getseters: The getseter structures. Terminated with a NULL sentinel. - Vector_dyn_names: All the names of the getseters that were allocated on the heap. - Each name is terminated with a null character, but there is - currently no way to find the length of this array. */ -PyGetSetDef* Vector_dyn_getseters = NULL; -char* Vector_dyn_names = NULL; - /*-------------------------DOC STRINGS ---------------------------*/ char Vector_Zero_doc[] = "() - set all values in the vector to 0"; char Vector_Normalize_doc[] = "() - normalize the vector"; @@ -1105,41 +1094,6 @@ static PyObject *Vector_getWrapped( VectorObject * self, void *type ) } -/*****************************************************************************/ -/* Python attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef Vector_getseters[] = { - {"x", - (getter)Vector_getAxis, (setter)Vector_setAxis, - "Vector X axis", - (void *)'X'}, - {"y", - (getter)Vector_getAxis, (setter)Vector_setAxis, - "Vector Y axis", - (void *)'Y'}, - {"z", - (getter)Vector_getAxis, (setter)Vector_setAxis, - "Vector Z axis", - (void *)'Z'}, - {"w", - (getter)Vector_getAxis, (setter)Vector_setAxis, - "Vector Z axis", - (void *)'W'}, - {"length", - (getter)Vector_getLength, (setter)Vector_setLength, - "Vector Length", - NULL}, - {"magnitude", - (getter)Vector_getLength, (setter)Vector_setLength, - "Vector Length", - NULL}, - {"wrapped", - (getter)Vector_getWrapped, (setter)NULL, - "True when this wraps blenders internal data", - NULL}, - {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ -}; - /* 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. */ @@ -1264,163 +1218,422 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur } } -/* Create a getseter that operates on the axes defined in swizzle. - Parameters: - gsd: An empty PyGetSetDef object. This will be modified. - swizzle: An array of axis indices. - dimensions: The number of axes to swizzle. Must be >= 2 and <= - MAX_DIMENSIONS. - name: A pointer to string that the name will be stored in. This is - purely to reduce the number of allocations. Before this function - returns, name will be advanced to the point immediately after - the name of the new getseter. Therefore, do not attempt to read - its contents. */ -static void Vector_createSwizzleGetSeter -( - PyGetSetDef *gsd, - unsigned short *swizzle, - size_t dimensions, - char **name -) -{ - const char axes[] = {'x', 'y', 'z', 'w'}; - unsigned int closure; - int i; +/*****************************************************************************/ +/* Python attributes get/set structure: */ +/*****************************************************************************/ +static PyGetSetDef Vector_getseters[] = { + {"x", + (getter)Vector_getAxis, (setter)Vector_setAxis, + "Vector X axis", + (void *)'X'}, + {"y", + (getter)Vector_getAxis, (setter)Vector_setAxis, + "Vector Y axis", + (void *)'Y'}, + {"z", + (getter)Vector_getAxis, (setter)Vector_setAxis, + "Vector Z axis", + (void *)'Z'}, + {"w", + (getter)Vector_getAxis, (setter)Vector_setAxis, + "Vector Z axis", + (void *)'W'}, + {"length", + (getter)Vector_getLength, (setter)Vector_setLength, + "Vector Length", + NULL}, + {"magnitude", + (getter)Vector_getLength, (setter)Vector_setLength, + "Vector Length", + NULL}, + {"wrapped", + (getter)Vector_getWrapped, (setter)NULL, + "True when this wraps blenders internal data", + NULL}, - /* Convert the index array into named axes. Store the name in the string - that was passed in, and make the getseter structure point to the same - address. */ - gsd->name = *name; - for (i = 0; i < dimensions; i++) - gsd->name[i] = axes[swizzle[i]]; - gsd->name[i] = '\0'; - /* Advance the name pointer to the next available address. */ - (*name) = (*name) + dimensions + 1; - - gsd->get = (getter)Vector_getSwizzle; - gsd->set = (setter)Vector_setSwizzle; - - gsd->doc = Vector_swizzle_doc; - - /* Pack the axes into a single value to use as the closure. Pack these in - in reverse so they come out in the right order when unpacked. */ - closure = 0; - for (i = MAX_DIMENSIONS - 1; i >= 0; i--) - { - closure = closure << SWIZZLE_BITS_PER_AXIS; - if (i < dimensions) - closure = closure | swizzle[i] | SWIZZLE_VALID_AXIS; - } - gsd->closure = (void*) closure; -} + /* autogenerated swizzle attrs, see python script below */ + {"xx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, Vector_swizzle_doc, (void *)((unsigned int)((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<= 2: - /* Count the explicit getseters. */ - for (len_orig = 0; Vector_getseters[len_orig].name != NULL; len_orig++); + for axis_0 in axises: + axis_0_pos = axis_pos[axis_0] + for axis_1 in axises: + axis_1_pos = axis_pos[axis_1] + axis_dict[axis_0+axis_1] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<2: + for axis_2 in axises: + axis_2_pos = axis_pos[axis_2] + axis_dict[axis_0+axis_1+axis_2] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)<3: + for axis_3 in axises: + axis_3_pos = axis_pos[axis_3] + axis_dict[axis_0+axis_1+axis_2+axis_3] = '((%s|SWIZZLE_VALID_AXIS) | ((%s|SWIZZLE_VALID_AXIS)< Date: Sun, 3 May 2009 20:47:29 +0000 Subject: [PATCH 148/444] fix for a problem with setUV2 reported by cthames on blenderartist http://blenderartists.org/forum/showpost.php?p=1369757&postcount=35 there was an undocumented second arg but may as well allow a single vector arg like setUV() --- source/gameengine/Ketsji/KX_VertexProxy.cpp | 5 +++-- source/gameengine/PyDoc/KX_VertexProxy.py | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 93ff35b5a9d..6563d0446eb 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -435,9 +435,10 @@ PyObject* KX_VertexProxy::PyGetUV2() PyObject* KX_VertexProxy::PySetUV2(PyObject* args) { MT_Point2 vec; - unsigned int unit=0; + unsigned int unit= RAS_TexVert::SECOND_UV; + PyObject* list= NULL; - if(!PyArg_ParseTuple(args, "Oi:setUV2", &list, &unit)) + if(!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit)) return NULL; if (!PyVecTo(list, vec)) diff --git a/source/gameengine/PyDoc/KX_VertexProxy.py b/source/gameengine/PyDoc/KX_VertexProxy.py index 114e0d88075..75bd4d788a6 100644 --- a/source/gameengine/PyDoc/KX_VertexProxy.py +++ b/source/gameengine/PyDoc/KX_VertexProxy.py @@ -86,11 +86,13 @@ class KX_VertexProxy(SCA_IObject): @rtype: list [u, v] @return: this vertexes UV (texture) coordinates. """ - def setUV2(uv): + def setUV2(uv, unit): """ Sets the 2nd UV (texture) coordinates of this vertex. @type uv: list [u, v] + @param unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV + @param unit: int """ def getRGBA(): """ From 20888482aed16df7da3e2b3736306799e5601036 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 3 May 2009 21:42:39 +0000 Subject: [PATCH 149/444] BGE: fix a crash with previous scene destruction speed up commit when sensors and controllers are cross connected between objects. --- source/gameengine/GameLogic/SCA_LogicManager.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index 0b549ded474..c43875a0047 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -193,10 +193,20 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) void SCA_LogicManager::RemoveController(SCA_IController* controller) { + sensormap_t::iterator sit; + sit = m_sensorcontrollermapje.begin(); + if (sit==m_sensorcontrollermapje.end()) + { + //TRICK: either there is no sensor at all, or the scene is being deleted + //(see KX_Scene::~KX_Scene()). In the first case, this is harmless. + //In the second case, we cannot rely on the sensor being still available, + //make the controller inactive to avoid link count. + //Need a better solution, maybe something similar to m_removedActuators. + controller->SetActive(false); + } controller->UnlinkAllSensors(); controller->UnlinkAllActuators(); - sensormap_t::iterator sit; - for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) + for (;!(sit==m_sensorcontrollermapje.end());++sit) { (*sit).second.remove(controller); } From 2aa3c932d00977a70bc299bd709fa505c48518d8 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 3 May 2009 21:51:57 +0000 Subject: [PATCH 150/444] BGE performance: use inline function as much as possible in scenegraph and logic to avoid function call. --- source/gameengine/Expressions/Value.cpp | 38 --------------- source/gameengine/Expressions/Value.h | 47 +++++++++++++++++-- source/gameengine/GameLogic/SCA_IActuator.cpp | 7 --- source/gameengine/GameLogic/SCA_IActuator.h | 6 ++- .../gameengine/GameLogic/SCA_ILogicBrick.cpp | 31 ------------ source/gameengine/GameLogic/SCA_ILogicBrick.h | 15 ++++-- source/gameengine/GameLogic/SCA_IObject.cpp | 45 ------------------ source/gameengine/GameLogic/SCA_IObject.h | 27 ++++++++--- source/gameengine/Ketsji/KX_GameObject.h | 5 -- 9 files changed, 81 insertions(+), 140 deletions(-) diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index c50a941f3a9..a811b39d790 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -453,50 +453,12 @@ double* CValue::GetVector3(bool bGetTransformedVec) /*--------------------------------------------------------------------------------------------------------------------- Reference Counting ---------------------------------------------------------------------------------------------------------------------*/ -// -// Add a reference to this value -// -CValue *CValue::AddRef() -{ - // Increase global reference count, used to see at the end of the program - // if all CValue-derived classes have been dereferenced to 0 - //debug(gRefCountValue++); -#ifdef _DEBUG - //gRefCountValue++; -#endif - m_refcount++; - return this; -} // // Release a reference to this value (when reference count reaches 0, the value is removed from the heap) // -int CValue::Release() -{ - // Decrease global reference count, used to see at the end of the program - // if all CValue-derived classes have been dereferenced to 0 - //debug(gRefCountValue--); -#ifdef _DEBUG - //gRefCountValue--; -#endif - // Decrease local reference count, if it reaches 0 the object should be freed - if (--m_refcount > 0) - { - // Reference count normal, return new reference count - return m_refcount; - } - else - { - // Reference count reached 0, delete ourselves and return 0 -// MT_assert(m_refcount==0, "Reference count reached sub-zero, object released too much"); - - delete this; - return 0; - } - -} diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index fca603a831e..c5c8229ebcf 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -259,10 +259,49 @@ public: }; /// Reference Counting - int GetRefCount() { return m_refcount; } - virtual CValue* AddRef(); // Add a reference to this value - virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap) - + int GetRefCount() + { + return m_refcount; + } + + // Add a reference to this value + CValue* AddRef() + { + // Increase global reference count, used to see at the end of the program + // if all CValue-derived classes have been dereferenced to 0 + //debug(gRefCountValue++); + #ifdef _DEBUG + //gRefCountValue++; + #endif + m_refcount++; + return this; + } + + // Release a reference to this value (when reference count reaches 0, the value is removed from the heap) + int Release() + { + // Decrease global reference count, used to see at the end of the program + // if all CValue-derived classes have been dereferenced to 0 + //debug(gRefCountValue--); + #ifdef _DEBUG + //gRefCountValue--; + #endif + // Decrease local reference count, if it reaches 0 the object should be freed + if (--m_refcount > 0) + { + // Reference count normal, return new reference count + return m_refcount; + } + else + { + // Reference count reached 0, delete ourselves and return 0 + // MT_assert(m_refcount==0, "Reference count reached sub-zero, object released too much"); + + delete this; + return 0; + } + } + /// Property Management virtual void SetProperty(const STR_String& name,CValue* ioProperty); // Set property , overwrites and releases a previous property with the same name if needed diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index 3d4ad3aec3a..214c7dded76 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -44,13 +44,6 @@ SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, -void SCA_IActuator::AddEvent(CValue* event) -{ - m_events.push_back(event); -} - - - void SCA_IActuator::RemoveAllEvents() { // remove event queue! for (vector::iterator i=m_events.begin(); !(i==m_events.end());i++) diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 51bd6454d92..e5f0a2cf4cc 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -75,7 +75,11 @@ public: /** * Add an event to an actuator. */ - void AddEvent(CValue* event); + void AddEvent(CValue* event) + { + m_events.push_back(event); + } + virtual void ProcessReplica(); /** diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index c138ae46283..6de9986b03a 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -71,13 +71,6 @@ void SCA_ILogicBrick::SetUeberExecutePriority(int execute_Priority) -SCA_IObject* SCA_ILogicBrick::GetParent() -{ - return m_gameobj; -} - - - void SCA_ILogicBrick::ReParent(SCA_IObject* parent) { m_gameobj = parent; @@ -142,14 +135,6 @@ void SCA_ILogicBrick::SetName(STR_String name) m_name = name; } - -bool SCA_ILogicBrick::IsActive() -{ - return m_bActive; -} - - - bool SCA_ILogicBrick::LessComparedTo(SCA_ILogicBrick* other) { return (this->m_Execute_Ueber_Priority < other->m_Execute_Ueber_Priority) @@ -157,22 +142,6 @@ bool SCA_ILogicBrick::LessComparedTo(SCA_ILogicBrick* other) (this->m_Execute_Priority < other->m_Execute_Priority)); } - - -void SCA_ILogicBrick::SetActive(bool active) -{ - m_bActive=active; - if (active) - { - //m_gameobj->SetDebugColor(GetDrawColor()); - } else - { - //m_gameobj->ResetDebugColor(); - } -} - - - void SCA_ILogicBrick::RegisterEvent(CValue* eventval) { if (m_eventval) diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index b8c6772fe8d..b1384e88826 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -59,7 +59,8 @@ public: void SetExecutePriority(int execute_Priority); void SetUeberExecutePriority(int execute_Priority); - SCA_IObject* GetParent(); + SCA_IObject* GetParent() { return m_gameobj; } + virtual void ReParent(SCA_IObject* parent); virtual void Relink(GEN_Map *obj_map); virtual void Delete() { Release(); } @@ -73,8 +74,16 @@ public: virtual STR_String GetName(); virtual void SetName(STR_String name); - bool IsActive(); - void SetActive(bool active) ; + bool IsActive() + { + return m_bActive; + } + + void SetActive(bool active) + { + m_bActive=active; + } + virtual bool LessComparedTo(SCA_ILogicBrick* other); diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index b3c4708978d..7eaa5c607be 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -79,29 +79,6 @@ SCA_IObject::~SCA_IObject() //} } - - -SCA_ControllerList& SCA_IObject::GetControllers() -{ - return m_controllers; -} - - - -SCA_SensorList& SCA_IObject::GetSensors() -{ - return m_sensors; -} - - - -SCA_ActuatorList& SCA_IObject::GetActuators() -{ - return m_actuators; -} - - - void SCA_IObject::AddSensor(SCA_ISensor* act) { act->AddRef(); @@ -143,20 +120,6 @@ void SCA_IObject::UnregisterActuator(SCA_IActuator* act) } } -void SCA_IObject::SetIgnoreActivityCulling(bool b) -{ - m_ignore_activity_culling = b; -} - - - -bool SCA_IObject::GetIgnoreActivityCulling() -{ - return m_ignore_activity_culling; -} - - - void SCA_IObject::ReParentLogic() { SCA_ActuatorList& oldactuators = GetActuators(); @@ -256,14 +219,6 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname) -void SCA_IObject::SetCurrentTime(float currentTime) { - //T_InterpolatorList::iterator i; - //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { - // (*i)->Execute(currentTime); - //} -} - - #if 0 const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist) { diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 7f63c9f5efd..10cf551aeb6 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -83,9 +83,18 @@ public: SCA_IObject(PyTypeObject* T=&Type); virtual ~SCA_IObject(); - SCA_ControllerList& GetControllers(); - SCA_SensorList& GetSensors(); - SCA_ActuatorList& GetActuators(); + SCA_ControllerList& GetControllers() + { + return m_controllers; + } + SCA_SensorList& GetSensors() + { + return m_sensors; + } + SCA_ActuatorList& GetActuators() + { + return m_actuators; + } void AddSensor(SCA_ISensor* act); void AddController(SCA_IController* act); @@ -97,20 +106,26 @@ public: SCA_IActuator* FindActuator(const STR_String& actuatorname); SCA_IController* FindController(const STR_String& controllername); - void SetCurrentTime(float currentTime); + void SetCurrentTime(float currentTime) {} void ReParentLogic(); /** * Set whether or not to ignore activity culling requests */ - void SetIgnoreActivityCulling(bool b); + void SetIgnoreActivityCulling(bool b) + { + m_ignore_activity_culling = b; + } /** * Set whether or not this object wants to ignore activity culling * requests */ - bool GetIgnoreActivityCulling(); + bool GetIgnoreActivityCulling() + { + return m_ignore_activity_culling; + } /** * Suspend all progress. diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 14ed713ecfa..bbb1b8bb360 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -192,11 +192,6 @@ public: ~KX_GameObject( ); - CValue* - AddRef() { - /* temporarily to find memleaks */ return CValue::AddRef(); - } - /** * @section Stuff which is here due to poor design. * Inherited from CValue and needs an implementation. From 3abb8e8e68c824db7cecdf2360e8e1daaff00413 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 3 May 2009 22:29:00 +0000 Subject: [PATCH 151/444] BGE performance: second round of scenegraph improvement. Use dynamic linked list to handle scenegraph rather than dumb scan of the whole tree. The performance improvement depends on the fraction of moving objects. If most objects are static, the speed up is considerable. The following table compares the time spent on scenegraph before and after this commit on a scene with 10000 objects in various configuratons: Scenegraph time (ms) Before After (includes culling) All objects static, 8.8 1.7 all visible but small fraction in the view frustrum All objects static, 7,5 0.01 all invisible. All objects moving, 14.1 8.4 all visible but small fraction in the view frustrum This tables shows that static and invisible objects take no CPU at all for scenegraph and culling. In the general case, this commit will speed up the scenegraph between 2x and 5x. Compared to 2.48a, it should be between 4x and 10x faster. Further speed up is possible by making the scenegraph cache-friendly. Next round of performance improvement will be on the rasterizer: use the same dynamic linked list technique for the mesh slots. --- .../scenegraph/SG_SceneGraph.vcproj | 9 + .../Converter/BL_BlenderDataConversion.cpp | 4 +- .../KX_SG_BoneParentNodeRelationship.cpp | 4 +- .../Ketsji/KX_SG_NodeRelationships.cpp | 10 +- source/gameengine/Ketsji/KX_Scene.cpp | 40 ++++- source/gameengine/Ketsji/KX_Scene.h | 7 + source/gameengine/SceneGraph/SG_DList.h | 147 ++++++++++++++++ source/gameengine/SceneGraph/SG_IObject.cpp | 92 +--------- source/gameengine/SceneGraph/SG_IObject.h | 129 +++++++++++--- source/gameengine/SceneGraph/SG_Node.cpp | 63 +------ source/gameengine/SceneGraph/SG_Node.h | 113 +++++++++---- source/gameengine/SceneGraph/SG_QList.h | 144 ++++++++++++++++ source/gameengine/SceneGraph/SG_Spatial.cpp | 147 +--------------- source/gameengine/SceneGraph/SG_Spatial.h | 160 +++++++++++------- 14 files changed, 649 insertions(+), 420 deletions(-) create mode 100644 source/gameengine/SceneGraph/SG_DList.h create mode 100644 source/gameengine/SceneGraph/SG_QList.h diff --git a/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj b/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj index 9c63f625820..95e61cc4af8 100644 --- a/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj +++ b/projectfiles_vc9/gameengine/scenegraph/SG_SceneGraph.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="SG_SceneGraph" ProjectGUID="{09222F5E-1625-4FF3-A89A-384D16875EE5}" + RootNamespace="SG_SceneGraph" TargetFrameworkVersion="131072" > @@ -509,6 +510,10 @@ RelativePath="..\..\..\source\gameengine\SceneGraph\SG_Controller.h" > + + @@ -521,6 +526,10 @@ RelativePath="..\..\..\source\gameengine\SceneGraph\SG_ParentRelation.h" > + + diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 6a570c9e815..c4c71d9dd85 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2055,7 +2055,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) { // blender has an additional 'parentinverse' offset in each object - SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks()); + SG_Node* parentinversenode = new SG_Node(NULL,kxscene,SG_Callbacks(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc)); // define a normal parent relationship for this node. KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); @@ -2249,7 +2249,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) { // blender has an additional 'parentinverse' offset in each object - SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks()); + SG_Node* parentinversenode = new SG_Node(NULL,kxscene,SG_Callbacks(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc)); // define a normal parent relationship for this node. KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp index 0e7571031e8..cb933419c57 100644 --- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp +++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp @@ -125,7 +125,9 @@ UpdateChildCoordinates( else { child->SetWorldFromLocalTransform(); } - child->SetModified(false); + child->ClearModified(); + // this node must always be updated, so reschedule it for next time + child->ActivateRecheduleUpdateCallback(); return valid_parent_transform; } diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp index c3b0c21c8e0..c49b6d671a7 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp @@ -63,7 +63,7 @@ UpdateChildCoordinates( if (parent==NULL) { /* Simple case */ child->SetWorldFromLocalTransform(); - child->SetModified(false); + child->ClearModified(); return true; //false; } else { @@ -75,7 +75,7 @@ UpdateChildCoordinates( child->SetWorldScale(p_world_scale * child->GetLocalScale()); child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation()); child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition())); - child->SetModified(false); + child->ClearModified(); return true; } } @@ -137,7 +137,7 @@ UpdateChildCoordinates( child->SetWorldPosition(child->GetLocalPosition()); child->SetWorldOrientation(child->GetLocalOrientation()); - child->SetModified(false); + child->ClearModified(); return true; //parent != NULL; } @@ -259,7 +259,9 @@ UpdateChildCoordinates( child->SetWorldScale(child_w_scale); child->SetWorldPosition(child_w_pos); child->SetWorldOrientation(child_w_rotation); - child->SetModified(false); + child->ClearModified(); + // this node must always be updated, so reschedule it for next time + child->ActivateRecheduleUpdateCallback(); return true; //parent != NULL; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 171ed5d130f..d31d451f02e 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -111,7 +111,22 @@ void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene) return NULL; }; -SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc,KX_GameObject::UpdateTransformFunc); +bool KX_Scene::KX_ScenegraphUpdateFunc(SG_IObject* node,void* gameobj,void* scene) +{ + return ((SG_Node*)node)->Schedule(((KX_Scene*)scene)->m_sghead); +} + +bool KX_Scene::KX_ScenegraphRescheduleFunc(SG_IObject* node,void* gameobj,void* scene) +{ + return ((SG_Node*)node)->Reschedule(((KX_Scene*)scene)->m_sghead); +} + +SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks( + KX_SceneReplicationFunc, + KX_SceneDestructionFunc, + KX_GameObject::UpdateTransformFunc, + KX_Scene::KX_ScenegraphUpdateFunc, + KX_Scene::KX_ScenegraphRescheduleFunc); // temporarily var until there is a button in the userinterface // (defined in KX_PythonInit.cpp) @@ -1473,17 +1488,30 @@ void KX_Scene::LogicEndFrame() */ void KX_Scene::UpdateParents(double curtime) { -// int numrootobjects = GetRootParentList()->GetCount(); + // we use the SG dynamic list + SG_Node* node; - for (int i=0; iGetCount(); i++) + while ((node = SG_Node::GetNextScheduled(m_sghead)) != NULL) { - KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i); - parentobj->NodeUpdateGS(curtime); + node->UpdateWorldData(curtime); + } + + //for (int i=0; iGetCount(); i++) + //{ + // KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i); + // parentobj->NodeUpdateGS(curtime); + //} + + // the list must be empty here + assert(m_sghead.Empty()); + // some nodes may be ready for reschedule, move them to schedule list for next time + while ((node = SG_Node::GetNextRescheduled(m_sghead)) != NULL) + { + node->Schedule(m_sghead); } } - RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool &bucketCreated) { return m_bucketmanager->FindBucket(polymat, bucketCreated); diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 52a3cd5733e..0cfef8b7bd1 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -118,6 +118,11 @@ protected: CListValue* m_parentlist; // all 'root' parents CListValue* m_lightlist; CListValue* m_inactivelist; // all objects that are not in the active layer + + SG_QList m_sghead; // list of nodes that needs scenegraph update + // the Dlist is not object that must be updated + // the Qlist is for objects that needs to be rescheduled + // for updates after udpate is over (slow parent, bone parent) /** * The tree of objects in the scene. @@ -307,6 +312,8 @@ public: /** * Update all transforms according to the scenegraph. */ + static bool KX_ScenegraphUpdateFunc(SG_IObject* node,void* gameobj,void* scene); + static bool KX_ScenegraphRescheduleFunc(SG_IObject* node,void* gameobj,void* scene); void UpdateParents(double curtime); void DupliGroupRecurse(CValue* gameobj, int level); bool IsObjectInGroup(CValue* gameobj) diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h new file mode 100644 index 00000000000..d682be679e6 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -0,0 +1,147 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __SG_DLIST +#define __SG_DLIST + +#include + +/** + * Double circular linked list + */ +class SG_DList +{ +protected : + SG_DList* m_flink; + SG_DList* m_blink; + +public: + template class iterator + { + private: + SG_DList& m_head; + T* m_current; + public: + typedef iterator _myT; + iterator(SG_DList& head) : m_head(head), m_current(NULL) {} + ~iterator() {} + + void begin() + { + m_current = (T*)m_head.Peek(); + if (m_current == (T*)m_head.Self()) + { + m_current = NULL; + } + } + bool end() + { + return (NULL == m_current); + } + T* operator*() + { + return m_current; + } + _myT& operator++() + { + assert(m_current); + m_current = (T*)m_current->Peek(); + if (m_current == (T*)m_head.Self()) + { + m_current = NULL; + } + return *this; + } + }; + + SG_DList() + { + m_flink = m_blink = this; + } + virtual ~SG_DList() + { + Delink(); + } + + inline bool Empty() // Check for empty queue + { + return ( m_flink == this ); + } + bool AddBack( SG_DList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_blink = m_blink; + item->m_flink = this; + m_blink->m_flink = item; + m_blink = item; + return true; + } + bool AddFront( SG_DList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_flink = m_flink; + item->m_blink = this; + m_flink->m_blink = item; + m_flink = item; + return true; + } + SG_DList *Remove() // Remove from the front + { + if (Empty()) + { + return NULL; + } + SG_DList* item = m_flink; + m_flink = item->m_flink; + m_flink->m_blink = this; + item->m_flink = item->m_blink = item; + return item; + } + void Delink() // Remove from the middle + { + if (!Empty()) + { + m_blink->m_flink = m_flink; + m_flink->m_blink = m_blink; + m_flink = m_blink = this; + } + } + inline SG_DList *Peek() // Look at front without removing + { + return m_flink; + } + inline SG_DList *Self() + { + return this; + } +}; + +#endif //__SG_DLIST + diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp index fbab4032a10..5795ca57113 100644 --- a/source/gameengine/SceneGraph/SG_IObject.cpp +++ b/source/gameengine/SceneGraph/SG_IObject.cpp @@ -39,19 +39,20 @@ SG_IObject:: SG_IObject( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ): + SG_QList(), m_SGclientObject(clientobj), - m_SGclientInfo(clientinfo), - m_callbacks(callbacks) + m_SGclientInfo(clientinfo) { - //nothing to do + m_callbacks = callbacks; } SG_IObject:: SG_IObject( const SG_IObject &other ) : + SG_QList(), m_SGclientObject(other.m_SGclientObject), m_SGclientInfo(other.m_SGclientInfo), m_callbacks(other.m_callbacks) @@ -74,92 +75,17 @@ RemoveAllControllers( m_SGcontrollers.clear(); } -/// Needed for replication - SGControllerList& -SG_IObject:: -GetSGControllerList( -){ - return m_SGcontrollers; -} - - void* -SG_IObject:: -GetSGClientObject( -){ - return m_SGclientObject; -} - -const - void* -SG_IObject:: -GetSGClientObject( -) const { - return m_SGclientObject; -} - - void -SG_IObject:: -SetSGClientObject( - void* clientObject -){ - m_SGclientObject = clientObject; -} - - - bool -SG_IObject:: -ActivateReplicationCallback( - SG_IObject *replica -){ - if (m_callbacks.m_replicafunc) - { - // Call client provided replication func - if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL) - return false; - } - return true; -}; - - void -SG_IObject:: -ActivateDestructionCallback( -){ - if (m_callbacks.m_destructionfunc) - { - // Call client provided destruction function on this! - m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo); - } - else - { - // no callback but must still destroy the node to avoid memory leak - delete this; - } -} - - void -SG_IObject:: -ActivateUpdateTransformCallback( -){ - if (m_callbacks.m_updatefunc) - { - // Call client provided update func. - m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo); - } -} - - void -SG_IObject:: -SetControllerTime( - double time -){ +void SG_IObject::SetControllerTime(double time) +{ SGControllerList::iterator contit; - for (contit = m_SGcontrollers.begin();contit!=m_SGcontrollers.end();++contit) { (*contit)->SetSimulatedTime(time); } } +/// Needed for replication + SG_IObject:: ~SG_IObject() diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index 9012b532059..b4dd9a9ddf2 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -29,6 +29,7 @@ #ifndef __SG_IOBJECT #define __SG_IOBJECT +#include "SG_QList.h" #include // used for debugging: stage of the game engine main loop at which a Scenegraph modification is done @@ -84,6 +85,18 @@ typedef void (*SG_UpdateTransformCallback)( void* clientinfo ); +typedef bool (*SG_ScheduleUpdateCallback)( + SG_IObject* sgobject, + void* clientobj, + void* clientinfo +); + +typedef bool (*SG_RescheduleUpdateCallback)( + SG_IObject* sgobject, + void* clientobj, + void* clientinfo +); + /** * SG_Callbacks hold 2 call backs to the outside world. @@ -106,30 +119,38 @@ struct SG_Callbacks ): m_replicafunc(NULL), m_destructionfunc(NULL), - m_updatefunc(NULL) + m_updatefunc(NULL), + m_schedulefunc(NULL), + m_reschedulefunc(NULL) { }; SG_Callbacks( SG_ReplicationNewCallback repfunc, SG_DestructionNewCallback destructfunc, - SG_UpdateTransformCallback updatefunc + SG_UpdateTransformCallback updatefunc, + SG_ScheduleUpdateCallback schedulefunc, + SG_RescheduleUpdateCallback reschedulefunc ): m_replicafunc(repfunc), m_destructionfunc(destructfunc), - m_updatefunc(updatefunc) + m_updatefunc(updatefunc), + m_schedulefunc(schedulefunc), + m_reschedulefunc(reschedulefunc) { }; SG_ReplicationNewCallback m_replicafunc; SG_DestructionNewCallback m_destructionfunc; SG_UpdateTransformCallback m_updatefunc; + SG_ScheduleUpdateCallback m_schedulefunc; + SG_RescheduleUpdateCallback m_reschedulefunc; }; /** base object that can be part of the scenegraph. */ -class SG_IObject +class SG_IObject : public SG_QList { private : @@ -177,9 +198,10 @@ public: * using STL? */ - SGControllerList& - GetSGControllerList( - ); + SGControllerList& GetSGControllerList() + { + return m_SGcontrollers; + } /** @@ -192,16 +214,16 @@ public: * This may be NULL. */ - void* - GetSGClientObject( - ); + inline const void* GetSGClientObject() const + { + return m_SGclientObject; + } - const - void* - GetSGClientObject( - ) const ; + inline void* GetSGClientObject() + { + return m_SGclientObject; + } - /** * Set the client object for this node. This is just a * pointer to an object allocated that should exist for @@ -209,10 +231,10 @@ public: * this function is called again. */ - void - SetSGClientObject( - void* clientObject - ); + void SetSGClientObject(void* clientObject) + { + m_SGclientObject = clientObject; + } /** * Set the current simulation time for this node. @@ -220,10 +242,7 @@ public: * the nodes list of controllers and calls their SetSimulatedTime methods */ - void - SetControllerTime( - double time - ); + void SetControllerTime(double time); virtual void @@ -235,20 +254,76 @@ protected : bool ActivateReplicationCallback( SG_IObject *replica - ); + ) + { + if (m_callbacks.m_replicafunc) + { + // Call client provided replication func + if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL) + return false; + } + return true; + } + void ActivateDestructionCallback( - ); + ) + { + if (m_callbacks.m_destructionfunc) + { + // Call client provided destruction function on this! + m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo); + } + else + { + // no callback but must still destroy the node to avoid memory leak + delete this; + } + } void ActivateUpdateTransformCallback( - ); + ) + { + if (m_callbacks.m_updatefunc) + { + // Call client provided update func. + m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo); + } + } + + bool + ActivateScheduleUpdateCallback( + ) + { + // HACK, this check assumes that the scheduled nodes are put on a DList (see SG_Node.h) + // The early check on Empty() allows up to avoid calling the callback function + // when the node is already scheduled for update. + if (Empty() && m_callbacks.m_schedulefunc) + { + // Call client provided update func. + return m_callbacks.m_schedulefunc(this, m_SGclientObject, m_SGclientInfo); + } + return false; + } + + void + ActivateRecheduleUpdateCallback( + ) + { + if (m_callbacks.m_reschedulefunc) + { + // Call client provided update func. + m_callbacks.m_reschedulefunc(this, m_SGclientObject, m_SGclientInfo); + } + } + SG_IObject( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ); SG_IObject( diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp index 64d9019c86a..c4a1b151846 100644 --- a/source/gameengine/SceneGraph/SG_Node.cpp +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -40,7 +40,7 @@ using namespace std; SG_Node::SG_Node( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ) : SG_Spatial(clientobj,clientinfo,callbacks), @@ -141,22 +141,6 @@ Destruct() ActivateDestructionCallback(); } - - SG_Node* -SG_Node:: -GetSGParent( -) const { - return m_SGparent; -} - - void -SG_Node:: -SetSGParent( - SG_Node* parent -){ - m_SGparent = parent; -} - const SG_Node* SG_Node:: @@ -165,28 +149,6 @@ GetRootSGParent( return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this); } - bool -SG_Node:: -IsVertexParent() -{ - if (m_parent_relation) - { - return m_parent_relation->IsVertexRelation(); - } - return false; -} - - bool -SG_Node:: -IsSlowParent() -{ - if (m_parent_relation) - { - return m_parent_relation->IsSlowRelation(); - } - return false; -} - void SG_Node:: DisconnectFromParent( @@ -199,8 +161,6 @@ DisconnectFromParent( } - - void SG_Node::AddChild(SG_Node* child) { m_children.push_back(child); @@ -228,6 +188,9 @@ void SG_Node::UpdateWorldData(double time, bool parentUpdated) // to update the ActivateUpdateTransformCallback(); + // The node is updated, remove it from the update list + Delink(); + // update children's worlddata for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it) { @@ -236,24 +199,6 @@ void SG_Node::UpdateWorldData(double time, bool parentUpdated) } -NodeList& SG_Node::GetSGChildren() -{ - return this->m_children; -} - - -const NodeList& SG_Node::GetSGChildren() const -{ - return this->m_children; -} - - -void SG_Node::ClearSGChildren() -{ - m_children.clear(); -} - - void SG_Node::SetSimulatedTime(double time,bool recurse) { diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index 29943653a81..7c6ef92f670 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -44,7 +44,7 @@ public: SG_Node( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ); SG_Node( @@ -85,45 +85,47 @@ public: * @return a reference to the list of children of this node. */ - NodeList& - GetSGChildren( - ); + NodeList& GetSGChildren() + { + return this->m_children; + } /** * Get the current list of children. * @return a const reference to the current list of children of this node. */ - const - NodeList& - GetSGChildren( - ) const; + const NodeList& GetSGChildren() const + { + return this->m_children; + } /** * Clear the list of children associated with this node */ - void - ClearSGChildren( - ); + void ClearSGChildren() + { + m_children.clear(); + } /** * return the parent of this node if it exists. */ - SG_Node* - GetSGParent( - ) const ; - + SG_Node* GetSGParent() const + { + return m_SGparent; + } /** * Set the parent of this node. */ - void - SetSGParent( - SG_Node* parent - ); + void SetSGParent(SG_Node* parent) + { + m_SGparent = parent; + } /** * Return the top node in this node's Scene graph hierarchy @@ -142,31 +144,34 @@ public: DisconnectFromParent( ); - /** - * Tell this node to treat it's parent as a vertex parent. - */ - - void - SetVertexParent( - bool isvertexparent - ) ; - - /** * Return vertex parent status. */ + bool IsVertexParent() + { + if (m_parent_relation) + { + return m_parent_relation->IsVertexRelation(); + } + return false; + } + - bool - IsVertexParent( - ) ; - /** * Return slow parent status. */ - bool - IsSlowParent( - ) ; + bool IsSlowParent() + { + if (m_parent_relation) + { + return m_parent_relation->IsSlowRelation(); + } + return false; + } + + + /** * Update the spatial data of this node. Iterate through @@ -190,6 +195,42 @@ public: bool recurse ); + /** + * Schedule this node for update by placing it in head queue + */ + bool Schedule(SG_QList& head) + { + // Put top parent in front of list to make sure they are updated before their + // children => the children will be udpated and removed from the list before + // we get to them, should they be in the list too. + return (m_SGparent)?head.AddBack(this):head.AddFront(this); + } + + /** + * Used during Scenegraph update + */ + static SG_Node* GetNextScheduled(SG_QList& head) + { + return static_cast(head.Remove()); + } + + /** + * Make this node ready for schedule on next update. This is needed for nodes + * that must always be updated (slow parent, bone parent) + */ + bool Reschedule(SG_QList& head) + { + return head.QAddBack(this); + } + + /** + * Used during Scenegraph update + */ + static SG_Node* GetNextRescheduled(SG_QList& head) + { + return static_cast(head.QRemove()); + } + /** * Node replication functions. */ diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h new file mode 100644 index 00000000000..efaa613bbb9 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -0,0 +1,144 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __SG_QLIST +#define __SG_QLIST + +#include "SG_DList.h" + +/** + * Double-Double circular linked list + * For storing an object is two lists simultaneously + */ +class SG_QList : public SG_DList +{ +protected : + SG_QList* m_fqlink; + SG_QList* m_bqlink; + +public: + template class iterator + { + private: + SG_QList& m_head; + T* m_current; + public: + typedef iterator _myT; + iterator(SG_QList& head) : m_head(head), m_current(NULL) {} + ~iterator() {} + + void begin() + { + m_current = (T*)m_head.QPeek(); + if (m_current == (T*)m_head.Self()) + { + m_current = NULL; + } + } + bool end() + { + return (NULL == m_current); + } + T* operator*() + { + return m_current; + } + _myT& operator++() + { + assert(m_current); + m_current = (T*)m_current->QPeek(); + if (m_current == (T*)m_head.Self()) + { + m_current = NULL; + } + return *this; + } + }; + + SG_QList() : SG_DList() + { + m_fqlink = m_bqlink = this; + } + virtual ~SG_QList() + { + QDelink(); + } + + inline bool QEmpty() // Check for empty queue + { + return ( m_fqlink == this ); + } + bool QAddBack( SG_QList *item ) // Add to the back + { + if (!item->QEmpty()) + return false; + item->m_bqlink = m_bqlink; + item->m_fqlink = this; + m_bqlink->m_fqlink = item; + m_bqlink = item; + return true; + } + bool QAddFront( SG_QList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_fqlink = m_fqlink; + item->m_bqlink = this; + m_fqlink->m_bqlink = item; + m_fqlink = item; + return true; + } + SG_QList *QRemove() // Remove from the front + { + if (QEmpty()) + { + return NULL; + } + SG_QList* item = m_fqlink; + m_fqlink = item->m_fqlink; + m_fqlink->m_bqlink = this; + item->m_fqlink = item->m_bqlink = item; + return item; + } + void QDelink() // Remove from the middle + { + if (!QEmpty()) + { + m_bqlink->m_fqlink = m_fqlink; + m_fqlink->m_bqlink = m_bqlink; + m_fqlink = m_bqlink = this; + } + } + inline SG_QList *QPeek() // Look at front without removing + { + return m_fqlink; + } +}; + +#endif //__SG_QLIST + diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index 2f3176816c6..97b15bdf376 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -40,7 +40,7 @@ SG_Spatial:: SG_Spatial( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ): SG_IObject(clientobj,clientinfo,callbacks), @@ -56,8 +56,9 @@ SG_Spatial( m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)), m_radius(1.0), - m_modified(true) + m_modified(false) { + SetModified(); } SG_Spatial:: @@ -88,13 +89,6 @@ SG_Spatial:: delete (m_parent_relation); } - SG_ParentRelation * -SG_Spatial:: -GetParentRelation( -){ - return m_parent_relation; -} - void SG_Spatial:: SetParentRelation( @@ -102,7 +96,7 @@ SetParentRelation( ){ delete (m_parent_relation); m_parent_relation = relation; - m_modified = true; + SetModified(); } @@ -143,11 +137,6 @@ UpdateSpatialData( return bComputesWorldTransform; } -bool SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated) -{ - return m_parent_relation->UpdateChildCoordinates(this,parent,parentUpdated); -} - /** * Position and translation methods */ @@ -169,56 +158,14 @@ RelativeTranslate( m_localPosition += trans; } } - m_modified = true; + SetModified(); } - void -SG_Spatial:: -SetLocalPosition( - const MT_Point3& trans -){ - m_localPosition = trans; - m_modified = true; -} - - void -SG_Spatial:: -SetWorldPosition( - const MT_Point3& trans -) { - m_worldPosition = trans; -} /** * Scaling methods. */ - void -SG_Spatial:: -RelativeScale( - const MT_Vector3& scale -){ - m_localScaling = m_localScaling * scale; - m_modified = true; -} - - void -SG_Spatial:: -SetLocalScale( - const MT_Vector3& scale -){ - m_localScaling = scale; - m_modified = true; -} - - - void -SG_Spatial:: -SetWorldScale( - const MT_Vector3& scale -){ - m_worldScaling = scale; -} /** * Orientation and rotation methods. @@ -236,93 +183,11 @@ RelativeRotate( rot : (GetWorldOrientation().inverse() * rot * GetWorldOrientation())); - m_modified = true; -} - - void -SG_Spatial:: -SetLocalOrientation(const MT_Matrix3x3& rot) -{ - m_localRotation = rot; - m_modified = true; + SetModified(); } - void -SG_Spatial:: -SetWorldOrientation( - const MT_Matrix3x3& rot -) { - m_worldRotation = rot; -} - -const - MT_Point3& -SG_Spatial:: -GetLocalPosition( -) const { - return m_localPosition; -} - -const - MT_Matrix3x3& -SG_Spatial:: -GetLocalOrientation( -) const { - return m_localRotation; -} - -const - MT_Vector3& -SG_Spatial:: -GetLocalScale( -) const{ - return m_localScaling; -} - - -const - MT_Point3& -SG_Spatial:: -GetWorldPosition( -) const { - return m_worldPosition; -} - -const - MT_Matrix3x3& -SG_Spatial:: -GetWorldOrientation( -) const { - return m_worldRotation; -} - -const - MT_Vector3& -SG_Spatial:: -GetWorldScaling( -) const { - return m_worldScaling; -} - -void SG_Spatial::SetWorldFromLocalTransform() -{ - m_worldPosition= m_localPosition; - m_worldScaling= m_localScaling; - m_worldRotation= m_localRotation; -} - -SG_BBox& SG_Spatial::BBox() -{ - return m_bbox; -} - -void SG_Spatial::SetBBox(SG_BBox& bbox) -{ - m_bbox = bbox; -} - MT_Transform SG_Spatial::GetWorldTransform() const { return MT_Transform(m_worldPosition, diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index c2ed80d21b2..eb1e87fbf19 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -35,6 +35,7 @@ #include // or Quaternion later ? #include "SG_IObject.h" #include "SG_BBox.h" +#include "SG_ParentRelation.h" class SG_Node; @@ -65,6 +66,16 @@ protected: public: + inline void ClearModified() + { + m_modified = false; + } + inline void SetModified() + { + m_modified = true; + ActivateScheduleUpdateCallback(); + } + /** * Define the realtionship this node has with it's parent * node. You should pass an unshared instance of an SG_ParentRelation @@ -84,9 +95,12 @@ public: SG_ParentRelation *relation ); - SG_ParentRelation * - GetParentRelation( - ); + SG_ParentRelation * GetParentRelation() + { + return m_parent_relation; + } + + /** @@ -105,15 +119,17 @@ public: bool local ); - void - SetLocalPosition( - const MT_Point3& trans - ); + void SetLocalPosition(const MT_Point3& trans) + { + m_localPosition = trans; + SetModified(); + } + + void SetWorldPosition(const MT_Point3& trans) + { + m_worldPosition = trans; + } - void - SetWorldPosition( - const MT_Point3& trans - ); void RelativeRotate( @@ -121,72 +137,95 @@ public: bool local ); - void - SetLocalOrientation( - const MT_Matrix3x3& rot - ); + void SetLocalOrientation(const MT_Matrix3x3& rot) + { + m_localRotation = rot; + SetModified(); + } - void - SetWorldOrientation( - const MT_Matrix3x3& rot - ); + void SetWorldOrientation(const MT_Matrix3x3& rot) + { + m_worldRotation = rot; + } - void - RelativeScale( - const MT_Vector3& scale - ); + void RelativeScale(const MT_Vector3& scale) + { + m_localScaling = m_localScaling * scale; + SetModified(); + } - void - SetLocalScale( - const MT_Vector3& scale - ); + void SetLocalScale(const MT_Vector3& scale) + { + m_localScaling = scale; + SetModified(); + } - void - SetWorldScale( - const MT_Vector3& scale - ); + void SetWorldScale(const MT_Vector3& scale) + { + m_worldScaling = scale; + } - const - MT_Point3& - GetLocalPosition( - ) const ; + const MT_Point3& GetLocalPosition() const + { + return m_localPosition; + } - const - MT_Matrix3x3& - GetLocalOrientation( - ) const ; + const MT_Matrix3x3& GetLocalOrientation() const + { + return m_localRotation; + } - const - MT_Vector3& - GetLocalScale( - ) const; + const MT_Vector3& GetLocalScale() const + { + return m_localScaling; + } - const - MT_Point3& - GetWorldPosition( - ) const ; + const MT_Point3& GetWorldPosition() const + { + return m_worldPosition; + } - const - MT_Matrix3x3& - GetWorldOrientation( - ) const ; + const MT_Matrix3x3& GetWorldOrientation() const + { + return m_worldRotation; + } + + const MT_Vector3& GetWorldScaling() const + { + return m_worldScaling; + } + + void SetWorldFromLocalTransform() + { + m_worldPosition= m_localPosition; + m_worldScaling= m_localScaling; + m_worldRotation= m_localRotation; + } - const - MT_Vector3& - GetWorldScaling( - ) const ; - void SetWorldFromLocalTransform(); MT_Transform GetWorldTransform() const; - bool ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated); + bool ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated) + { + return m_parent_relation->UpdateChildCoordinates(this,parent,parentUpdated); + } + /** * Bounding box functions. */ - SG_BBox& BBox(); - void SetBBox(SG_BBox & bbox); + SG_BBox& BBox() + { + return m_bbox; + } + + void SetBBox(SG_BBox& bbox) + { + m_bbox = bbox; + } + + bool inside(const MT_Point3 &point) const; void getBBox(MT_Point3 *box) const; void getAABBox(MT_Point3 *box) const; @@ -210,7 +249,7 @@ protected: SG_Spatial( void* clientobj, void* clientinfo, - SG_Callbacks callbacks + SG_Callbacks& callbacks ); SG_Spatial( @@ -231,7 +270,6 @@ protected: double time, bool& parentUpdated ); - void SetModified(bool modified) { m_modified = modified; } }; From 9248da811e7e0c1e8945d85a6520e74678d9e6c0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 May 2009 08:17:18 +0000 Subject: [PATCH 152/444] gcc4.4 needed this to build --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index c4c71d9dd85..3c93265c40b 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2055,7 +2055,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) { // blender has an additional 'parentinverse' offset in each object - SG_Node* parentinversenode = new SG_Node(NULL,kxscene,SG_Callbacks(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc)); + SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); + SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); // define a normal parent relationship for this node. KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); @@ -2249,7 +2250,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) { // blender has an additional 'parentinverse' offset in each object - SG_Node* parentinversenode = new SG_Node(NULL,kxscene,SG_Callbacks(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc)); + SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); + SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); // define a normal parent relationship for this node. KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); From 2f7cd19ff520ff5a1a0f80a55cc5e68c802b7df5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 May 2009 08:55:54 +0000 Subject: [PATCH 153/444] print BGE Py api warnings only once to avoid flooding the terminal and slowing the game down too much, resets on loading scenes/blendfiles and restarting the game engine. --- .../gameengine/Expressions/PyObjectPlus.cpp | 29 +++++++++++++- source/gameengine/Expressions/PyObjectPlus.h | 40 ++++++++++++++++++- source/gameengine/Ketsji/KX_PythonInit.cpp | 10 ++++- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 107b12b7159..82f67a9b007 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -908,15 +908,16 @@ PyObject *PyObjectPlus::NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// /* deprecation warning management */ + bool PyObjectPlus::m_ignore_deprecation_warnings(false); void PyObjectPlus::SetDeprecationWarnings(bool ignoreDeprecationWarnings) { m_ignore_deprecation_warnings = ignoreDeprecationWarnings; } -void PyObjectPlus::ShowDeprecationWarning(const char* old_way,const char* new_way) +void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* new_way) { - if (!m_ignore_deprecation_warnings) { + { printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way); // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno) @@ -955,6 +956,30 @@ void PyObjectPlus::ShowDeprecationWarning(const char* old_way,const char* new_wa } } +void PyObjectPlus::ClearDeprecationWarning() +{ + WarnLink *wlink_next; + WarnLink *wlink = GetDeprecationWarningLinkFirst(); + + while(wlink) + { + wlink->warn_done= false; /* no need to NULL the link, its cleared before adding to the list next time round */ + wlink_next= reinterpret_cast(wlink->link); + wlink->link= NULL; + wlink= wlink_next; + } + NullDeprecationWarning(); +} + +WarnLink* m_base_wlink_first= NULL; +WarnLink* m_base_wlink_last= NULL; + +WarnLink* PyObjectPlus::GetDeprecationWarningLinkFirst(void) {return m_base_wlink_first;} +WarnLink* PyObjectPlus::GetDeprecationWarningLinkLast(void) {return m_base_wlink_last;} +void PyObjectPlus::SetDeprecationWarningFirst(WarnLink* wlink) {m_base_wlink_first= wlink;} +void PyObjectPlus::SetDeprecationWarningLinkLast(WarnLink* wlink) {m_base_wlink_last= wlink;} +void PyObjectPlus::NullDeprecationWarning() {m_base_wlink_first= m_base_wlink_last= NULL;} + #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index f90a1436d00..449ece535c1 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -81,6 +81,36 @@ static inline void Py_Fatal(const char *M) { exit(-1); }; + +/* Use with ShowDeprecationWarning macro */ +typedef struct { + bool warn_done; + void *link; +} WarnLink; + +#define ShowDeprecationWarning(old_way, new_way) \ +{ \ + static WarnLink wlink = {false, NULL}; \ + if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \ + { \ + ShowDeprecationWarning_func(old_way, new_way); \ + WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \ + ShowDeprecationWarning_func(old_way, new_way); \ + wlink.warn_done = true; \ + wlink.link = NULL; \ + \ + if(wlink_last) { \ + wlink_last->link= (void *)&(wlink); \ + SetDeprecationWarningLinkLast(&(wlink)); \ + } else { \ + SetDeprecationWarningFirst(&(wlink)); \ + SetDeprecationWarningLinkLast(&(wlink)); \ + } \ + } \ +} \ + + + typedef struct { PyObject_HEAD /* required python macro */ class PyObjectPlus *ref; @@ -461,13 +491,21 @@ public: static bool m_ignore_deprecation_warnings; + static WarnLink* GetDeprecationWarningLinkFirst(void); + static WarnLink* GetDeprecationWarningLinkLast(void); + static void SetDeprecationWarningFirst(WarnLink* wlink); + static void SetDeprecationWarningLinkLast(WarnLink* wlink); + static void NullDeprecationWarning(); + /** enable/disable display of deprecation warnings */ static void SetDeprecationWarnings(bool ignoreDeprecationWarnings); /** Shows a deprecation warning */ - static void ShowDeprecationWarning(const char* method,const char* prop); + static void ShowDeprecationWarning_func(const char* method,const char* prop); + static void ClearDeprecationWarning(); }; + PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict); #endif // _adr_py_lib_h_ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 18fd990dc51..8eb8956cfe2 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1123,8 +1123,8 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack gp_KetsjiScene = scene; gUseVisibilityTemp=false; - - + + PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */ /* Use existing module where possible * be careful not to init any runtime vars after this */ @@ -1697,6 +1697,8 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur first_time = false; + PyObjectPlus::ClearDeprecationWarning(); + PyObject* moduleobj = PyImport_AddModule("__main__"); return PyModule_GetDict(moduleobj); } @@ -1710,6 +1712,7 @@ void exitGamePlayerPythonScripting() Py_Finalize(); bpy_import_main_set(NULL); + PyObjectPlus::ClearDeprecationWarning(); } @@ -1736,6 +1739,8 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev /* clear user defined modules that may contain data from the last run */ clearGameModules(); + PyObjectPlus::NullDeprecationWarning(); + PyObject* moduleobj = PyImport_AddModule("__main__"); return PyModule_GetDict(moduleobj); } @@ -1781,6 +1786,7 @@ void exitGamePythonScripting() clearGameModules(); restorePySysPath(); /* get back the original sys.path and clear the backup */ bpy_import_main_set(NULL); + PyObjectPlus::ClearDeprecationWarning(); } From 3226b33e4852f58c2ebc9d28beee2e03278bd2d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 May 2009 13:01:18 +0000 Subject: [PATCH 154/444] python geometry function Geometry.BezierInterp(vec_knot_1, vec_handle_1, vec_handle_2, vec_knot_2, resolution) can use 2D-4D vectors Also made 3ds import give a message when no python installed --- release/scripts/3ds_import.py | 14 ++++-- source/blender/python/api2_2x/Geometry.c | 49 +++++++++++++++++++ source/blender/python/api2_2x/doc/Geometry.py | 8 ++- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py index 1963d2e7433..bcde82c4869 100644 --- a/release/scripts/3ds_import.py +++ b/release/scripts/3ds_import.py @@ -133,10 +133,12 @@ import BPyImage import BPyMessages -import struct -from struct import calcsize, unpack +try: + from struct import calcsize, unpack +except: + calcsize= unpack= None + -import os # If python version is less than 2.4, try to get set stuff from module try: @@ -958,7 +960,10 @@ def load_3ds(filename, PREF_UI= True): DEBUG= False if __name__=='__main__' and not DEBUG: - Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') + if calcsize==None: + Blender.Draw.PupMenu('Error%t|a full python installation not found') + else: + Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') # For testing compatibility #load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False) @@ -966,6 +971,7 @@ if __name__=='__main__' and not DEBUG: ''' else: + import os # DEBUG ONLY TIME= Blender.sys.time() import os diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index 80869889af7..cbb6d60632e 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BKE_utildefines.h" +#include "BKE_curve.h" #include "BLI_boxpack2d.h" #include "BLI_arithb.h" @@ -53,6 +54,7 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args ); static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args ); static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args ); +static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ); /*-------------------------DOC STRINGS ---------------------------*/ @@ -63,6 +65,7 @@ static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - take static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triangle, only the x and y are used from the vectors"; static char M_Geometry_PointInQuad2D_doc[] = "(pt, quad_p1, quad_p2, quad_p3, quad_p4) - takes 5 vectors, one is the point and the next 4 define the quad, only the x and y are used from the vectors"; static char M_Geometry_BoxPack2D_doc[] = ""; +static char M_Geometry_BezierInterp_doc[] = ""; /*-----------------------METHOD DEFINITIONS ----------------------*/ struct PyMethodDef M_Geometry_methods[] = { {"PolyFill", ( PyCFunction ) M_Geometry_PolyFill, METH_O, M_Geometry_PolyFill_doc}, @@ -71,6 +74,7 @@ struct PyMethodDef M_Geometry_methods[] = { {"PointInTriangle2D", ( PyCFunction ) M_Geometry_PointInTriangle2D, METH_VARARGS, M_Geometry_PointInTriangle2D_doc}, {"PointInQuad2D", ( PyCFunction ) M_Geometry_PointInQuad2D, METH_VARARGS, M_Geometry_PointInQuad2D_doc}, {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc}, + {"BezierInterp", ( PyCFunction ) M_Geometry_BezierInterp, METH_VARARGS, M_Geometry_BezierInterp_doc}, {NULL, NULL, 0, NULL} }; @@ -469,3 +473,48 @@ static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * boxlist ) return Py_BuildValue( "ff", tot_width, tot_height); } + +static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) +{ + VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2; + int resolu; + int dims; + int i; + float *coord_array, *fp; + + float k1[4] = {0.0, 0.0, 0.0, 0.0}; + float h1[4] = {0.0, 0.0, 0.0, 0.0}; + float k2[4] = {0.0, 0.0, 0.0, 0.0}; + float h2[4] = {0.0, 0.0, 0.0, 0.0}; + + float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, newvec[2]; + if( !PyArg_ParseTuple ( args, "O!O!O!O!i", + &vector_Type, &vec_k1, + &vector_Type, &vec_h1, + &vector_Type, &vec_h2, + &vector_Type, &vec_k2, &resolu) || (resolu<=1) + ) { + PyErr_SetString( PyExc_TypeError, "expected 4 vector types and an int greater then 1\n" ); + return NULL; + } + + dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); + + for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; + for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i]; + for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i]; + for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i]; + + coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "BezierInterp"); + for(i=0; i Date: Mon, 4 May 2009 14:41:25 +0000 Subject: [PATCH 155/444] Fix for msvc compile error reported by Wahooney - thanks --- source/blender/python/api2_2x/Geometry.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index cbb6d60632e..2ac6b8a714a 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -481,6 +481,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) int dims; int i; float *coord_array, *fp; + PyObject *list; float k1[4] = {0.0, 0.0, 0.0, 0.0}; float h1[4] = {0.0, 0.0, 0.0, 0.0}; @@ -510,7 +511,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, dims); } - PyObject* list= PyList_New(resolu); + list= PyList_New(resolu); fp= coord_array; for(i=0; i Date: Mon, 4 May 2009 15:31:28 +0000 Subject: [PATCH 156/444] Fix crash because XSetInputFocus fail. Some WM send a WM_TAKE_FOCUS event before the window is really mapped (for example, change from virtual desktop), because of this, the call to XSetInputFocus fail and close Blender. --- intern/ghost/intern/GHOST_SystemX11.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 02dfdc2e25c..bfa5f35d312 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -515,11 +515,28 @@ GHOST_SystemX11::processEvent(XEvent *xe) window, data); } } else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) { + XWindowAttributes attr; + Window fwin; + int revert_to; + /* as ICCCM say, we need reply this event * with a SetInputFocus, the data[1] have * the valid timestamp (send by the wm). + * + * Some WM send this event before the + * window is really mapped (for example + * change from virtual desktop), so we need + * to be sure that our windows is mapped + * or this call fail and close blender. */ - XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]); + if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) { + if (XGetInputFocus(m_display, &fwin, &revert_to) == True) { + if (attr.map_state == IsViewable) { + if (fwin != xcme.window) + XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]); + } + } + } } else { /* Unknown client message, ignore */ } From 40fa6b0f37ce022175d1b17a5c8e987119d14218 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Mon, 4 May 2009 16:03:54 +0000 Subject: [PATCH 157/444] Fix some spelling errors. --- release/scripts/object_cookie_cutter.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/release/scripts/object_cookie_cutter.py b/release/scripts/object_cookie_cutter.py index 2a6e0ad6b2e..4950c18c0f4 100644 --- a/release/scripts/object_cookie_cutter.py +++ b/release/scripts/object_cookie_cutter.py @@ -10,7 +10,7 @@ __url__= ["blender", "blenderartist"] __version__= "1.0" __bpydoc__= """\ -This script takes the selected mesh objects, devides them into 2 groups +This script takes the selected mesh objects, divides them into 2 groups Cutters and The objects to be cut. Cutters are meshes with no faces, just edge loops. and any meshes with faces will be cut. @@ -128,14 +128,14 @@ def sorted_indicies(i1, i2): def fake_length2d(pt1, pt2): ''' - Only used for comparison so dont sqrt + Only used for comparison so don't sqrt ''' #return math.sqrt(abs(pow(x1-x2, 2)+ pow(y1-y2, 2))) return pow(pt1[0]-pt2[0], 2) + pow(pt1[1]- pt2[1], 2) def length2d(pt1, pt2): ''' - Only used for comparison so dont sqrt + Only used for comparison so don't sqrt ''' #return math.sqrt(abs(pow(x1-x2, 2)+ pow(y1-y2, 2))) return sqrt(pow(pt1[0]-pt2[0], 2) + pow(pt1[1]- pt2[1], 2)) @@ -150,7 +150,7 @@ def tri_area_2d(v1, v2, v3): return 0.25 * sqrt(abs(p*(p-2*e1)*(p-2*e2)*(p-2*e3))) def tri_pt_find_z_2d(pt, tri): - """ Takes a face and 3d vector and assigns teh vectors Z to its on the face""" + """ Takes a face and 3d vector and assigns the vectors Z to its on the face""" l1= tri_area_2d(tri[1], tri[2], pt) l2= tri_area_2d(tri[0], tri[2], pt) @@ -170,7 +170,7 @@ def tri_pt_find_z_2d(pt, tri): def tri_pt_find_uv_2d(pt, tri, uvs): - """ Takes a face and 3d vector and assigns teh vectors Z to its on the face""" + """ Takes a face and 3d vector and assigns the vectors Z to its on the face""" l1= tri_area_2d(tri[1], tri[2], pt) l2= tri_area_2d(tri[0], tri[2], pt) @@ -288,12 +288,12 @@ def terrain_cut_2d(t, c, PREF_Z_LOC): # Loop through the cutter edges. for ei_c, ed_c in enumerate(me_c.edges): # If the cutter edge has 2 verts inside the same face then we can ignore it - # Bothe are different faces or None + # Both are different faces or None if cut_vert_terrain_faces[ed_c.v1.index] != cut_vert_terrain_faces[ed_c.v2.index] or\ cut_vert_terrain_faces[ed_c.v1.index] == cut_vert_terrain_faces[ed_c.v2.index] == None: eb_c= c.edge_bounds[ei_c] if bounds_intersect(eb_t, eb_c): # face/edge bounds intersect? - # Now we know the 2 edges might intersect, we'll do a propper test + # Now we know the 2 edges might intersect, we'll do a proper test x= LineIntersect2D(ed_t.v1.co, ed_t.v2.co, ed_c.v1.co, ed_c.v2.co) if x: @@ -340,7 +340,7 @@ def terrain_cut_2d(t, c, PREF_Z_LOC): for f in faces: faces_intersecting.setdefault(f.index, []).append(ed_isect) - # this list is used to store edges that are totaly inside a face ( no intersections with terrain) + # this list is used to store edges that are totally inside a face ( no intersections with terrain) # we can remove these as we face_containing_edges= [[] for i in xrange(len(me_t.faces))] for ed_c in me_c.edges: @@ -412,8 +412,8 @@ def terrain_cut_2d(t, c, PREF_Z_LOC): - # edges that dont have a vert in the face have to span between to intersection points - # since we dont know the other point at any 1 time we need to remember edges that + # edges that don't have a vert in the face have to span between to intersection points + # since we don't know the other point at any 1 time we need to remember edges that # span a face and add them once we'v collected both # first add outline edges edge_span_face= {} @@ -507,7 +507,7 @@ def terrain_cut_2d(t, c, PREF_Z_LOC): # 0,2,3 f_uv_mod= f_uv[0], f_uv[2], f_uv[3] f_vco_mod= f_vco[0], f_vco[2], f_vco[3] - # else - side of 0,1,2 - dont modify the quad + # else - side of 0,1,2 - don't modify the quad uvs[i]= tri_pt_find_uv_2d(v_co, f_vco_mod, f_uv_mod) @@ -579,7 +579,7 @@ def main(): for ob in obs: if ob.type == 'Mesh': me= ob.getData(mesh=1) - elif ob.data.flag & 1: # Is the curve 3D? else dont use. + elif ob.data.flag & 1: # Is the curve 3D? else don't use. me= BPyMesh.getMeshFromObject(ob) # get the curve else: continue From 4ecff51bfeda54d93f06c2f0c6964e9398841453 Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Mon, 4 May 2009 18:46:34 +0000 Subject: [PATCH 158/444] BugFix [#18597] Blender's text editor cant paste from SciTE in linux Commit patch [#18597] Blender's text editor cant paste from SciTE in linux Submitted by Campbell. I made some changes to cleanup a little the code, atoms are now in the System class. The getClipboard_xcout try to convert/request: 1) Request for UTF8, if fail 2) Request for COMPOUND_TEXT, if fail 3) Request for TEXT, if fail 4) Request for STRING Test here with SciTE Version 1.77, firefox, xterm and text editor working with both library's gtk/qt and all work fine. --- intern/ghost/intern/GHOST_SystemX11.cpp | 395 ++++++++++++++++-------- intern/ghost/intern/GHOST_SystemX11.h | 21 +- 2 files changed, 288 insertions(+), 128 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index bfa5f35d312..0fb4b735f97 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -107,6 +107,15 @@ GHOST_SystemX11( m_wm_protocols= XInternAtom(m_display, "WM_PROTOCOLS", False); m_wm_take_focus= XInternAtom(m_display, "WM_TAKE_FOCUS", False); + m_targets= XInternAtom(m_display, "TARGETS", False); + m_string= XInternAtom(m_display, "STRING", False); + m_compound_text= XInternAtom(m_display, "COMPOUND_TEXT", False); + m_text= XInternAtom(m_display, "TEXT", False); + m_clipboard= XInternAtom(m_display, "CLIPBOARD", False); + m_primary= XInternAtom(m_display, "PRIMARY", False); + m_xclip_out= XInternAtom(m_display, "XCLIP_OUT", False); + m_incr= XInternAtom(m_display, "INCR", False); + m_utf8_string= XInternAtom(m_display, "UTF8_STRING", False); // compute the initial time timeval tv; @@ -992,144 +1001,280 @@ convertXKey( #undef GXMAP - GHOST_TUns8* -GHOST_SystemX11:: -getClipboard(int flag -) const { - //Flag - //0 = Regular clipboard 1 = selection - static Atom Primary_atom, clip_String, compound_text, a_text, a_string; - Atom rtype; - Window m_window, owner; - unsigned char *data, *tmp_data; - int bits, count; - unsigned long len, bytes; - XEvent xevent; - + +/* from xclip.c xcout() v0.11 */ + +#define XCLIB_XCOUT_NONE 0 /* no context */ +#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */ +#define XCLIB_XCOUT_INCR 2 /* in an incr loop */ +#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */ +#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */ +#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */ +#define XCLIB_XCOUT_FALLBACK_TEXT 6 + +// Retrieves the contents of a selections. +void GHOST_SystemX11::getClipboard_xcout(XEvent evt, + Atom sel, Atom target, unsigned char **txt, + unsigned long *len, unsigned int *context) const +{ + Atom pty_type; + int pty_format; + unsigned char *buffer; + unsigned long pty_size, pty_items; + unsigned char *ltxt= *txt; + vector & win_vec = m_windowManager->getWindows(); vector::iterator win_it = win_vec.begin(); GHOST_WindowX11 * window = static_cast(*win_it); - m_window = window->getXWindow(); + Window win = window->getXWindow(); - clip_String = XInternAtom(m_display, "_BLENDER_STRING", False); - compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False); - a_text= XInternAtom(m_display, "TEXT", False); - a_string= XInternAtom(m_display, "STRING", False); + switch (*context) { + // There is no context, do an XConvertSelection() + case XCLIB_XCOUT_NONE: + // Initialise return length to 0 + if (*len > 0) { + free(*txt); + *len = 0; + } - //lets check the owner and if it is us then return the static buffer - if(flag == 0) { - Primary_atom = XInternAtom(m_display, "CLIPBOARD", False); - owner = XGetSelectionOwner(m_display, Primary_atom); - if (owner == m_window) { - data = (unsigned char*) malloc(strlen(txt_cut_buffer)+1); - strcpy((char*)data, txt_cut_buffer); - return (GHOST_TUns8*)data; - } else if (owner == None) { - return NULL; - } - } else { - Primary_atom = XInternAtom(m_display, "PRIMARY", False); - owner = XGetSelectionOwner(m_display, Primary_atom); - if (owner == m_window) { - data = (unsigned char*) malloc(strlen(txt_select_buffer)+1); - strcpy((char*)data, txt_select_buffer); - return (GHOST_TUns8*)data; - } else if (owner == None) { - return NULL; - } - } + // Send a selection request + XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime); + *context = XCLIB_XCOUT_SENTCONVSEL; + return; - if(!Primary_atom) { - return NULL; - } - - XDeleteProperty(m_display, m_window, Primary_atom); - XConvertSelection(m_display, Primary_atom, compound_text, clip_String, m_window, CurrentTime); //XA_STRING - XFlush(m_display); + case XCLIB_XCOUT_SENTCONVSEL: + if (evt.type != SelectionNotify) + return; - //This needs to change so we do not wait for ever or check owner first - count= 1; - while(1) { - XNextEvent(m_display, &xevent); - if(xevent.type == SelectionNotify) { - if (xevent.xselection.property == None) { - /* Ok, the client can't convert the property - * to some that we can handle, try other types.. - */ - if (count == 1) { - XConvertSelection(m_display, Primary_atom, a_text, clip_String, m_window, CurrentTime); - count++; - } - else if (count == 2) { - XConvertSelection(m_display, Primary_atom, a_string, clip_String, m_window, CurrentTime); - count++; - } - else { - /* Ok, the owner of the selection can't - * convert the data to something that we can - * handle. - */ - return(NULL); - } + if (target == m_utf8_string && evt.xselection.property == None) { + *context= XCLIB_XCOUT_FALLBACK_UTF8; + return; + } + else if (target == m_compound_text && evt.xselection.property == None) { + *context= XCLIB_XCOUT_FALLBACK_COMP; + return; + } + else if (target == m_text && evt.xselection.property == None) { + *context= XCLIB_XCOUT_FALLBACK_TEXT; + return; + } + + // find the size and format of the data in property + XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, + AnyPropertyType, &pty_type, &pty_format, + &pty_items, &pty_size, &buffer); + XFree(buffer); + + if (pty_type == m_incr) { + // start INCR mechanism by deleting property + XDeleteProperty(m_display, win, m_xclip_out); + XFlush(m_display); + *context = XCLIB_XCOUT_INCR; + return; + } + + // if it's not incr, and not format == 8, then there's + // nothing in the selection (that xclip understands, anyway) + + if (pty_format != 8) { + *context = XCLIB_XCOUT_NONE; + return; + } + + // not using INCR mechanism, just read the property + XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, + False, AnyPropertyType, &pty_type, + &pty_format, &pty_items, &pty_size, &buffer); + + // finished with property, delete it + XDeleteProperty(m_display, win, m_xclip_out); + + // copy the buffer to the pointer for returned data + ltxt = (unsigned char *) malloc(pty_items); + memcpy(ltxt, buffer, pty_items); + + // set the length of the returned data + *len = pty_items; + *txt = ltxt; + + // free the buffer + XFree(buffer); + + *context = XCLIB_XCOUT_NONE; + + // complete contents of selection fetched, return 1 + return; + + case XCLIB_XCOUT_INCR: + // To use the INCR method, we basically delete the + // property with the selection in it, wait for an + // event indicating that the property has been created, + // then read it, delete it, etc. + + // make sure that the event is relevant + if (evt.type != PropertyNotify) + return; + + // skip unless the property has a new value + if (evt.xproperty.state != PropertyNewValue) + return; + + // check size and format of the property + XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, + AnyPropertyType, &pty_type, &pty_format, + &pty_items, &pty_size, (unsigned char **) &buffer); + + if (pty_format != 8) { + // property does not contain text, delete it + // to tell the other X client that we have read + // it and to send the next property + XFree(buffer); + XDeleteProperty(m_display, win, m_xclip_out); + return; + } + + if (pty_size == 0) { + // no more data, exit from loop + XFree(buffer); + XDeleteProperty(m_display, win, m_xclip_out); + *context = XCLIB_XCOUT_NONE; + + // this means that an INCR transfer is now + // complete, return 1 + return; + } + + XFree(buffer); + + // if we have come this far, the propery contains + // text, we know the size. + XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, + False, AnyPropertyType, &pty_type, &pty_format, + &pty_items, &pty_size, (unsigned char **) &buffer); + + // allocate memory to accommodate data in *txt + if (*len == 0) { + *len = pty_items; + ltxt = (unsigned char *) malloc(*len); } else { - if(XGetWindowProperty(m_display, m_window, xevent.xselection.property , 0L, 4096L, False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) == Success) { - if (data) { - if (bits == 8 && (rtype == compound_text || rtype == a_text || rtype == a_string)) { - tmp_data = (unsigned char*) malloc(strlen((char*)data)+1); - strcpy((char*)tmp_data, (char*)data); - } - else - tmp_data= NULL; - - XFree(data); - return (GHOST_TUns8*)tmp_data; - } - } - return(NULL); + *len += pty_items; + ltxt = (unsigned char *) realloc(ltxt, *len); } - } - } -} - void -GHOST_SystemX11:: -putClipboard( -GHOST_TInt8 *buffer, int flag) const -{ - static Atom Primary_atom; - Window m_window, owner; - - if(!buffer) {return;} - - if(flag == 0) { - Primary_atom = XInternAtom(m_display, "CLIPBOARD", False); - if(txt_cut_buffer) { free((void*)txt_cut_buffer); } - - txt_cut_buffer = (char*) malloc(strlen(buffer)+1); - strcpy(txt_cut_buffer, buffer); - } else { - Primary_atom = XInternAtom(m_display, "PRIMARY", False); - if(txt_select_buffer) { free((void*)txt_select_buffer); } - - txt_select_buffer = (char*) malloc(strlen(buffer)+1); - strcpy(txt_select_buffer, buffer); - } - - vector & win_vec = m_windowManager->getWindows(); - vector::iterator win_it = win_vec.begin(); - GHOST_WindowX11 * window = static_cast(*win_it); - m_window = window->getXWindow(); + // add data to ltxt + memcpy(<xt[*len - pty_items], buffer, pty_items); - if(!Primary_atom) { - return; + *txt = ltxt; + XFree(buffer); + + // delete property to get the next item + XDeleteProperty(m_display, win, m_xclip_out); + XFlush(m_display); + return; } - - XSetSelectionOwner(m_display, Primary_atom, m_window, CurrentTime); - owner = XGetSelectionOwner(m_display, Primary_atom); - if (owner != m_window) - fprintf(stderr, "failed to own primary\n"); - return; } +GHOST_TUns8 *GHOST_SystemX11::getClipboard(int flag) const +{ + //Flag + //0 = Regular clipboard 1 = selection + + // Options for where to get the selection from + Atom sseln= flag ? m_clipboard : m_primary; + Atom target= m_string; + + // from xclip.c doOut() v0.11 + unsigned char *sel_buf; /* buffer for selection data */ + unsigned long sel_len= 0; /* length of sel_buf */ + XEvent evt; /* X Event Structures */ + unsigned int context= XCLIB_XCOUT_NONE; + + if (sseln == m_string) + sel_buf= (unsigned char *)XFetchBuffer(m_display, (int *)&sel_len, 0); + else { + while (1) { + /* only get an event if xcout() is doing something */ + if (context != XCLIB_XCOUT_NONE) + XNextEvent(m_display, &evt); + + /* fetch the selection, or part of it */ + getClipboard_xcout(evt, sseln, target, &sel_buf, &sel_len, &context); + + /* fallback is needed. set XA_STRING to target and restart the loop. */ + if (context == XCLIB_XCOUT_FALLBACK) { + context= XCLIB_XCOUT_NONE; + target= m_string; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_UTF8) { + /* utf8 fail, move to compouned text. */ + context= XCLIB_XCOUT_NONE; + target= m_compound_text; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_COMP) { + /* compouned text faile, move to text. */ + context= XCLIB_XCOUT_NONE; + target= m_text; + continue; + } + + /* only continue if xcout() is doing something */ + if (context == XCLIB_XCOUT_NONE) + break; + } + } + + if (sel_len) { + /* only print the buffer out, and free it, if it's not + * empty + */ + unsigned char *tmp_data = (unsigned char*) malloc(sel_len+1); + memcpy((char*)tmp_data, (char*)sel_buf, sel_len); + tmp_data[sel_len] = '\0'; + + if (sseln == m_string) + XFree(sel_buf); + else + free(sel_buf); + + return (GHOST_TUns8*)tmp_data; + } + return(NULL); +} + +void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, int flag) const +{ + Window m_window, owner; + + vector & win_vec = m_windowManager->getWindows(); + vector::iterator win_it = win_vec.begin(); + GHOST_WindowX11 * window = static_cast(*win_it); + m_window = window->getXWindow(); + + if (buffer) { + if (flag == 0) { + XSetSelectionOwner(m_display, m_clipboard, m_window, CurrentTime); + owner= XGetSelectionOwner(m_display, m_clipboard); + if (txt_cut_buffer) + free((void*)txt_cut_buffer); + + txt_cut_buffer = (char*) malloc(strlen(buffer)+1); + strcpy(txt_cut_buffer, buffer); + } else { + XSetSelectionOwner(m_display, m_primary, m_window, CurrentTime); + owner= XGetSelectionOwner(m_display, m_primary); + if (txt_select_buffer) + free((void*)txt_select_buffer); + + txt_select_buffer = (char*) malloc(strlen(buffer)+1); + strcpy(txt_select_buffer, buffer); + } + + if (owner != m_window) + fprintf(stderr, "failed to own primary\n"); + } +} + diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index 576577917ba..6a2c81c09a7 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -199,14 +199,18 @@ public: prepareNdofInfo( volatile GHOST_TEventNDOFData *current_values ); - + + /* Helped function for get data from the clipboard. */ + void getClipboard_xcout(XEvent evt, Atom sel, Atom target, + unsigned char **txt, unsigned long *len, + unsigned int *context) const; + /** * Returns unsinged char from CUT_BUFFER0 * @param flag Flag indicates which buffer to return 0 for clipboard 1 for selection * @return Returns the Clipboard indicated by Flag */ - GHOST_TUns8* - getClipboard(int flag) const; + GHOST_TUns8 *getClipboard(int flag) const; /** * Puts buffer to system clipboard @@ -220,6 +224,17 @@ public: Atom m_wm_protocols; Atom m_delete_window_atom; + /* Atoms for Selection, copy & paste. */ + Atom m_targets; + Atom m_string; + Atom m_compound_text; + Atom m_text; + Atom m_clipboard; + Atom m_primary; + Atom m_xclip_out; + Atom m_incr; + Atom m_utf8_string; + private : Display * m_display; From e29e329885aa582316b70e13be2e4a05fe32fefc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 May 2009 21:49:25 +0000 Subject: [PATCH 159/444] [#18650] fbx export assigning textures to wrong materials... also fixed an error that made this script fail when python wasnt found. --- release/scripts/export_fbx.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 730776bf1b8..80b2fea0dd8 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -511,7 +511,7 @@ def write(filename, batch_objects = None, \ if time: curtime = time.localtime()[0:6] else: - curtime = [0,0,0,0,0,0] + curtime = (0,0,0,0,0,0) # file.write(\ '''FBXHeaderExtension: { @@ -1538,13 +1538,13 @@ def write(filename, batch_objects = None, \ if len(my_mesh.blenTextures) == 1: file.write('0') else: - #texture_mapping_local = {None:0} texture_mapping_local = {None:-1} i = 0 # 1 for dummy for tex in my_mesh.blenTextures: - texture_mapping_local[tex] = i - i+=1 + if tex: # None is set above + texture_mapping_local[tex] = i + i+=1 i=-1 for f in me.faces: @@ -1856,11 +1856,6 @@ def write(filename, batch_objects = None, \ armob = BPyObject.getObjectArmature(ob) blenParentBoneName = None - # Note - Fixed in BPyObject but for now just copy the function because testers wont have up to date modukes, - # TODO - remove this for 2.45 release since getObjectArmature has been fixed - if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.ARMATURE: - armob = ob.parent - # parent bone - special case if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE: armob = ob.parent From be2c21bcdb2a05fa238cb637940269941a5fc12c Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 4 May 2009 22:21:02 +0000 Subject: [PATCH 160/444] BGE logic: new sensor "tap" option to generate automatically on/off pulses When enabled, this option converts any positive trigger from the sensor into a pair of positive+negative trigger, with the negative trigger sent in the next frame. The negative trigger from the sensor are not passed to the controller as the option automatically generates the negative triggers. From the controller point of view, the sensor is positive only for 1 frame, even if the underlying sensor state remains positive. The option interacts with the other sensor option in this way: - Level option: tap option is mutually exclusive with level option. Both cannot be enabled at the same time. - Invert option: tap option operates on the negative trigger of the sensor, which are converted to positive trigger by the invert option. Hence, the controller will see the sensor positive for 1 frame when the underlying sensor state turns negative. - Positive pulse option: tap option adds a negative trigger after each repeated positive pulse, unless the frequency option is 0, in which case positive pulse are generated on every frame as before, as long as the underlying sensor state is positive. - Negative pulse option: this option is not compatible with tap option and is ignored when tap option is enabled. Notes: - Keyboard "All keys" is handled specially when tap option is set: There will be one pair of positive/negative trigger for each new key press, regardless on how many keys are already pressed and there is no trigger when keys are released, regardless if keys are still pressed. In case two keys are pressed in succesive frames, there will be 2 positive triggers and 1 negative trigger in the following frame. --- source/blender/makesdna/DNA_sensor_types.h | 3 +- source/blender/src/buttons_logic.c | 36 +++++++-- .../Converter/KX_ConvertSensors.cpp | 3 + .../GameLogic/SCA_ANDController.cpp | 2 +- .../GameLogic/SCA_ExpressionController.cpp | 2 +- source/gameengine/GameLogic/SCA_ISensor.cpp | 78 +++++++++++++++---- source/gameengine/GameLogic/SCA_ISensor.h | 19 ++++- .../GameLogic/SCA_KeyboardSensor.cpp | 3 + .../GameLogic/SCA_NANDController.cpp | 2 +- .../GameLogic/SCA_NORController.cpp | 2 +- .../gameengine/GameLogic/SCA_ORController.cpp | 2 +- .../GameLogic/SCA_XNORController.cpp | 2 +- .../GameLogic/SCA_XORController.cpp | 2 +- 13 files changed, 126 insertions(+), 30 deletions(-) diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h index 7a358ad0694..8b29ce1338d 100644 --- a/source/blender/makesdna/DNA_sensor_types.h +++ b/source/blender/makesdna/DNA_sensor_types.h @@ -158,7 +158,8 @@ typedef struct bSensor { /* just add here, to avoid align errors... */ short invert; /* Whether or not to invert the output. */ short level; /* Whether the sensor is level base (edge by default) */ - int pad; + short tap; + short pad; } bSensor; typedef struct bJoystickSensor { diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 941ed5ebe12..dccbc73787d 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1026,6 +1026,19 @@ static void set_col_sensor(int type, int medium) BIF_ThemeColorShade(col, medium?30:0); } + +static void verify_logicbutton_func(void *data1, void *data2) +{ + bSensor *sens= (bSensor*)data1; + + if(sens->level && sens->tap) { + if(data2 == &(sens->level)) sens->tap= 0; + else sens->level= 0; + allqueue(REDRAWBUTSLOGIC, 0); + } +} + + /** * Draws a toggle for pulse mode, a frequency field and a toggle to invert * the value of this sensor. Operates on the shared data block of sensors. @@ -1036,30 +1049,39 @@ static void draw_default_sensor_header(bSensor *sens, short y, short w) { + uiBut *but; + /* Pulsing and frequency */ uiDefIconButBitS(block, TOG, SENS_PULSE_REPEAT, 1, ICON_DOTSUP, - (short)(x + 10 + 0. * (w-20)), (short)(y - 21), (short)(0.15 * (w-20)), 19, + (short)(x + 10 + 0. * (w-20)), (short)(y - 21), (short)(0.1 * (w-20)), 19, &sens->pulse, 0.0, 0.0, 0, 0, "Activate TRUE level triggering (pulse mode)"); uiDefIconButBitS(block, TOG, SENS_NEG_PULSE_MODE, 1, ICON_DOTSDOWN, - (short)(x + 10 + 0.15 * (w-20)), (short)(y - 21), (short)(0.15 * (w-20)), 19, + (short)(x + 10 + 0.1 * (w-20)), (short)(y - 21), (short)(0.1 * (w-20)), 19, &sens->pulse, 0.0, 0.0, 0, 0, "Activate FALSE level triggering (pulse mode)"); uiDefButS(block, NUM, 1, "f:", - (short)(x + 10 + 0.3 * (w-20)), (short)(y - 21), (short)(0.275 * (w-20)), 19, + (short)(x + 10 + 0.2 * (w-20)), (short)(y - 21), (short)(0.275 * (w-20)), 19, &sens->freq, 0.0, 10000.0, 0, 0, "Delay between repeated pulses (in logic tics, 0 = no delay)"); /* value or shift? */ + but= uiDefButS(block, TOG, 1, "Level", + (short)(x + 10 + 0.5 * (w-20)), (short)(y - 21), (short)(0.20 * (w-20)), 19, + &sens->level, 0.0, 0.0, 0, 0, + "Level detector, trigger controllers of new states (only applicable upon logic state transition)"); + uiButSetFunc(but, verify_logicbutton_func, sens, &(sens->level)); + but= uiDefButS(block, TOG, 1, "Tap", + (short)(x + 10 + 0.702 * (w-20)), (short)(y - 21), (short)(0.12 * (w-20)), 19, + &sens->tap, 0.0, 0.0, 0, 0, + "Trigger controllers only for an instant, even while the sensor remains true"); + uiButSetFunc(but, verify_logicbutton_func, sens, &(sens->tap)); + uiDefButS(block, TOG, 1, "Inv", (short)(x + 10 + 0.85 * (w-20)), (short)(y - 21), (short)(0.15 * (w-20)), 19, &sens->invert, 0.0, 0.0, 0, 0, "Invert the level (output) of this sensor"); - uiDefButS(block, TOG, 1, "Level", - (short)(x + 10 + 0.65 * (w-20)), (short)(y - 21), (short)(0.20 * (w-20)), 19, - &sens->level, 0.0, 0.0, 0, 0, - "Level detector, trigger controllers of new states (only applicable upon logic state transition)"); } static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname) diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 19e594ff0cb..af57094b2b5 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -255,6 +255,7 @@ void BL_ConvertSensors(struct Object* blenderobject, int frequency = 0; bool invert = false; bool level = false; + bool tap = false; while(sens) { @@ -268,6 +269,7 @@ void BL_ConvertSensors(struct Object* blenderobject, frequency = sens->freq; invert = !(sens->invert == 0); level = !(sens->level == 0); + tap = !(sens->tap == 0); switch (sens->type) { @@ -755,6 +757,7 @@ void BL_ConvertSensors(struct Object* blenderobject, frequency); gamesensor->SetInvert(invert); gamesensor->SetLevel(level); + gamesensor->SetTap(tap); gamesensor->SetName(STR_String(sens->name)); gameobj->AddSensor(gamesensor); diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index 1b151cbe615..7991e82168f 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -66,7 +66,7 @@ void SCA_ANDController::Trigger(SCA_LogicManager* logicmgr) !(is==m_linkedsensors.end());is++) { SCA_ISensor* sensor = *is; - if (!sensor->IsPositiveTrigger()) + if (!sensor->GetState()) { sensorresult = false; break; diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index e6bccef08d4..a4e898a808f 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -161,7 +161,7 @@ CValue* SCA_ExpressionController::FindIdentifier(const STR_String& identifiernam SCA_ISensor* sensor = *is; if (sensor->GetName() == identifiername) { - identifierval = new CBoolValue(sensor->IsPositiveTrigger()); + identifierval = new CBoolValue(sensor->GetState()); //identifierval = sensor->AddRef(); } diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index 4d69216ed0b..1e9a4521df5 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -52,19 +52,21 @@ void SCA_ISensor::ReParent(SCA_IObject* parent) SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj, class SCA_EventManager* eventmgr, PyTypeObject* T ) : - SCA_ILogicBrick(gameobj,T), - m_triggered(false) + SCA_ILogicBrick(gameobj,T) { m_links = 0; m_suspended = false; m_invert = false; m_level = false; + m_tap = false; m_reset = false; m_pos_ticks = 0; m_neg_ticks = 0; m_pos_pulsemode = false; m_neg_pulsemode = false; m_pulse_frequency = 0; + m_state = false; + m_prev_state = false; m_eventmgr = eventmgr; } @@ -104,9 +106,13 @@ void SCA_ISensor::SetLevel(bool lvl) { m_level = lvl; } +void SCA_ISensor::SetTap(bool tap) { + m_tap = tap; +} + double SCA_ISensor::GetNumber() { - return IsPositiveTrigger(); + return GetState(); } void SCA_ISensor::Suspend() { @@ -143,6 +149,7 @@ void SCA_ISensor::RegisterToManager() { // sensor is just activated, initialize it Init(); + m_state = false; m_newControllers.erase(m_newControllers.begin(), m_newControllers.end()); m_eventmgr->RegisterSensor(this); } @@ -159,11 +166,20 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) // don't evaluate a sensor that is not connected to any controller if (m_links && !m_suspended) { bool result = this->Evaluate(event); + // store the state for the rest of the logic system + m_prev_state = m_state; + m_state = this->IsPositiveTrigger(); if (result) { - logicmgr->AddActivatedSensor(this); - // reset these counters so that pulse are synchronized with transition - m_pos_ticks = 0; - m_neg_ticks = 0; + // the sensor triggered this frame + if (m_state || !m_tap) { + logicmgr->AddActivatedSensor(this); + // reset these counters so that pulse are synchronized with transition + m_pos_ticks = 0; + m_neg_ticks = 0; + } else + { + result = false; + } } else { /* First, the pulsing behaviour, if pulse mode is @@ -172,19 +188,20 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) if (m_pos_pulsemode) { m_pos_ticks++; if (m_pos_ticks > m_pulse_frequency) { - if ( this->IsPositiveTrigger() ) + if ( m_state ) { logicmgr->AddActivatedSensor(this); + result = true; } m_pos_ticks = 0; } } - - if (m_neg_pulsemode) + // negative pulse doesn't make sense in tap mode, skip + if (m_neg_pulsemode && !m_tap) { m_neg_ticks++; if (m_neg_ticks > m_pulse_frequency) { - if (!this->IsPositiveTrigger() ) + if (!m_state ) { logicmgr->AddActivatedSensor(this); } @@ -192,6 +209,21 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) } } } + if (m_tap) + { + // in tap mode: we send always a negative pulse immediately after a positive pulse + if (!result) + { + // the sensor did not trigger on this frame + if (m_prev_state) + { + // but it triggered on previous frame => send a negative pulse + logicmgr->AddActivatedSensor(this); + } + // in any case, absence of trigger means sensor off + m_state = false; + } + } if (!m_newControllers.empty()) { if (!IsActive() && m_level) @@ -221,7 +253,7 @@ const char SCA_ISensor::IsPositive_doc[] = PyObject* SCA_ISensor::PyIsPositive() { ShowDeprecationWarning("isPositive()", "the read-only positive property"); - int retval = IsPositiveTrigger(); + int retval = GetState(); return PyInt_FromLong(retval); } @@ -385,6 +417,7 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset, "\tThe sensor is put in its initial state as if it was just activated.\n") { Init(); + m_prev_state = false; Py_RETURN_NONE; } @@ -458,7 +491,8 @@ PyAttributeDef SCA_ISensor::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("useNegPulseMode",SCA_ISensor,m_neg_pulsemode), KX_PYATTRIBUTE_INT_RW("frequency",0,100000,true,SCA_ISensor,m_pulse_frequency), KX_PYATTRIBUTE_BOOL_RW("invert",SCA_ISensor,m_invert), - KX_PYATTRIBUTE_BOOL_RW("level",SCA_ISensor,m_level), + KX_PYATTRIBUTE_BOOL_RW_CHECK("level",SCA_ISensor,m_level,pyattr_check_level), + KX_PYATTRIBUTE_BOOL_RW_CHECK("tap",SCA_ISensor,m_tap,pyattr_check_tap), KX_PYATTRIBUTE_RO_FUNCTION("triggered", SCA_ISensor, pyattr_get_triggered), KX_PYATTRIBUTE_RO_FUNCTION("positive", SCA_ISensor, pyattr_get_positive), //KX_PYATTRIBUTE_TODO("links"), @@ -493,7 +527,23 @@ PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_D PyObject* SCA_ISensor::pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_ISensor* self= static_cast(self_v); - return PyInt_FromLong(self->IsPositiveTrigger()); + return PyInt_FromLong(self->GetState()); +} + +int SCA_ISensor::pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_ISensor* self= static_cast(self_v); + if (self->m_level) + self->m_tap = false; + return 0; +} + +int SCA_ISensor::pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_ISensor* self= static_cast(self_v); + if (self->m_tap) + self->m_level = false; + return 0; } /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index e2ceec19b69..7bbef5fef2f 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -43,7 +43,6 @@ class SCA_ISensor : public SCA_ILogicBrick { Py_Header; class SCA_EventManager* m_eventmgr; - bool m_triggered; /** Pulse positive pulses? */ bool m_pos_pulsemode; @@ -66,6 +65,9 @@ class SCA_ISensor : public SCA_ILogicBrick /** detect level instead of edge*/ bool m_level; + /** tap mode */ + bool m_tap; + /** sensor has been reset */ bool m_reset; @@ -75,6 +77,12 @@ class SCA_ISensor : public SCA_ILogicBrick /** number of connections to controller */ int m_links; + /** current sensor state */ + bool m_state; + + /** previous state (for tap option) */ + bool m_prev_state; + /** list of controllers that have just activated this sensor because of a state change */ std::vector m_newControllers; @@ -109,6 +117,7 @@ public: void SetInvert(bool inv); /** set the level detection on or off */ void SetLevel(bool lvl); + void SetTap(bool tap); virtual void RegisterToManager(); virtual void UnregisterToManager(); @@ -121,6 +130,12 @@ public: /** Is this sensor switched off? */ bool IsSuspended(); + /** get the state of the sensor: positive or negative */ + bool GetState() + { + return m_state; + } + /** Resume sensing. */ void Resume(); @@ -158,6 +173,8 @@ public: static PyObject* pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); }; #endif //__SCA_ISENSOR diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index 821d2155d2a..a9ea4272531 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -195,6 +195,9 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval) } } } + if (m_tap) + // special case for tap mode: only generate event for new activation + result = false; } diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index 4643a42a4be..df62f91aaed 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -66,7 +66,7 @@ void SCA_NANDController::Trigger(SCA_LogicManager* logicmgr) !(is==m_linkedsensors.end());is++) { SCA_ISensor* sensor = *is; - if (!sensor->IsPositiveTrigger()) + if (!sensor->GetState()) { sensorresult = true; break; diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index a0e9fcb239c..b87af965a50 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -66,7 +66,7 @@ void SCA_NORController::Trigger(SCA_LogicManager* logicmgr) !(is==m_linkedsensors.end());is++) { SCA_ISensor* sensor = *is; - if (sensor->IsPositiveTrigger()) + if (sensor->GetState()) { sensorresult = false; break; diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 87e6d19d008..7aa58b6c320 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -76,7 +76,7 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr) while ( (!sensorresult) && (!(is==m_linkedsensors.end())) ) { sensor = *is; - if (sensor->IsPositiveTrigger()) sensorresult = true; + if (sensor->GetState()) sensorresult = true; is++; } diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index 947e8b7a68a..9b0fe51c5b8 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -66,7 +66,7 @@ void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr) !(is==m_linkedsensors.end());is++) { SCA_ISensor* sensor = *is; - if (sensor->IsPositiveTrigger()) + if (sensor->GetState()) { if (sensorresult == false) { diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index d9e41c2b27e..9232120075f 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -66,7 +66,7 @@ void SCA_XORController::Trigger(SCA_LogicManager* logicmgr) !(is==m_linkedsensors.end());is++) { SCA_ISensor* sensor = *is; - if (sensor->IsPositiveTrigger()) + if (sensor->GetState()) { if (sensorresult == true) { From 9e8261a13b696708c3f7f7bac83d5aae8ef43fed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 May 2009 05:57:08 +0000 Subject: [PATCH 161/444] Disable importing module python controller scripts at conversion time because it can run BGE functions and crash since the internal state isnt setup yet. face-select mode wasnt working when used with projection paint. --- source/blender/src/drawview.c | 2 +- source/gameengine/Converter/KX_ConvertControllers.cpp | 9 +++++++-- source/gameengine/GameLogic/SCA_PythonController.cpp | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 203c9869022..d6184f42410 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -977,7 +977,7 @@ void backdrawview3d(int test) int m; #endif - if( G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT ); + if( G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || (FACESEL_PAINT_TEST)); else if ((G.f & G_TEXTUREPAINT) && G.scene->toolsettings && (G.scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)); else if(G.obedit && G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)); else { diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp index 79664ca4622..856f3f79588 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.cpp +++ b/source/gameengine/Converter/KX_ConvertControllers.cpp @@ -216,8 +216,13 @@ void BL_ConvertControllers( * gives more pradictable performance for larger scripts */ if(pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) pyctrl->Compile(); - else - pyctrl->Import(); + else { + /* We cant do this because importing runs the script which could end up accessing + * internal BGE functions, this is unstable while we're converting the scene. + * This is a pitty because its useful to see errors at startup but cant help it */ + + // pyctrl->Import(); + } } //done with gamecontroller diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index bf4c2475a64..0e78e03d5af 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -164,6 +164,11 @@ static const char* sPyGetCurrentController__doc__; /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */ PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self) { + if(m_sCurrentController==NULL) + { + PyErr_SetString(PyExc_SystemError, "GameLogic.getCurrentController(), this function is being run outside the python controllers context, or blenders internal state is corrupt."); + return NULL; + } return m_sCurrentController->GetProxy(); } From 2bce9ff1d10a54deffbf0937d5c48b5982f07f2f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 May 2009 21:47:58 +0000 Subject: [PATCH 162/444] DXF export with a single nurbs curve failed --- release/scripts/bpymodules/dxfLibrary.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py index 5390be084ee..f8de376d226 100644 --- a/release/scripts/bpymodules/dxfLibrary.py +++ b/release/scripts/bpymodules/dxfLibrary.py @@ -307,6 +307,7 @@ class PolyLine(_Entity): self.points=points self.org_point=org_point self.flag=flag + self.width= 0.0 # dummy value if self.flag & POLYFACE_MESH: self.polyface=True self.points=points[0] @@ -315,6 +316,8 @@ class PolyLine(_Entity): self.f_count=len(self.faces) elif not self.flag & POLYLINE_3D: self.polyline2d = True + self.polyface = False + self.faces = [] # dummy value if width: if type(width)!='list': width=[width,width] From 4bc6749403f0b59c53637b60f936ddc8e0a66d10 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 May 2009 21:51:54 +0000 Subject: [PATCH 163/444] [#18695] Replace python errors with useful messages when no full python installation is found from Philipp Oeser (lichtwerk) --- release/scripts/3ds_export.py | 12 +++-- release/scripts/DirectX8Exporter.py | 3 +- release/scripts/add_mesh_torus.py | 8 +++- release/scripts/export_dxf.py | 62 +++++++++++++------------ release/scripts/export_fbx.py | 19 ++++---- release/scripts/help_bpy_api.py | 12 +++-- release/scripts/help_getting_started.py | 12 ++++- release/scripts/help_manual.py | 12 ++++- release/scripts/help_release_notes.py | 10 +++- release/scripts/help_tutorials.py | 10 +++- release/scripts/help_web_blender.py | 10 +++- release/scripts/help_web_devcomm.py | 10 +++- release/scripts/help_web_eshop.py | 10 +++- release/scripts/help_web_usercomm.py | 10 +++- release/scripts/lightwave_export.py | 12 ++++- 15 files changed, 147 insertions(+), 65 deletions(-) diff --git a/release/scripts/3ds_export.py b/release/scripts/3ds_export.py index 54e1ea3db33..87680bce1b0 100644 --- a/release/scripts/3ds_export.py +++ b/release/scripts/3ds_export.py @@ -7,7 +7,7 @@ Group: 'Export' Tooltip: 'Export to 3DS file format (.3ds).' """ -__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] +__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] __url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") __version__ = "0.90a" __bpydoc__ = """\ @@ -50,7 +50,10 @@ import Blender import bpy from BPyMesh import getMeshFromObject from BPyObject import getDerivedObjects -import struct +try: + import struct +except: + struct = None # So 3ds max can open files, limit names to 12 in length # this is verry annoying for filenames! @@ -1009,5 +1012,8 @@ def save_3ds(filename): if __name__=='__main__': - Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) + if struct: + Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) + else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") # save_3ds('/test_b.3ds') diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py index b8bdae4de2b..8a0ecaf0eb7 100644 --- a/release/scripts/DirectX8Exporter.py +++ b/release/scripts/DirectX8Exporter.py @@ -45,7 +45,8 @@ from Blender import Types, Object, NMesh, Material,Armature,Mesh from Blender.Mathutils import * from Blender import Draw, BGL from Blender.BGL import * -import math +try: import math +except: math = None global mat_flip,index_list,space,bone_list,mat_dict global anim,flip_norm,swap_zy,flip_z,speed,ticks,no_light,recalc_norm,Bl_norm diff --git a/release/scripts/add_mesh_torus.py b/release/scripts/add_mesh_torus.py index 4f759256497..f2fc53ef275 100644 --- a/release/scripts/add_mesh_torus.py +++ b/release/scripts/add_mesh_torus.py @@ -6,7 +6,8 @@ Group: 'AddMesh' """ import BPyAddMesh import Blender -from math import cos, sin, pi +try: from math import cos, sin, pi +except: math = None def add_torus(PREF_MAJOR_RAD, PREF_MINOR_RAD, PREF_MAJOR_SEG, PREF_MINOR_SEG): Vector = Blender.Mathutils.Vector @@ -61,5 +62,8 @@ def main(): BPyAddMesh.add_mesh_simple('Torus', verts, [], faces) -main() +if math: + main() +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py index 99c6acaceab..84a173c1e7d 100644 --- a/release/scripts/export_dxf.py +++ b/release/scripts/export_dxf.py @@ -94,37 +94,40 @@ ______________________________________________________________ import Blender from Blender import Mathutils, Window, Scene, sys, Draw, Mesh import BPyMessages -import os -import subprocess +try: import os +except: os = None +try: import subprocess +except: subprocess = None +try: import copy +except: copy = None #print os.sys.platform #print dir(os.sys.version) #import dxfLibrary #reload(dxfLibrary) -from dxfLibrary import * - - -#-------- DWG support ------------------------------------------ -extCONV_OK = True -extCONV = 'DConvertCon.exe' -extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) -if not os.path.isfile(extCONV_PATH): - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ -Copy first %s into Blender script directory.|\ -More details in online Help.' %extCONV -else: - if not os.sys.platform.startswith('win'): - # check if Wine installed: - if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): - extCONV_PATH = 'wine %s'%extCONV_PATH - else: - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ -The external DWG-converter (%s) needs Wine installed on your system.|\ -More details in online Help.' %extCONV -#print 'extCONV_PATH = ', extCONV_PATH +if copy and os: + from dxfLibrary import * + #-------- DWG support ------------------------------------------ + extCONV_OK = True + extCONV = 'DConvertCon.exe' + extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) + if not os.path.isfile(extCONV_PATH): + extCONV_OK = False + extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ + Copy first %s into Blender script directory.|\ + More details in online Help.' %extCONV + else: + if not os.sys.platform.startswith('win'): + # check if Wine installed: + if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): + extCONV_PATH = 'wine %s'%extCONV_PATH + else: + extCONV_OK = False + extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ + The external DWG-converter (%s) needs Wine installed on your system.|\ + More details in online Help.' %extCONV + #print 'extCONV_PATH = ', extCONV_PATH @@ -526,7 +529,8 @@ http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf') #----------------------------------------------------- if __name__=='__main__': - #main() - if not copy: - Draw.PupMenu('Error%t|This script requires a full python install') - else: Window.FileSelector(dxf_export_ui, 'EXPORT DXF', sys.makename(ext='.dxf')) \ No newline at end of file + #main() + if copy and os and subprocess: + Window.FileSelector(dxf_export_ui, 'EXPORT DXF', sys.makename(ext='.dxf')) + else: + Draw.PupMenu('Error%t|This script requires a full python install') diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 80b2fea0dd8..65427dcfee6 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -2729,15 +2729,16 @@ def fbx_ui_exit(e,v): GLOBALS['EVENT'] = e def do_help(e,v): - url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' - print 'Trying to open web browser with documentation at this address...' - print '\t' + url - - try: - import webbrowser - webbrowser.open(url) - except: - print '...could not open a browser window.' + url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' + print 'Trying to open web browser with documentation at this address...' + print '\t' + url + + try: + import webbrowser + webbrowser.open(url) + except: + Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation") + print '...could not open a browser window.' diff --git a/release/scripts/help_bpy_api.py b/release/scripts/help_bpy_api.py index 9c3a24af288..e8d77ed8452 100644 --- a/release/scripts/help_bpy_api.py +++ b/release/scripts/help_bpy_api.py @@ -36,6 +36,12 @@ This script opens the user's default web browser at http://www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser -version = str(int(Blender.Get('version'))) -webbrowser.open('http://www.blender.org/documentation/'+ version +'PythonDoc/') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + version = str(int(Blender.Get('version'))) + webbrowser.open('http://www.blender.org/documentation/'+ version +'PythonDoc/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/help_getting_started.py b/release/scripts/help_getting_started.py index a4f6da5cc55..77dda2cf88f 100644 --- a/release/scripts/help_getting_started.py +++ b/release/scripts/help_getting_started.py @@ -38,5 +38,13 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser -webbrowser.open('http://www.blender.org/education-help/tutorials/getting-started/') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender.org/education-help/tutorials/getting-started/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") + + diff --git a/release/scripts/help_manual.py b/release/scripts/help_manual.py index b830975e593..27900040eb4 100644 --- a/release/scripts/help_manual.py +++ b/release/scripts/help_manual.py @@ -36,5 +36,13 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser -webbrowser.open('http://wiki.blender.org/index.php/Manual') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://wiki.blender.org/index.php/Manual') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") + + diff --git a/release/scripts/help_release_notes.py b/release/scripts/help_release_notes.py index 919ec72da3c..870f2391487 100644 --- a/release/scripts/help_release_notes.py +++ b/release/scripts/help_release_notes.py @@ -36,6 +36,12 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender.org/development/release-logs/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") -webbrowser.open('http://www.blender.org/development/release-logs/') diff --git a/release/scripts/help_tutorials.py b/release/scripts/help_tutorials.py index 1fe466560f0..e0cef1abdbf 100644 --- a/release/scripts/help_tutorials.py +++ b/release/scripts/help_tutorials.py @@ -37,5 +37,11 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser -webbrowser.open('http://www.blender.org/education-help/tutorials/') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender.org/education-help/tutorials/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/help_web_blender.py b/release/scripts/help_web_blender.py index db0a78d90f7..2a0f90844ae 100644 --- a/release/scripts/help_web_blender.py +++ b/release/scripts/help_web_blender.py @@ -38,5 +38,11 @@ www.blender.org. # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser -webbrowser.open('http://www.blender.org/') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender.org/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/help_web_devcomm.py b/release/scripts/help_web_devcomm.py index e04a54501f7..46fa2487a89 100644 --- a/release/scripts/help_web_devcomm.py +++ b/release/scripts/help_web_devcomm.py @@ -37,5 +37,11 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import webbrowser -webbrowser.open('http://www.blender.org/community/get-involved/') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender.org/community/get-involved/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/help_web_eshop.py b/release/scripts/help_web_eshop.py index c33849ac419..e40795b3a0d 100644 --- a/release/scripts/help_web_eshop.py +++ b/release/scripts/help_web_eshop.py @@ -37,5 +37,11 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import Blender, webbrowser -webbrowser.open('http://www.blender3d.org/e-shop') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender3d.org/e-shop') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/help_web_usercomm.py b/release/scripts/help_web_usercomm.py index a77a2bb9fef..dda5e42f34e 100644 --- a/release/scripts/help_web_usercomm.py +++ b/release/scripts/help_web_usercomm.py @@ -37,5 +37,11 @@ This script opens the user's default web browser at www.blender.org's # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import webbrowser -webbrowser.open('http://www.blender.org/community/user-community/') +import Blender +try: import webbrowser +except: webbrowser = None + +if webbrowser: + webbrowser.open('http://www.blender.org/community/user-community/') +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/lightwave_export.py b/release/scripts/lightwave_export.py index 115761ec3e0..bbfb9649c69 100644 --- a/release/scripts/lightwave_export.py +++ b/release/scripts/lightwave_export.py @@ -68,8 +68,13 @@ v5.5 format. # ***** END GPL LICENCE BLOCK ***** import Blender -import struct, cStringIO, operator import BPyMesh +try: import struct +except: struct = None +try: import cStringIO +except: cStringIO = None +try: import operator +except: operator = None VCOL_NAME = "\251 Per-Face Vertex Colors" DEFAULT_NAME = "\251 Blender Default" @@ -696,4 +701,7 @@ def fs_callback(filename): if not filename.lower().endswith('.lwo'): filename += '.lwo' write(filename) -Blender.Window.FileSelector(fs_callback, "Export LWO", Blender.sys.makename(ext='.lwo')) +if struct and cStringIO and operator: + Blender.Window.FileSelector(fs_callback, "Export LWO", Blender.sys.makename(ext='.lwo')) +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") From 362202cc14d501484ab62bdd6c638e81bc52981d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 5 May 2009 22:32:15 +0000 Subject: [PATCH 164/444] Fix an undefined variable bug detected by valgrind. --- source/gameengine/SceneGraph/SG_Node.cpp | 3 ++- source/gameengine/SceneGraph/SG_Spatial.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp index c4a1b151846..4cd43e852b8 100644 --- a/source/gameengine/SceneGraph/SG_Node.cpp +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -46,6 +46,7 @@ SG_Node::SG_Node( : SG_Spatial(clientobj,clientinfo,callbacks), m_SGparent(NULL) { + m_modified = true; } SG_Node::SG_Node( @@ -55,7 +56,7 @@ SG_Node::SG_Node( m_children(other.m_children), m_SGparent(other.m_SGparent) { - // nothing to do + m_modified = true; } SG_Node::~SG_Node() diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index 97b15bdf376..b79d4bac91a 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -58,7 +58,6 @@ SG_Spatial( m_radius(1.0), m_modified(false) { - SetModified(); } SG_Spatial:: From 31b52cf95365ea08ac46987700f08e893d1ccb7f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 5 May 2009 23:15:31 +0000 Subject: [PATCH 165/444] Bugfix: Data from hidden objects was still being taken into account for many NLA-editor operations NOTE for Merging - do not port this commit, since the changes here are utterly irrelevant to the new system --- source/blender/src/editnla.c | 22 +++++++++++++++++++--- source/blender/src/transform_conversions.c | 9 +++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c index 179ea41d5ad..3127f0e5072 100644 --- a/source/blender/src/editnla.c +++ b/source/blender/src/editnla.c @@ -927,7 +927,11 @@ void deselect_nlachannel_keys (int test) /* Determine if this is selection or deselection */ if (test){ - for (base=G.scene->base.first; base && sel; base=base->next){ + for (base=G.scene->base.first; base && sel; base=base->next){ + /* only consider if visible */ + if (nla_filter(base) == 0) + continue; + /* Test object ipos */ if (is_ipo_key_selected(base->object->ipo)){ sel = 0; @@ -986,7 +990,11 @@ void deselect_nlachannel_keys (int test) /* Set the flags */ - for (base=G.scene->base.first; base; base=base->next){ + for (base=G.scene->base.first; base; base=base->next){ + /* only consider if visible */ + if (nla_filter(base) == 0) + continue; + /* Set the object ipos */ set_ipo_key_selection(base->object->ipo, sel); @@ -1068,6 +1076,10 @@ void delete_nlachannel_keys(void) bActionStrip *strip, *nextstrip; for (base = G.scene->base.first; base; base=base->next){ + /* only consider if visible */ + if (nla_filter(base) == 0) + continue; + /* Delete object ipos */ delete_ipo_keys(base->object->ipo); @@ -1122,7 +1134,11 @@ void duplicate_nlachannel_keys(void) bActionStrip *strip, *laststrip; /* Find selected items */ - for (base = G.scene->base.first; base; base=base->next){ + for (base = G.scene->base.first; base; base=base->next){ + /* only consider if visible */ + if (nla_filter(base) == 0) + continue; + /* Duplicate object keys */ duplicate_ipo_keys(base->object->ipo); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 76f315cde04..2eab0bc9730 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -120,6 +120,7 @@ #include "BSE_view.h" #include "BSE_drawipo.h" +#include "BSE_drawnla.h" // nla_filter() #include "BSE_edit.h" #include "BSE_editipo.h" #include "BSE_editipo_types.h" @@ -3132,6 +3133,10 @@ static void createTransNlaData(TransInfo *t) /* Ensure that partial selections result in beztriple selections */ for (base=G.scene->base.first; base; base=base->next) { + /* only consider if visible */ + if (nla_filter(base) == 0) + continue; + /* Check object ipos */ i= count_ipo_keys(base->object->ipo, side, (float)CFRA); if (i) base->flag |= BA_HAS_RECALC_OB; @@ -3197,6 +3202,10 @@ static void createTransNlaData(TransInfo *t) /* build the transdata structure */ td= t->data; for (base=G.scene->base.first; base; base=base->next) { + /* only consider if visible */ + if (nla_filter(base) == 0) + continue; + /* Manipulate object ipos */ /* - no scaling of keyframe times is allowed here */ td= IpoToTransData(td, base->object->ipo, NULL, side, (float)CFRA); From 013afe4314dbda5345d52abc84938fabd51a86b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 01:41:04 +0000 Subject: [PATCH 166/444] [#18690] mesh ripping allowed on multires also fixed uninitialized variable use in the BGE when shaders are not supported. --- source/blender/src/editmesh_tools.c | 2 ++ source/gameengine/Rasterizer/RAS_2DFilterManager.cpp | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 377cb42e2f5..0fb072c1af4 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -5624,6 +5624,8 @@ void mesh_rip(void) float projectMat[4][4], viewMat[4][4], vec[3], dist, mindist; short doit= 1, mval[2],propmode,prop; + if(multires_test()) return; + propmode = G.scene->prop_mode; G.scene->prop_mode = 0; prop = G.scene->proportional; diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 176da51b183..239031866ca 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -63,11 +63,9 @@ numberoffilters(0), need_tex_update(true) isshadersupported = GLEW_ARB_shader_objects && GLEW_ARB_fragment_shader && GLEW_ARB_multitexture; + /* used to return before 2.49 but need to initialize values so dont */ if(!isshadersupported) - { std::cout<<"shaders not supported!" << std::endl; - return; - } int passindex; for(passindex =0; passindex Date: Wed, 6 May 2009 02:19:16 +0000 Subject: [PATCH 167/444] dxfLibrary.py - modif in POLYLINE class --- release/scripts/bpymodules/dxfLibrary.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py index f8de376d226..55907e03bc1 100644 --- a/release/scripts/bpymodules/dxfLibrary.py +++ b/release/scripts/bpymodules/dxfLibrary.py @@ -307,7 +307,10 @@ class PolyLine(_Entity): self.points=points self.org_point=org_point self.flag=flag - self.width= 0.0 # dummy value + self.polyface = False + self.polyline2d = False + self.faces = [] # dummy value + self.width= None # dummy value if self.flag & POLYFACE_MESH: self.polyface=True self.points=points[0] @@ -316,8 +319,6 @@ class PolyLine(_Entity): self.f_count=len(self.faces) elif not self.flag & POLYLINE_3D: self.polyline2d = True - self.polyface = False - self.faces = [] # dummy value if width: if type(width)!='list': width=[width,width] @@ -332,7 +333,7 @@ class PolyLine(_Entity): result+=' 71\n%s\n' %self.p_count result+=' 72\n%s\n' %self.f_count elif self.polyline2d: - if self.width: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) + if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) for point in self.points: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer From de4f811b4b1291f6c44d709de591086032a10fe7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 04:24:01 +0000 Subject: [PATCH 168/444] - Export hard edge and face info - Use Edges field rather then 2 vert faces (worked in some apps but crashed maya) --- release/scripts/export_fbx.py | 61 +++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 65427dcfee6..47197b7cdff 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -1,13 +1,13 @@ #!BPY """ Name: 'Autodesk FBX (.fbx)...' -Blender: 244 +Blender: 249 Group: 'Export' Tooltip: 'Selection to an ASCII Autodesk FBX ' """ __author__ = "Campbell Barton" __url__ = ['www.blender.org', 'blenderartists.org'] -__version__ = "1.1" +__version__ = "1.2" __bpydoc__ = """\ This script is an exporter to the FBX file format. @@ -1385,22 +1385,18 @@ def write(filename, batch_objects = None, \ else: file.write(',%i,%i,%i,%i' % fi ) i+=1 - ed_val = [None, None] - LOOSE = Blender.Mesh.EdgeFlags.LOOSE + file.write('\n\t\tEdges: ') + i=-1 for ed in me.edges: - if ed.flag & LOOSE: - ed_val[0] = ed.v1.index - ed_val[1] = -(ed.v2.index+1) if i==-1: - file.write('%i,%i' % tuple(ed_val) ) + file.write('%i,%i' % (ed.v1.index, ed.v2.index)) i=0 else: if i==13: file.write('\n\t\t') i=0 - file.write(',%i,%i' % tuple(ed_val) ) + file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) i+=1 - del LOOSE file.write('\n\t\tGeometryVersion: 124') @@ -1423,6 +1419,51 @@ def write(filename, batch_objects = None, \ i+=1 file.write('\n\t\t}') + # Write Face Smoothing + file.write(''' + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "Direct" + Smoothing: ''') + + i=-1 + for f in me.faces: + if i==-1: + file.write('%i' % f.smooth); i=0 + else: + if i==54: + file.write('\n '); i=0 + file.write(',%i' % f.smooth) + i+=1 + + file.write('\n\t\t}') + + # Write Edge Smoothing + file.write(''' + LayerElementSmoothing: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: ''') + + SHARP = Blender.Mesh.EdgeFlags.SHARP + i=-1 + for ed in me.edges: + if i==-1: + file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 + else: + if i==54: + file.write('\n '); i=0 + file.write(',%i' % ((ed.flag&SHARP)!=0)) + i+=1 + + file.write('\n\t\t}') + del SHARP + + # Write VertexColor Layers # note, no programs seem to use this info :/ collayers = [] From 899c6695571cb4a9e4dbc28cfbf5cb9bede17d60 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 06:01:09 +0000 Subject: [PATCH 169/444] [#18328] FBX exporter not exporting multi-texture materials properly even though the format allows materials and textures to be written separately the textures wont load right in maya or 3dsmax unless each texture has its own material. --- release/scripts/export_fbx.py | 118 ++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 41 deletions(-) diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 47197b7cdff..0a38d63049d 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -93,8 +93,8 @@ def copy_images(dest_dir, textures): dest_dir += Blender.sys.sep image_paths = set() - for img in textures: - image_paths.add(Blender.sys.expandpath(img.filename)) + for tex in textures: + image_paths.add(Blender.sys.expandpath(tex.filename)) # Now copy images copyCount = 0 @@ -157,14 +157,29 @@ def increment_string(t): # todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up. def sane_name(data, dct): #if not data: return None - name = data.name + + if type(data)==tuple: # materials are paired up with images + data, other = data + use_other = True + else: + other = None + use_other = False + + if data: name = data.name + else: name = None + orig_name = name + + if other: + orig_name_other = other.name + name = '%s #%s' % (name, orig_name_other) + else: + orig_name_other = None # dont cache, only ever call once for each data type now, # so as to avoid namespace collision between types - like with objects <-> bones #try: return dct[name] #except: pass - orig_name = name if not name: name = 'unnamed' # blank string, ASKING FOR TROUBLE! else: @@ -173,7 +188,11 @@ def sane_name(data, dct): while name in dct.itervalues(): name = increment_string(name) - dct[orig_name] = name + if use_other: # even if other is None - orig_name_other will be a string or None + dct[orig_name, orig_name_other] = name + else: + dct[orig_name] = name + return name def sane_obname(data): return sane_name(data, sane_name_mapping_ob) @@ -1333,11 +1352,13 @@ def write(filename, batch_objects = None, \ me = my_mesh.blenData # if there are non NULL materials on this mesh - if [mat for mat in my_mesh.blenMaterials if mat]: do_materials = True - else: do_materials = False + if my_mesh.blenMaterials: do_materials = True + else: do_materials = False if my_mesh.blenTextures: do_textures = True - else: do_textures = False + else: do_textures = False + + do_uvs = me.faceUV file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) @@ -1516,7 +1537,7 @@ def write(filename, batch_objects = None, \ # Write UV and texture layers. uvlayers = [] - if me.faceUV: + if do_uvs: uvlayers = me.getUVLayerNames() uvlayer_orig = me.activeUVLayer for uvindex, uvlayer in enumerate(uvlayers): @@ -1635,32 +1656,32 @@ def write(filename, batch_objects = None, \ file.write('0') else: # Build a material mapping for this - #material_mapping_local = [0] * 16 # local-index : global index. - material_mapping_local = [-1] * 16 # local-index : global index. - i= 0 # 1 - for j, mat in enumerate(my_mesh.blenMaterials): - if mat: - material_mapping_local[j] = i - i+=1 - # else leave as -1 + material_mapping_local = {} # local-mat & tex : global index. + + for j, mat_tex_pair in enumerate(my_mesh.blenMaterials): + material_mapping_local[mat_tex_pair] = j len_material_mapping_local = len(material_mapping_local) + mats = my_mesh.blenMaterialList + i=-1 for f in me.faces: - f_mat = f.mat - if f_mat >= len_material_mapping_local: - f_mat = 0 + try: mat = mats[f.mat] + except:mat = None + + if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ + else: tex = None if i==-1: i=0 - file.write( '%s' % (material_mapping_local[f_mat])) + file.write( '%s' % (material_mapping_local[mat, tex])) # None for mat or tex is ok else: if i==55: file.write('\n\t\t\t\t') i=0 - file.write(',%s' % (material_mapping_local[f_mat])) + file.write(',%s' % (material_mapping_local[mat, tex])) i+=1 file.write('\n\t\t}') @@ -1695,7 +1716,7 @@ def write(filename, batch_objects = None, \ TypedIndex: 0 }''') - if me.faceUV: + if do_uvs: # same as me.faceUV file.write(''' LayerElement: { Type: "LayerElementUV" @@ -1777,8 +1798,8 @@ def write(filename, batch_objects = None, \ ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null] groups = [] # blender groups, only add ones that have objects in the selections - materials = {} - textures = {} + materials = {} # (mat, image) keys, should be a set() + textures = {} # should be a set() tmp_ob_type = ob_type = None # incase no objects are exported, so as not to raise an error @@ -1878,20 +1899,29 @@ def write(filename, batch_objects = None, \ if EXP_MESH_HQ_NORMALS: BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines. - for mat in mats: - # 2.44 use mat.lib too for uniqueness - if mat: materials[mat] = mat - texture_mapping_local = {} + material_mapping_local = {} if me.faceUV: uvlayer_orig = me.activeUVLayer for uvlayer in me.getUVLayerNames(): me.activeUVLayer = uvlayer for f in me.faces: - img = f.image - textures[img] = texture_mapping_local[img] = img + tex = f.image + textures[tex] = texture_mapping_local[tex] = None + + try: mat = mats[f.mat] + except: mat = None + + materials[mat, tex] = material_mapping_local[mat, tex] = None # should use sets, wait for blender 2.5 + me.activeUVLayer = uvlayer_orig + else: + for mat in mats: + # 2.44 use mat.lib too for uniqueness + materials[mat, None] = material_mapping_local[mat, None] = None + else: + materials[None, None] = None if EXP_ARMATURE: armob = BPyObject.getObjectArmature(ob) @@ -1912,8 +1942,9 @@ def write(filename, batch_objects = None, \ my_mesh = my_object_generic(ob, mtx) my_mesh.blenData = me my_mesh.origData = origData - my_mesh.blenMaterials = mats - my_mesh.blenTextures = texture_mapping_local.values() + my_mesh.blenMaterials = material_mapping_local.keys() + my_mesh.blenMaterialList = mats + my_mesh.blenTextures = texture_mapping_local.keys() # if only 1 null texture then empty the list if len(my_mesh.blenTextures) == 1 and my_mesh.blenTextures[0] == None: @@ -2032,8 +2063,8 @@ def write(filename, batch_objects = None, \ # Finished finding groups we use - materials = [(sane_matname(mat), mat) for mat in materials.itervalues() if mat] - textures = [(sane_texname(img), img) for img in textures.itervalues() if img] + materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.iterkeys()] + textures = [(sane_texname(tex), tex) for tex in textures.iterkeys() if tex] materials.sort() # sort by name textures.sort() @@ -2162,8 +2193,8 @@ Objects: {''') write_camera_default() - for matname, mat in materials: - write_material(matname, mat) + for matname, (mat, tex) in materials: + write_material(matname, mat) # We only need to have a material per image pair, but no need to write any image info into the material (dumb fbx standard) # each texture uses a video, odd for texname, tex in textures: @@ -2283,7 +2314,7 @@ Relations: {''') Model: "Model::Camera Switcher", "CameraSwitcher" { }''') - for matname, mat in materials: + for matname, (mat, tex) in materials: file.write('\n\tMaterial: "Material::%s", "" {\n\t}' % matname) if textures: @@ -2335,9 +2366,14 @@ Connections: {''') if materials: for my_mesh in ob_meshes: # Connect all materials to all objects, not good form but ok for now. - for mat in my_mesh.blenMaterials: - if mat: - file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat.name], my_mesh.fbxName)) + for mat, tex in my_mesh.blenMaterials: + if mat: mat_name = mat.name + else: mat_name = None + + if tex: tex_name = tex.name + else: tex_name = None + + file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat_name, tex_name], my_mesh.fbxName)) if textures: for my_mesh in ob_meshes: From 25b415f310bd181671f11afbe9d9b0ab899a87ec Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 6 May 2009 08:33:40 +0000 Subject: [PATCH 170/444] Fix for [#18697] 2.49RC1: Keyed Particles fine in viewport but give me a crash during render --- source/blender/blenkernel/intern/particle_system.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index bbf62d033bf..d3ba3fa3802 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2007,7 +2007,6 @@ static void set_keyed_keys(Object *ob, ParticleSystem *psys) Object *kob = ob; ParticleSystem *kpsys = psys; ParticleData *pa; - ParticleKey state; int totpart = psys->totpart, i, k, totkeys = psys->totkeyed + 1; float prevtime, nexttime, keyedtime; @@ -2031,10 +2030,11 @@ static void set_keyed_keys(Object *ob, ParticleSystem *psys) } psys->flag &= ~PSYS_KEYED; - state.time=-1.0; for(k=0; kparticles; ikeys + k)->time = -1.0; /* use current time */ + if(kpsys->totpart > 0) psys_get_particle_state(kob, kpsys, i%kpsys->totpart, pa->keys + k, 1); From c1e1091f027e2d1b8a84ff5595e9a85b092f1b88 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 09:12:08 +0000 Subject: [PATCH 171/444] moved py controller functions from SCA_PythonController to SCA_IController - the base controller class so python can get the sensors & actuators from any controller (not just SCA_PythonController types) also deprecated getActuators() and getSensors() for 'sensors' and 'actuators' attributes. an example of getting every sensor connected to an object. all_sensors = [s for c in ob.controllers for s in c.sensors] --- .../blender/python/api2_2x/doc/Mathutils.py | 8 +- .../gameengine/GameLogic/SCA_IController.cpp | 174 ++++++++++++++++++ source/gameengine/GameLogic/SCA_IController.h | 17 +- .../GameLogic/SCA_PythonController.cpp | 115 +----------- .../GameLogic/SCA_PythonController.h | 9 +- .../gameengine/Ketsji/KX_PythonInitTypes.cpp | 5 +- source/gameengine/PyDoc/GameLogic.py | 6 +- source/gameengine/PyDoc/KX_SceneActuator.py | 2 +- source/gameengine/PyDoc/SCA_IController.py | 52 ++++++ .../gameengine/PyDoc/SCA_PythonController.py | 42 +---- 10 files changed, 266 insertions(+), 164 deletions(-) diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index fc0c4ed10fa..7ca10c53d02 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -440,7 +440,7 @@ class Vector: Example:: wrappedObject = Object.getAttribute() #this is wrapped data print wrappedObject.wrapped #prints 'True' - copyOfObject = Object(wrappedObject) #creates a copy of the object + copyOfObject = wrappedObject.copy() #creates a copy of the object secondPointer = wrappedObject #creates a second pointer to the same data print wrappedObject.attribute #prints '5' secondPointer.attribute = 10 @@ -564,7 +564,7 @@ class Euler: Example:: wrappedObject = Object.getAttribute() #this is wrapped data print wrappedObject.wrapped #prints 'True' - copyOfObject = Object(wrappedObject) #creates a copy of the object + copyOfObject = wrappedObject.copy() #creates a copy of the object secondPointer = wrappedObject #creates a second pointer to the same data print wrappedObject.attribute #prints '5' secondPointer.attribute = 10 @@ -652,7 +652,7 @@ class Quaternion: Example:: wrappedObject = Object.getAttribute() #this is wrapped data print wrappedObject.wrapped #prints 'True' - copyOfObject = Object(wrappedObject) #creates a copy of the object + copyOfObject = wrappedObject.copy() #creates a copy of the object secondPointer = wrappedObject #creates a second pointer to the same data print wrappedObject.attribute #prints '5' secondPointer.attribute = 10 @@ -760,7 +760,7 @@ class Matrix: Example:: wrappedObject = Object.getAttribute() #this is wrapped data print wrappedObject.wrapped #prints 'True' - copyOfObject = Object(wrappedObject) #creates a copy of the object + copyOfObject = wrappedObject.copy() #creates a copy of the object secondPointer = wrappedObject #creates a second pointer to the same data print wrappedObject.attribute #prints '5' secondPointer.attribute = 10 diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index f9c192cae5c..8bf21ed8264 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -30,6 +30,7 @@ #include "SCA_LogicManager.h" #include "SCA_IActuator.h" #include "SCA_ISensor.h" +#include "PyObjectPlus.h" #ifdef HAVE_CONFIG_H #include @@ -207,3 +208,176 @@ void SCA_IController::ApplyState(unsigned int state) } } +/* Python api */ + +PyTypeObject SCA_IController::Type = { +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif + "SCA_IController", + sizeof(PyObjectPlus_Proxy), + 0, + py_base_dealloc, + 0, + 0, + 0, + 0, + py_base_repr, + 0,0,0,0,0,0, + py_base_getattro, + py_base_setattro, + 0,0,0,0,0,0,0,0,0, + Methods +}; + +PyParentObject SCA_IController::Parents[] = { + &SCA_IController::Type, + &CValue::Type, + NULL +}; + +PyMethodDef SCA_IController::Methods[] = { + {"getActuator", (PyCFunction) SCA_IController::sPyGetActuator, METH_O}, + {"getSensor", (PyCFunction) SCA_IController::sPyGetSensor, METH_O}, + + //Deprecated functions ------> + {"getSensors", (PyCFunction) SCA_IController::sPyGetSensors, METH_NOARGS}, + {"getActuators", (PyCFunction) SCA_IController::sPyGetActuators, METH_NOARGS}, + {"getState", (PyCFunction) SCA_IController::sPyGetState, METH_NOARGS}, + //<----- Deprecated + {NULL,NULL} //Sentinel +}; + +PyAttributeDef SCA_IController::Attributes[] = { + KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state), + KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors), + KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators), + { NULL } //Sentinel +}; + +PyObject* SCA_IController::py_getattro(PyObject *attr) +{ + py_getattro_up(SCA_ILogicBrick); +} + +PyObject* SCA_IController::py_getattro_dict() { + py_getattro_dict_up(SCA_ILogicBrick); +} + +int SCA_IController::py_setattro(PyObject *attr, PyObject *value) +{ + py_setattro_up(SCA_ILogicBrick); +} + + + +PyObject* SCA_IController::PyGetActuators() +{ + ShowDeprecationWarning("getActuators()", "the actuators property"); + + PyObject* resultlist = PyList_New(m_linkedactuators.size()); + for (unsigned int index=0;indexGetProxy()); + } + + return resultlist; +} + +PyObject* SCA_IController::PyGetSensor(PyObject* value) +{ + + char *scriptArg = PyString_AsString(value); + if (scriptArg==NULL) { + PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)"); + return NULL; + } + + for (unsigned int index=0;indexGetName(); + if (realname == scriptArg) + { + return sensor->GetProxy(); + } + } + + PyErr_Format(PyExc_AttributeError, "controller.getSensor(string): Python Controller, unable to find requested sensor \"%s\"", scriptArg); + return NULL; +} + +PyObject* SCA_IController::PyGetActuator(PyObject* value) +{ + + char *scriptArg = PyString_AsString(value); + if (scriptArg==NULL) { + PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)"); + return NULL; + } + + for (unsigned int index=0;indexGetName() == scriptArg) + { + return actua->GetProxy(); + } + } + + PyErr_Format(PyExc_AttributeError, "controller.getActuator(string): Python Controller, unable to find requested actuator \"%s\"", scriptArg); + return NULL; +} + +PyObject* SCA_IController::PyGetSensors() +{ + ShowDeprecationWarning("getSensors()", "the sensors property"); + + PyObject* resultlist = PyList_New(m_linkedsensors.size()); + for (unsigned int index=0;indexGetProxy()); + } + + return resultlist; +} + +PyObject* SCA_IController::PyGetState() +{ + ShowDeprecationWarning("getState()", "the state property"); + return PyInt_FromLong(m_statemask); +} + +PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_IController* self= static_cast(self_v); + return PyInt_FromLong(self->m_statemask); +} + +PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_IController* self= static_cast(self_v); + vector linkedsensors = self->GetLinkedSensors(); + PyObject* resultlist = PyList_New(linkedsensors.size()); + + for (unsigned int index=0;indexGetProxy()); + + return resultlist; +} + +PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_IController* self= static_cast(self_v); + vector linkedactuators = self->GetLinkedActuators(); + PyObject* resultlist = PyList_New(linkedactuators.size()); + + for (unsigned int index=0;indexGetProxy()); + + return resultlist; +} diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index f67c0942eb4..7ed83bc90b8 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -30,9 +30,11 @@ #define __KX_ICONTROLLER #include "SCA_ILogicBrick.h" +#include "PyObjectPlus.h" class SCA_IController : public SCA_ILogicBrick { + Py_Header; protected: std::vector m_linkedsensors; std::vector m_linkedactuators; @@ -51,7 +53,20 @@ public: void UnlinkSensor(class SCA_ISensor* sensor); void SetState(unsigned int state) { m_statemask = state; } void ApplyState(unsigned int state); - + + virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); + virtual int py_setattro(PyObject *attr, PyObject *value); + + KX_PYMETHOD_NOARGS(SCA_IController,GetSensors); + KX_PYMETHOD_NOARGS(SCA_IController,GetActuators); + KX_PYMETHOD_O(SCA_IController,GetSensor); + KX_PYMETHOD_O(SCA_IController,GetActuator); + KX_PYMETHOD_NOARGS(SCA_IController,GetState); + + static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); }; diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 0e78e03d5af..063a7b47321 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -157,10 +157,6 @@ int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor) return 0; } -#if 0 -static const char* sPyGetCurrentController__doc__; -#endif - /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */ PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self) { @@ -189,7 +185,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) } } else if (BGE_PROXY_CHECK_TYPE(value)) { - PyObjectPlus *value_plus= BGE_PROXY_REF(value); /* Expecting an actuator type */ // XXX TODO - CHECK TYPE + PyObjectPlus *value_plus= BGE_PROXY_REF(value); for(it = lacts.begin(); it!= lacts.end(); it++) { if( static_cast(value_plus) == (*it) ) { return *it; @@ -205,13 +201,11 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) return false; } -#if 0 -static const char* sPyAddActiveActuator__doc__; -#endif - /* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */ PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* args) { + ShowDeprecationWarning("GameLogic.addActiveActuator(act, bool)", "controller.activate(act) or controller.deactivate(act)"); + PyObject* ob1; int activate; if (!PyArg_ParseTuple(args, "Oi:addActiveActuator", &ob1,&activate)) @@ -227,10 +221,8 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* a Py_RETURN_NONE; } - const char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()"; const char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuator(actuator,bool)"; -const char SCA_PythonController::GetActuators_doc[] = "getActuator"; PyTypeObject SCA_PythonController::Type = { #if (PY_VERSION_HEX >= 0x02060000) @@ -266,20 +258,14 @@ PyMethodDef SCA_PythonController::Methods[] = { {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O}, {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O}, - {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetActuators_doc}, - {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator, METH_O, (PY_METHODCHAR)SCA_PythonController::GetActuator_doc}, - {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetSensors_doc}, - {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor, METH_O, (PY_METHODCHAR)SCA_PythonController::GetSensor_doc}, //Deprecated functions ------> {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O}, {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS}, - {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_NOARGS}, //<----- Deprecated {NULL,NULL} //Sentinel }; PyAttributeDef SCA_PythonController::Attributes[] = { - KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_PythonController, pyattr_get_state), KX_PYATTRIBUTE_RW_FUNCTION("script", SCA_PythonController, pyattr_get_script, pyattr_set_script), { NULL } //Sentinel }; @@ -498,6 +484,10 @@ PyObject* SCA_PythonController::py_getattro(PyObject *attr) py_getattro_up(SCA_IController); } +PyObject* SCA_PythonController::py_getattro_dict() { + py_getattro_dict_up(SCA_IController); +} + int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value) { py_setattro_up(SCA_IController); @@ -527,84 +517,6 @@ PyObject* SCA_PythonController::PyDeActivate(PyObject *value) Py_RETURN_NONE; } -PyObject* SCA_PythonController::PyGetActuators() -{ - PyObject* resultlist = PyList_New(m_linkedactuators.size()); - for (unsigned int index=0;indexGetProxy()); - } - - return resultlist; -} - -const char SCA_PythonController::GetSensor_doc[] = -"getSensor (char sensorname) return linked sensor that is named [sensorname]\n"; -PyObject* -SCA_PythonController::PyGetSensor(PyObject* value) -{ - - char *scriptArg = PyString_AsString(value); - if (scriptArg==NULL) { - PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)"); - return NULL; - } - - for (unsigned int index=0;indexGetName(); - if (realname == scriptArg) - { - return sensor->GetProxy(); - } - } - - PyErr_Format(PyExc_AttributeError, "controller.getSensor(string): Python Controller, unable to find requested sensor \"%s\"", scriptArg); - return NULL; -} - - - -const char SCA_PythonController::GetActuator_doc[] = -"getActuator (char sensorname) return linked actuator that is named [actuatorname]\n"; -PyObject* -SCA_PythonController::PyGetActuator(PyObject* value) -{ - - char *scriptArg = PyString_AsString(value); - if (scriptArg==NULL) { - PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)"); - return NULL; - } - - for (unsigned int index=0;indexGetName() == scriptArg) - { - return actua->GetProxy(); - } - } - - PyErr_Format(PyExc_AttributeError, "controller.getActuator(string): Python Controller, unable to find requested actuator \"%s\"", scriptArg); - return NULL; -} - - -const char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors"; -PyObject* -SCA_PythonController::PyGetSensors() -{ - PyObject* resultlist = PyList_New(m_linkedsensors.size()); - for (unsigned int index=0;indexGetProxy()); - } - - return resultlist; -} - /* 1. getScript */ PyObject* SCA_PythonController::PyGetScript() { @@ -632,19 +544,6 @@ PyObject* SCA_PythonController::PySetScript(PyObject* value) Py_RETURN_NONE; } -/* 1. getScript */ -PyObject* SCA_PythonController::PyGetState() -{ - ShowDeprecationWarning("getState()", "the state property"); - return PyInt_FromLong(m_statemask); -} - -PyObject* SCA_PythonController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ - SCA_PythonController* self= static_cast(self_v); - return PyInt_FromLong(self->m_statemask); -} - PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_PythonController* self= static_cast(self_v); diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 587e6264d8c..0c2af79c3a3 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -96,21 +96,18 @@ class SCA_PythonController : public SCA_IController static PyObject* sPyAddActiveActuator(PyObject* self, PyObject* args); static SCA_IActuator* LinkedActuatorFromPy(PyObject *value); + virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); KX_PYMETHOD_O(SCA_PythonController,Activate); KX_PYMETHOD_O(SCA_PythonController,DeActivate); - KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetSensors); - KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetActuators); - KX_PYMETHOD_DOC_O(SCA_PythonController,GetSensor); - KX_PYMETHOD_DOC_O(SCA_PythonController,GetActuator); KX_PYMETHOD_O(SCA_PythonController,SetScript); KX_PYMETHOD_NOARGS(SCA_PythonController,GetScript); - KX_PYMETHOD_NOARGS(SCA_PythonController,GetState); + - static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index dcd11b551a1..cd21663f41d 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -84,6 +84,7 @@ #include "SCA_PropertySensor.h" #include "SCA_PythonController.h" #include "SCA_RandomActuator.h" +#include "SCA_IController.h" void initPyObjectPlusType(PyTypeObject **parents) @@ -225,9 +226,7 @@ void initPyTypes(void) PyType_Ready_Attr(dict, SCA_RandomSensor); PyType_Ready_Attr(dict, SCA_XNORController); PyType_Ready_Attr(dict, SCA_XORController); - - - + PyType_Ready_Attr(dict, SCA_IController); } #endif \ No newline at end of file diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 708dc29f137..d16c00ca272 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -59,7 +59,7 @@ Documentation for the GameLogic Module. actuator = co.getActuator("actuatorname") # Activate an actuator - GameLogic.addActiveActuator(actuator, True) + controller.activate(actuator) See the actuator's reference for available methods: - L{2DFilterActuator} @@ -307,6 +307,8 @@ KX_SCENE_RESUME: See L{KX_SceneActuator} @var VIEWMATRIX_INVERSE: @var VIEWMATRIX_INVERSETRANSPOSE: @var VIEWMATRIX_TRANSPOSE: + +@group Deprecated: addActiveActuator """ # TODO @@ -335,7 +337,7 @@ def getSceneList(): """ def addActiveActuator(actuator, activate): """ - Activates the given actuator. + Activates the given actuator. (B{deprecated}) @type actuator: L{SCA_IActuator} or the actuator name as a string. @type activate: boolean diff --git a/source/gameengine/PyDoc/KX_SceneActuator.py b/source/gameengine/PyDoc/KX_SceneActuator.py index 8e806c2c50e..937c94c91e6 100644 --- a/source/gameengine/PyDoc/KX_SceneActuator.py +++ b/source/gameengine/PyDoc/KX_SceneActuator.py @@ -20,7 +20,7 @@ class KX_SceneActuator(SCA_IActuator): @type camera: L{KX_Camera} on read, string or L{KX_Camera} on write @ivar useRestart: Set flag to True to restart the sene @type useRestart: bool - @type mode: The mode of the actuator + @ivar mode: The mode of the actuator @type mode: int from 0 to 5 L{GameLogic.Scene Actuator} """ def setUseRestart(flag): diff --git a/source/gameengine/PyDoc/SCA_IController.py b/source/gameengine/PyDoc/SCA_IController.py index f83e7c97dce..3e6ee45e115 100644 --- a/source/gameengine/PyDoc/SCA_IController.py +++ b/source/gameengine/PyDoc/SCA_IController.py @@ -5,5 +5,57 @@ from SCA_ILogicBrick import * class SCA_IController(SCA_ILogicBrick): """ Base class for all controller logic bricks. + + @ivar state: the controllers state bitmask. + This can be used with the GameObject's state to test if the controller is active. + @type state: int bitmask + @ivar sensors: a list of sensors linked to this controller + - note: the sensors are not necessarily owned by the same object. + - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. + @type sensors: list + @ivar actuators: a list of actuators linked to this controller. + - note: the sensors are not necessarily owned by the same object. + - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. + @type actuators: list + + @group Deprecated: getState, getSensors, getActuators """ + def getState(): + """ + DEPRECATED: use the state property + Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. + This for instance will always be true however you could compare with a previous state to see when the state was activated. + GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState() + + @rtype: int + """ + def getSensors(): + """ + DEPRECATED: use the sensors property + Gets a list of all sensors attached to this controller. + + @rtype: list [L{SCA_ISensor}] + """ + def getSensor(name): + """ + Gets the named linked sensor. + + @type name: string + @rtype: L{SCA_ISensor} + """ + def getActuators(): + """ + DEPRECATED: use the actuators property + Gets a list of all actuators linked to this controller. + + @rtype: list [L{SCA_IActuator}] + """ + def getActuator(name): + """ + Gets the named linked actuator. + + @type name: string + @rtype: L{SCA_IActuator} + """ + \ No newline at end of file diff --git a/source/gameengine/PyDoc/SCA_PythonController.py b/source/gameengine/PyDoc/SCA_PythonController.py index 9684b41d481..7b9b6ccd80a 100644 --- a/source/gameengine/PyDoc/SCA_PythonController.py +++ b/source/gameengine/PyDoc/SCA_PythonController.py @@ -11,9 +11,8 @@ class SCA_PythonController(SCA_IController): @ivar script: the Python script this controller executes @type script: string, read-only - @ivar state: the controllers state bitmask. - This can be used with the GameObject's state to test if the controller is active. - @type state: integer + + @group Deprecated: getScript, setScript """ def activate(actuator): """ @@ -25,33 +24,6 @@ class SCA_PythonController(SCA_IController): Deactivates an actuator attached to this controller. @type actuator: actuator or the actuator name as a string """ - - def getSensors(): - """ - Gets a list of all sensors attached to this controller. - - @rtype: list [L{SCA_ISensor}] - """ - def getSensor(name): - """ - Gets the named linked sensor. - - @type name: string - @rtype: L{SCA_ISensor} - """ - def getActuators(): - """ - Gets a list of all actuators linked to this controller. - - @rtype: list [L{SCA_IActuator}] - """ - def getActuator(name): - """ - Gets the named linked actuator. - - @type name: string - @rtype: L{SCA_IActuator} - """ def getScript(): """ DEPRECATED: use the script property @@ -61,17 +33,9 @@ class SCA_PythonController(SCA_IController): """ def setScript(script): """ + DEPRECATED: use the script property Sets the Python script this controller executes. @type script: string. """ - def getState(): - """ - DEPRECATED: use the state property - Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. - This for instance will always be true however you could compare with a previous state to see when the state was activated. - GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState() - - @rtype: int - """ From 94e9e954b1ce5395a66b1f66d3fdc1818fe96a6c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 12:45:08 +0000 Subject: [PATCH 172/444] [#18681] Mousesensor Over doesn't work in ortho mode of 3dview camera bugfix, the clip near/far are scaled up for some reason, so use a range between 0 - clipfar for now. --- source/gameengine/Ketsji/KX_MouseFocusSensor.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 9106902ca0e..8b7c3cb928b 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -230,18 +230,17 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam) */ frompoint.setValue( (2 * (m_x-x_lb) / width) - 1.0, 1.0 - (2 * (m_y - y_lb) / height), + /*cam->GetCameraData()->m_perspective ? 0.0:cdata->m_clipstart,*/ /* real clipstart is scaled in ortho for some reason, zero is ok */ 0.0, /* nearclip, see above comments */ 1.0 ); topoint.setValue( (2 * (m_x-x_lb) / width) - 1.0, 1.0 - (2 * (m_y-y_lb) / height), - 1.0, /* farclip, see above comments */ + cam->GetCameraData()->m_perspective ? 1.0:cam->GetCameraData()->m_clipend, /* farclip, see above comments */ 1.0 ); /* camera to world */ MT_Transform wcs_camcs_tranform = cam->GetWorldToCamera(); - if (!cam->GetCameraData()->m_perspective) - wcs_camcs_tranform.getOrigin()[2] *= 100.0; MT_Transform cams_wcs_transform; cams_wcs_transform.invert(wcs_camcs_tranform); From cf93cad415e6b4f3952220c69977f74d29fb6533 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 21:41:14 +0000 Subject: [PATCH 173/444] use the python version scons is running with by default on linux, will make it easier for people with new distros that only come with python 2.6 --- config/linux2-config.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index c1b9d7d2ebd..22210f0218d 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -4,8 +4,16 @@ LIBDIR = "${LCGDIR}" WITH_BF_VERSE = False BF_VERSE_INCLUDE = "#extern/verse/dist" +def py_version_string(): + ''' + returns py version - "2.5", "2.6" etc + ''' + import platform + ver = platform.python_version_tuple() + return '%d.%d' % (ver[0], ver[1]) + BF_PYTHON = '/usr' -BF_PYTHON_VERSION = '2.5' +BF_PYTHON_VERSION = get_py_version_string() WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' From 3d60c4e746f08a3a7e583ea4461122f3358e21da Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 21:47:24 +0000 Subject: [PATCH 174/444] [#18702] FBX exported hemi light crashes maya - bugfix, off by 1 when clamping lamp types, caused blender to write an invalid lamp type - error in last commit (renamed function) --- config/linux2-config.py | 2 +- release/scripts/export_fbx.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index 22210f0218d..b0c989f1b5c 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -13,7 +13,7 @@ def py_version_string(): return '%d.%d' % (ver[0], ver[1]) BF_PYTHON = '/usr' -BF_PYTHON_VERSION = get_py_version_string() +BF_PYTHON_VERSION = py_version_string() WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 0a38d63049d..707ab9ebbb7 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -1002,7 +1002,7 @@ def write(filename, batch_objects = None, \ #eDIRECTIONAL #eSPOT light_type = light.type - if light_type > 3: light_type = 0 + if light_type > 2: light_type = 1 # hemi and area lights become directional mode = light.mode if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: From 49fda9470d3abe0e8f19058ea6e893209bf250f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 6 May 2009 22:16:28 +0000 Subject: [PATCH 175/444] python is not being very helpful! It seems 2.5 gives the version as a string, 2.6 as ints --- config/linux2-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/linux2-config.py b/config/linux2-config.py index b0c989f1b5c..6d207dc40e6 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -10,7 +10,7 @@ def py_version_string(): ''' import platform ver = platform.python_version_tuple() - return '%d.%d' % (ver[0], ver[1]) + return '%d.%d' % (int(ver[0]), int(ver[1])) # py2.5 uses strings, 2.6 ints BF_PYTHON = '/usr' BF_PYTHON_VERSION = py_version_string() From c46fa2745a98fe0b4545743751ad1e96802e330d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 May 2009 01:27:58 +0000 Subject: [PATCH 176/444] smudge on float images crashed --- source/blender/src/imagepaint.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index ad155dc27a1..86534438ba0 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -3798,10 +3798,9 @@ static void *do_projectpaint_thread(void *ph_v) *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint; } - for (node= smearPixels_f; node; node= node->next) { /* this wont run for a float image */ + for (node= smearPixels_f; node; node= node->next) { projPixel = node->link; IMAPAINT_CHAR_RGBA_TO_FLOAT(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.ch); - node = node->next; } BLI_memarena_free(smearArena); From 779bf435ef2ba87fbcee6a28b053d97a551b8eb5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 May 2009 05:23:15 +0000 Subject: [PATCH 177/444] python3 compatibility for the BGE api, this only works with scons when WITH_BF_NOBLENDER is enabled. Mathutils, Geometry and BGL modules are currently disabled with python3 --- .../nodes/intern/SHD_nodes/SHD_dynamic.c | 5 ++++ source/blender/python/SConscript | 4 ++- source/gameengine/Expressions/PyObjectPlus.h | 17 +++++++++++ source/gameengine/Ketsji/KX_PythonInit.cpp | 12 ++++++-- .../gameengine/Ketsji/KX_VehicleWrapper.cpp | 27 ++---------------- source/gameengine/Ketsji/SConscript | 28 ++++++++++--------- source/gameengine/VideoTexture/Texture.cpp | 2 +- 7 files changed, 53 insertions(+), 42 deletions(-) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 9a8f2f13d65..4b20ca9da21 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -33,6 +33,11 @@ #include #endif +/* TODO, support python3.x */ +#if PY_VERSION_HEX >= 0x03000000 +#define DISABLE_PYTHON 1 +#endif + #include "DNA_text_types.h" #include "BKE_text.h" #include "BKE_utildefines.h" diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index e869cfba556..e06cf1840c5 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -30,4 +30,6 @@ if env['WITH_BF_FFMPEG']: if env['BF_BUILDINFO']: defs.append('NAN_BUILDINFO') -env.BlenderLib ( libname='blender_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype=['core','game2'], priority = [60,115] ) +# A bit dodgy but disable building with python3 +if not env['BF_PYTHON_VERSION'].startswith('3'): + env.BlenderLib ( libname='blender_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype=['core','game2'], priority = [60,115] ) diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 449ece535c1..c21dc3a6e57 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -43,6 +43,23 @@ * Python defines ------------------------------*/ + + +#if PY_VERSION_HEX > 0x03000000 +#define PyString_FromString PyUnicode_FromString +#define PyString_FromFormat PyUnicode_FromFormat +#define PyString_Check PyUnicode_Check +#define PyString_Size PyUnicode_GetSize + +#define PyInt_FromLong PyLong_FromSsize_t +#define PyInt_AsLong PyLong_AsSsize_t +#define PyString_AsString _PyUnicode_AsString +#define PyInt_Check PyLong_Check +#define PyInt_AS_LONG PyLong_AsLong // TODO - check this one +#endif + + + /* Py_RETURN_NONE Python 2.4 macro. diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 8eb8956cfe2..1a571633b15 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -88,10 +88,12 @@ #include "BKE_main.h" extern "C" { + #include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ +#if PY_VERSION_HEX < 0x03000000 #include "Mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use. #include "Geometry.h" // Blender.Geometry module copied here so the blenderlayer can use. - #include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ #include "BGL.h" +#endif } #include "marshal.h" /* python header for loading/saving dicts */ @@ -1770,7 +1772,7 @@ static void clearGameModules() clearModule(modules, "GameLogic"); clearModule(modules, "Rasterizer"); clearModule(modules, "GameKeys"); - clearModule(modules, "VideoTexture"); + clearModule(modules, "VideoTexture"); clearModule(modules, "Mathutils"); clearModule(modules, "Geometry"); clearModule(modules, "BGL"); @@ -2095,6 +2097,7 @@ PyObject* initGameKeys() return d; } +#if PY_VERSION_HEX < 0x03000000 PyObject* initMathutils() { return Mathutils_Init("Mathutils"); // Use as a top level module in BGE @@ -2109,6 +2112,11 @@ PyObject* initBGL() { return BGL_Init("BGL"); // Use as a top level module in BGE } +#else // TODO Py3k conversion +PyObject* initMathutils() {Py_INCREF(Py_None);return Py_None;} +PyObject* initGeometry() {Py_INCREF(Py_None);return Py_None;} +PyObject* initBGL() {Py_INCREF(Py_None);return Py_None;} +#endif void KX_SetActiveScene(class KX_Scene* scene) { diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index e43a5caa50a..8146d04a878 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -312,32 +312,9 @@ PyObject* KX_VehicleWrapper::py_getattro_dict() { py_getattro_dict_up(PyObjectPlus); } -int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* pyobj) +int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* value) { - /* TODO - strange setattr, needs updating */ - PyTypeObject* type = pyobj->ob_type; - int result = 1; - - if (type == &PyList_Type) - { - result = 0; - } - if (type == &PyFloat_Type) - { - result = 0; - - } - if (type == &PyInt_Type) - { - result = 0; - } - if (type == &PyString_Type) - { - result = 0; - } - if (result) - result = PyObjectPlus::py_setattro(attr,pyobj); - return result; + py_setattro_up(PyObjectPlus); }; diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index dd7297080e5..2c87c7dd78a 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -7,25 +7,27 @@ sources = env.Glob('*.cpp') defs = '' # Mathutils C files. -sources.extend([\ - '#source/blender/python/api2_2x/Mathutils.c',\ - '#source/blender/python/api2_2x/Geometry.c',\ - '#source/blender/python/api2_2x/constant.c',\ - '#source/blender/python/api2_2x/euler.c',\ - '#source/blender/python/api2_2x/matrix.c',\ - '#source/blender/python/api2_2x/quat.c',\ - '#source/blender/python/api2_2x/vector.c',\ -]) +if not env['BF_PYTHON_VERSION'].startswith('3'): + # TODO - py3 support + sources.extend([\ + '#source/blender/python/api2_2x/Mathutils.c',\ + '#source/blender/python/api2_2x/Geometry.c',\ + '#source/blender/python/api2_2x/euler.c',\ + '#source/blender/python/api2_2x/matrix.c',\ + '#source/blender/python/api2_2x/quat.c',\ + '#source/blender/python/api2_2x/vector.c',\ + '#source/blender/python/api2_2x/constant.c',\ + ]) + + sources.extend([\ + '#source/blender/python/api2_2x/BGL.c' + ]) sources.extend([\ '#source/blender/python/api2_2x/bpy_internal_import.c' ]) -sources.extend([\ - '#source/blender/python/api2_2x/BGL.c' -]) - incs = '. #source/blender/python/api2_2x' # Only for Mathutils! and bpy_internal_import.h, be very careful incs += ' #source/kernel/gen_system #intern/string #intern/guardedalloc' diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index f1fcbee3041..a8ece4bc17e 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -168,7 +168,7 @@ void Texture_dealloc (Texture * self) // release scaled image buffer delete [] self->m_scaledImg; // release object - self->ob_type->tp_free((PyObject*)self); + ((PyObject *)self)->ob_type->tp_free((PyObject*)self); } From 42557f90bd16771a5c6437dbfb3952527df7fb1a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 7 May 2009 09:13:01 +0000 Subject: [PATCH 178/444] BGE performance, 3rd round: culling and rasterizer. This commit extend the technique of dynamic linked list to the mesh slots so as to eliminate dumb scan or map lookup. It provides massive performance improvement in the culling and in the rasterizer when the majority of objects are static. Other improvements: - Compute the opengl matrix only for objects that are visible. - Simplify hash function for GEN_HasedPtr - Scan light list instead of general object list to render shadows - Remove redundant opengl calls to set specularity, shinyness and diffuse between each mesh slots. - Cache GPU material to avoid frequent call to GPU_material_from_blender - Only set once the fixed elements of mesh slot - Use more inline function The following table shows the performance increase between 2.48, 1st round and this round of improvement. The test was done with a scene containing 40000 objects, of which 1000 are in the view frustrum approximately. The object are simple textured cube to make sure the GPU is not the bottleneck. As some of the rasterizer processing time has moved under culling, I present the sum of scenegraph(includes culling)+rasterizer time Scenegraph+rasterizer(ms) 2.48 1st round 3rd round All objects static, 323.0 86.0 7.2 all visible, 1000 in the view frustrum All objects static, 219.0 49.7 N/A(*) all invisible. All objects moving, 323.0 105.6 34.7 all visible, 1000 in the view frustrum Scene destruction 40min 40min 4s (*) : this time is not representative because the frame rate was at 60fps. In that case, the GPU holds down the GE by frame sync. By design, the overhead of the rasterizer is 0 when the the objects are invisible. This table shows a global speed up between 9x and 45x compared to 2.48a for scenegraph, culling and rasterizer overhead. The speed up goes much higher when objects are invisible. An additional 2-4x speed up is possible in the scenegraph by upgrading the Moto library to use Eigen2 BLAS library instead of C++ classes but the scenegraph is already so fast that it is not a priority right now. Next speed up in logic: many things to do there... --- .../rasterizer/RAS_rasterizer.vcproj | 12 ++-- .../RAS_openglrasterizer.vcproj | 12 ++-- source/gameengine/Ketsji/BL_BlenderShader.cpp | 32 ++++------ source/gameengine/Ketsji/BL_BlenderShader.h | 13 +++- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 18 ++++-- source/gameengine/Ketsji/KX_BlenderMaterial.h | 1 + source/gameengine/Ketsji/KX_GameObject.cpp | 49 +++++++++++++-- source/gameengine/Ketsji/KX_GameObject.h | 1 + source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 28 ++++----- source/gameengine/Ketsji/KX_Light.cpp | 5 +- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 15 +++-- source/gameengine/Ketsji/KX_PythonInit.cpp | 7 ++- source/gameengine/Ketsji/KX_Scene.cpp | 2 + source/gameengine/Rasterizer/CMakeLists.txt | 1 + source/gameengine/Rasterizer/Makefile | 1 + .../Rasterizer/RAS_BucketManager.cpp | 60 ++++++++++++++++++- .../gameengine/Rasterizer/RAS_BucketManager.h | 1 + .../Rasterizer/RAS_IPolygonMaterial.cpp | 3 + .../Rasterizer/RAS_IPolygonMaterial.h | 1 + .../Rasterizer/RAS_MaterialBucket.cpp | 12 ++-- .../Rasterizer/RAS_MaterialBucket.h | 25 +++++++- .../gameengine/Rasterizer/RAS_MeshObject.cpp | 8 ++- source/gameengine/Rasterizer/RAS_MeshObject.h | 2 +- .../RAS_OpenGLRasterizer/CMakeLists.txt | 1 + .../Rasterizer/RAS_OpenGLRasterizer/Makefile | 1 + .../RAS_ListRasterizer.cpp | 2 +- .../RAS_OpenGLRasterizer/SConscript | 2 +- source/gameengine/Rasterizer/SConscript | 2 +- source/gameengine/SceneGraph/SG_DList.h | 4 ++ source/gameengine/SceneGraph/SG_QList.h | 4 ++ source/gameengine/SceneGraph/SG_Spatial.cpp | 7 ++- source/gameengine/SceneGraph/SG_Spatial.h | 8 ++- .../gameengine/VideoTexture/ImageRender.cpp | 3 - source/kernel/gen_system/GEN_HashedPtr.cpp | 9 ++- 34 files changed, 260 insertions(+), 92 deletions(-) diff --git a/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj b/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj index d3d35ff4826..dde8714507a 100644 --- a/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj +++ b/projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj @@ -43,7 +43,7 @@ GetBlenderScene(); mBlendMode = GPU_BLEND_SOLID; - if(mMat) - GPU_material_from_blender(mBlenderScene, mMat); + ReloadMaterial(); } BL_BlenderShader::~BL_BlenderShader() { - if(mMat && GPU_material_from_blender(mBlenderScene, mMat)) - GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat)); + if(mGPUMat) + GPU_material_unbind(mGPUMat); } -bool BL_BlenderShader::Ok() +void BL_BlenderShader::ReloadMaterial() { - return VerifyShader(); -} - -bool BL_BlenderShader::VerifyShader() -{ - if(mMat) - return (GPU_material_from_blender(mBlenderScene, mMat) != 0); - else - return false; + mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL; } void BL_BlenderShader::SetProg(bool enable, double time) { if(VerifyShader()) { if(enable) - GPU_material_bind(GPU_material_from_blender(mBlenderScene, mMat), mLightLayer, mBlenderScene->lay, time); + GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time); else - GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat)); + GPU_material_unbind(mGPUMat); } } @@ -66,7 +58,7 @@ int BL_BlenderShader::GetAttribNum() if(!VerifyShader()) return enabled; - GPU_material_vertex_attributes(GPU_material_from_blender(mBlenderScene, mMat), &attribs); + GPU_material_vertex_attributes(mGPUMat, &attribs); for(i = 0; i < attribs.totlayer; i++) if(attribs.layer[i].glindex+1 > enabled) @@ -89,7 +81,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat) if(!VerifyShader()) return; - gpumat = GPU_material_from_blender(mBlenderScene, mMat); + gpumat = mGPUMat; if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { GPU_material_vertex_attributes(gpumat, &attribs); @@ -131,7 +123,7 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty ) float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4]; GPUMaterial *gpumat; - gpumat = GPU_material_from_blender(mBlenderScene, mMat); + gpumat = mGPUMat; if(!gpumat || !GPU_material_bound(gpumat)) return; diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index 5c1f59f94ad..9af53bfc863 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -32,19 +32,28 @@ private: struct Material *mMat; int mLightLayer; int mBlendMode; + GPUMaterial *mGPUMat; - bool VerifyShader(); + bool VerifyShader() + { + return (NULL != mGPUMat); + } public: BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer); virtual ~BL_BlenderShader(); - bool Ok(); + bool Ok() + { + // same as VerifyShared + return (NULL != mGPUMat); + } void SetProg(bool enable, double time=0.0); int GetAttribNum(); void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat); void Update(const class RAS_MeshSlot & ms, class RAS_IRasterizer* rasty); + void ReloadMaterial(); int GetBlendMode(); bool Equals(BL_BlenderShader *blshader); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 5f08739ea14..c3c738a8183 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -152,6 +152,12 @@ Scene* KX_BlenderMaterial::GetBlenderScene() const return mScene->GetBlenderScene(); } +void KX_BlenderMaterial::ReleaseMaterial() +{ + if (mBlenderShader) + mBlenderShader->ReloadMaterial(); +} + void KX_BlenderMaterial::OnConstruction() { if (mConstructed) @@ -409,10 +415,12 @@ KX_BlenderMaterial::ActivatShaders( } else rasty->SetLines(false); + ActivatGLMaterials(rasty); + ActivateTexGen(rasty); } - ActivatGLMaterials(rasty); - ActivateTexGen(rasty); + //ActivatGLMaterials(rasty); + //ActivateTexGen(rasty); } void @@ -501,10 +509,12 @@ KX_BlenderMaterial::ActivateMat( } else rasty->SetLines(false); + ActivatGLMaterials(rasty); + ActivateTexGen(rasty); } - ActivatGLMaterials(rasty); - ActivateTexGen(rasty); + //ActivatGLMaterials(rasty); + //ActivateTexGen(rasty); } bool diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index d763ba3ef03..52019ed2248 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -121,6 +121,7 @@ private: void GetMaterialRGBAColor(unsigned char *rgba) const; Material* GetBlenderMaterial() const; Scene* GetBlenderScene() const; + void ReleaseMaterial(); // message centers void setTexData( bool enable,RAS_IRasterizer *ras); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 22b9c940178..b20c0dae97b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -436,6 +436,7 @@ double* KX_GameObject::GetOpenGLMatrix() m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false; trans.scale(scaling[0], scaling[1], scaling[2]); trans.getValue(fl); + GetSGNode()->ClearDirty(); } return fl; } @@ -443,8 +444,27 @@ double* KX_GameObject::GetOpenGLMatrix() void KX_GameObject::AddMeshUser() { for (size_t i=0;iAddMeshUser(this); - + { + m_meshes[i]->AddMeshUser(this, &m_meshSlots); + } + // set the part of the mesh slot that never change + double* fl = GetOpenGLMatrixPtr()->getPointer(); + RAS_Deformer *deformer = GetDeformer(); + + //RAS_MeshSlot *ms; + //for(ms =static_cast(m_meshSlots.QPeek()); + // ms!=static_cast(m_meshSlots.Self()); + // ms =static_cast(ms->QPeek())) + //{ + // ms->m_OpenGLMatrix = fl; + // ms->SetDeformer(deformer); + //} + SG_QList::iterator mit(m_meshSlots); + for(mit.begin(); !mit.end(); ++mit) + { + (*mit)->m_OpenGLMatrix = fl; + (*mit)->SetDeformer(deformer); + } UpdateBuckets(false); } @@ -468,10 +488,29 @@ static void UpdateBuckets_recursive(SG_Node* node) void KX_GameObject::UpdateBuckets( bool recursive ) { if (GetSGNode()) { - double* fl = GetOpenGLMatrixPtr()->getPointer(); + RAS_MeshSlot *ms; - for (size_t i=0;iUpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled); + if (GetSGNode()->IsDirty()) + GetOpenGLMatrix(); + //for(ms =static_cast(m_meshSlots.QPeek()); + // ms!=static_cast(m_meshSlots.Self()); + // ms =static_cast(ms->QPeek())) + SG_QList::iterator mit(m_meshSlots); + for(mit.begin(); !mit.end(); ++mit) + { + ms = *mit; + ms->m_bObjectColor = m_bUseObjectColor; + ms->m_RGBAcolor = m_objectColor; + ms->m_bVisible = m_bVisible; + ms->m_bCulled = m_bCulled || !m_bVisible; + if (!ms->m_bCulled) + ms->m_bucket->ActivateMesh(ms); + + /* split if necessary */ +#ifdef USE_SPLIT + ms->Split(); +#endif + } if (recursive) { UpdateBuckets_recursive(GetSGNode()); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index bbb1b8bb360..2869404ee9b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -77,6 +77,7 @@ protected: STR_String m_text; int m_layer; std::vector m_meshes; + SG_QList m_meshSlots; // head of mesh slots of this struct Object* m_pBlenderObject; struct Object* m_pBlenderGroupObject; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index d6747bd1ba4..e773a9571f1 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -296,11 +296,13 @@ void KX_KetsjiEngine::RenderDome() return; KX_SceneList::iterator sceneit; - for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) - { - // do this only once per scene - (*sceneit)->UpdateMeshTransformations(); - } + + // This is now done incrementally in KX_Scene::CalculateVisibleMeshes() + //for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + //{ + // // do this only once per scene + // (*sceneit)->UpdateMeshTransformations(); + //} int n_renders=m_dome->GetNumberRenders();// usually 4 or 6 for (int i=0;iGetWorldInfo()); - // do this only once per scene - scene->UpdateMeshTransformations(); + // this is now done incrementatlly in KX_Scene::CalculateVisibleMeshes + //scene->UpdateMeshTransformations(); // shadow buffers RenderShadowBuffers(scene); @@ -1119,16 +1121,13 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) { - CListValue *objectlist = scene->GetObjectList(); + CListValue *lightlist = scene->GetLightList(); int i, drawmode; m_rendertools->SetAuxilaryClientInfo(scene); - for(i=0; iGetCount(); i++) { - KX_GameObject *gameobj = (KX_GameObject*)objectlist->GetValue(i); - - if(!gameobj->IsLight()) - continue; + for(i=0; iGetCount(); i++) { + KX_GameObject *gameobj = (KX_GameObject*)lightlist->GetValue(i); KX_LightObject *light = (KX_LightObject*)gameobj; @@ -1268,9 +1267,6 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); - //redundant, already done in Render() - //scene->UpdateMeshTransformations(); - // The following actually reschedules all vertices to be // redrawn. There is a cache between the actual rescheduling // and this call though. Visibility is imparted when this call diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 0f90bfd8a02..777a7f32629 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -102,8 +102,11 @@ void KX_LightObject::Update() { GPULamp *lamp; - if((lamp = GetGPULamp())) { + if((lamp = GetGPULamp()) != NULL && GetSGNode()) { float obmat[4][4]; + // lights don't get their openGL matrix updated, do it now + if (GetSGNode()->IsDirty()) + GetOpenGLMatrix(); double *dobmat = GetOpenGLMatrixPtr()->getPointer(); for(int i=0; i<4; i++) diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 918c251599e..2aa0ef921e9 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -172,13 +172,18 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c rasty->SetLines(true); else rasty->SetLines(false); + rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity); + rasty->SetShinyness(m_shininess); + rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0); + if (m_material) + rasty->SetPolygonOffset(-m_material->zoffs, 0.0); } - rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity); - rasty->SetShinyness(m_shininess); - rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0); - if (m_material) - rasty->SetPolygonOffset(-m_material->zoffs, 0.0); + //rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity); + //rasty->SetShinyness(m_shininess); + //rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0); + //if (m_material) + // rasty->SetPolygonOffset(-m_material->zoffs, 0.0); } void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 1a571633b15..57f736a6c09 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -936,16 +936,17 @@ static PyObject* gPySetGLSLMaterialSetting(PyObject*, /* display lists and GLSL materials need to be remade */ if(G.fileflags != fileflags) { + GPU_materials_free(); if(gp_KetsjiEngine) { KX_SceneList *scenes = gp_KetsjiEngine->CurrentScenes(); KX_SceneList::iterator it; for(it=scenes->begin(); it!=scenes->end(); it++) - if((*it)->GetBucketManager()) + if((*it)->GetBucketManager()) { (*it)->GetBucketManager()->ReleaseDisplayLists(); + (*it)->GetBucketManager()->ReleaseMaterials(); + } } - - GPU_materials_free(); } Py_RETURN_NONE; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index d31d451f02e..7280071cd1d 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -488,6 +488,8 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal // this is the list of object that are send to the graphics pipeline m_objectlist->Add(newobj->AddRef()); + if (newobj->IsLight()) + m_lightlist->Add(newobj->AddRef()); newobj->AddMeshUser(); // logic cannot be replicated, until the whole hierarchy is replicated. diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index 69a167e54a9..143209f5a54 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -30,6 +30,7 @@ SET(INC . ../../../source/kernel/gen_system ../../../source/blender/makesdna + ../../../source/gameengine/SceneGraph ../../../intern/string ../../../intern/moto/include ../../../extern/glew/include diff --git a/source/gameengine/Rasterizer/Makefile b/source/gameengine/Rasterizer/Makefile index fa6cf94c4b6..eafa2ded2f2 100644 --- a/source/gameengine/Rasterizer/Makefile +++ b/source/gameengine/Rasterizer/Makefile @@ -41,6 +41,7 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../kernel/gen_system CPPFLAGS += -I../../blender/makesdna +CPPFLAGS += -I../SceneGraph CPPFLAGS += -I../BlenderRoutines CPPFLAGS += -I../Expressions diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index ec290f89d9e..a111ac2786f 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -113,16 +113,38 @@ void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList const MT_Vector3 pnorm(cameratrans.getBasis()[2]); for (bit = buckets.begin(); bit != buckets.end(); ++bit) + { +#if 1 + SG_DList::iterator mit((*bit)->GetActiveMeshSlots()); + for(mit.begin(); !mit.end(); ++mit) + size++; +#else for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) if (!mit->IsCulled()) size++; +#endif + } slots.resize(size); for (bit = buckets.begin(); bit != buckets.end(); ++bit) + { +#if 1 + RAS_MaterialBucket* bucket = *bit; + RAS_MeshSlot* ms; + // remove the mesh slot form the list, it culls them automatically for next frame + for(ms = bucket->GetNextActiveMeshSlot(); + ms!= NULL; + ms = bucket->GetNextActiveMeshSlot()) + { + slots[i++].set(ms, bucket, pnorm); + } +#else for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) if (!mit->IsCulled()) slots[i++].set(&*mit, *bit, pnorm); +#endif + } if(alpha) sort(slots.begin(), slots.end(), backtofront()); @@ -161,11 +183,28 @@ void RAS_BucketManager::RenderSolidBuckets( const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools) { BucketList::iterator bit; - list::iterator mit; rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED); for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) { +#if 1 + RAS_MaterialBucket* bucket = *bit; + RAS_MeshSlot* ms; + // remove the mesh slot form the list, it culls them automatically for next frame + for(ms = bucket->GetNextActiveMeshSlot(); + ms!= NULL; + ms = bucket->GetNextActiveMeshSlot()) + { + rendertools->SetClientObject(rasty, ms->m_clientObj); + while (bucket->ActivateMaterial(cameratrans, rasty, rendertools)) + bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *ms); + + // make this mesh slot culled automatically for next frame + // it will be culled out by frustrum culling + ms->SetCulled(true); + } +#else + list::iterator mit; for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) { if (mit->IsCulled()) continue; @@ -179,6 +218,7 @@ void RAS_BucketManager::RenderSolidBuckets( // it will be culled out by frustrum culling mit->SetCulled(true); } +#endif } /* this code draws meshes order front-to-back instead to reduce overdraw. @@ -276,3 +316,21 @@ void RAS_BucketManager::ReleaseDisplayLists(RAS_IPolyMaterial *mat) } } +void RAS_BucketManager::ReleaseMaterials(RAS_IPolyMaterial * mat) +{ + BucketList::iterator bit; + list::iterator mit; + + for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) { + if (mat == NULL || (mat == (*bit)->GetPolyMaterial())) { + (*bit)->GetPolyMaterial()->ReleaseMaterial(); + } + } + + for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) { + if (mat == NULL || (mat == (*bit)->GetPolyMaterial())) { + (*bit)->GetPolyMaterial()->ReleaseMaterial(); + } + } +} + diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index 74526f365a0..2b81ddd3c82 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -58,6 +58,7 @@ public: void OptimizeBuckets(MT_Scalar distance); void ReleaseDisplayLists(RAS_IPolyMaterial * material = NULL); + void ReleaseMaterials(RAS_IPolyMaterial * material = NULL); private: void OrderBuckets(const MT_Transform& cameratrans, BucketList& buckets, vector& slots, bool alpha); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index c10e4040a92..f2fd96d63e9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -227,6 +227,9 @@ Scene* RAS_IPolyMaterial::GetBlenderScene() const return NULL; } +void RAS_IPolyMaterial::ReleaseMaterial() +{ +} unsigned int RAS_IPolyMaterial::GetFlag() const { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 1bc03a1db05..decd93c3d13 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -160,6 +160,7 @@ public: virtual Material* GetBlenderMaterial() const; virtual Scene* GetBlenderScene() const; + virtual void ReleaseMaterial(); virtual void GetMaterialRGBAColor(unsigned char *rgba) const; virtual bool UsesLighting(RAS_IRasterizer *rasty) const; virtual bool UsesObjectColor() const; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index d63e9c98415..db6394c1ec0 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -42,7 +42,7 @@ /* mesh slot */ -RAS_MeshSlot::RAS_MeshSlot() +RAS_MeshSlot::RAS_MeshSlot() : SG_QList() { m_clientObj = NULL; m_pDeformer = NULL; @@ -82,7 +82,7 @@ RAS_MeshSlot::~RAS_MeshSlot() } } -RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot) +RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot) : SG_QList() { RAS_DisplayArrayList::iterator it; @@ -461,21 +461,21 @@ bool RAS_MeshSlot::Split(bool force) return false; } + +#ifdef USE_SPLIT bool RAS_MeshSlot::IsCulled() { - list::iterator it; - if(m_joinSlot) return true; if(!m_bCulled) return false; -#ifdef USE_SPLIT + list::iterator it; for(it=m_joinedSlots.begin(); it!=m_joinedSlots.end(); it++) if(!(*it)->m_bCulled) return false; -#endif return true; } +#endif /* material bucket sorting */ diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index b07f86b079e..8db75b8b735 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -32,6 +32,7 @@ #include "RAS_TexVert.h" #include "GEN_Map.h" #include "STR_HashedString.h" +#include "SG_QList.h" #include "MT_Transform.h" #include "RAS_IPolygonMaterial.h" @@ -89,7 +90,9 @@ public: /* Entry of a RAS_MeshObject into RAS_MaterialBucket */ typedef std::vector RAS_DisplayArrayList; -class RAS_MeshSlot +// The QList is used to link the mesh slots to the object +// The DList is used to link the visible mesh slots to the material bucket +class RAS_MeshSlot : public SG_QList { friend class RAS_ListRasterizer; private: @@ -160,7 +163,11 @@ public: bool Split(bool force=false); bool Join(RAS_MeshSlot *target, MT_Scalar distance); bool Equals(RAS_MeshSlot *target); +#ifdef USE_SPLIT bool IsCulled(); +#else + bool IsCulled() { return m_bCulled; } +#endif void SetCulled(bool culled) { m_bCulled = culled; } }; @@ -171,7 +178,6 @@ class RAS_MeshMaterial public: RAS_MeshSlot *m_baseslot; class RAS_MaterialBucket *m_bucket; - GEN_Map m_slots; }; @@ -208,10 +214,23 @@ public: class RAS_MeshSlot* CopyMesh(class RAS_MeshSlot *ms); void RemoveMesh(class RAS_MeshSlot* ms); void Optimize(MT_Scalar distance); + void ActivateMesh(RAS_MeshSlot* slot) + { + m_activeMeshSlotsHead.AddBack(slot); + } + SG_DList& GetActiveMeshSlots() + { + return m_activeMeshSlotsHead; + } + RAS_MeshSlot* GetNextActiveMeshSlot() + { + return (RAS_MeshSlot*)m_activeMeshSlotsHead.Remove(); + } private: - list m_meshSlots; + list m_meshSlots; // all the mesh slots RAS_IPolyMaterial* m_material; + SG_DList m_activeMeshSlotsHead; // only those which must be rendered }; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 278aa9c75e2..c3223cb9448 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -242,6 +242,7 @@ RAS_Polygon* RAS_MeshObject::AddPolygon(RAS_MaterialBucket *bucket, int numverts RAS_MeshMaterial meshmat; meshmat.m_bucket = bucket; meshmat.m_baseslot = meshmat.m_bucket->AddMesh(numverts); + meshmat.m_baseslot->m_mesh = this; m_materials.push_back(meshmat); mmat = &m_materials.back(); } @@ -381,7 +382,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid, return NULL; } -void RAS_MeshObject::AddMeshUser(void *clientobj) +void RAS_MeshObject::AddMeshUser(void *clientobj, SG_QList *head) { list::iterator it; @@ -391,6 +392,7 @@ void RAS_MeshObject::AddMeshUser(void *clientobj) RAS_MeshSlot *ms = it->m_bucket->CopyMesh(it->m_baseslot); ms->m_clientObj = clientobj; it->m_slots.insert(clientobj, ms); + head->QAddBack(ms); } } @@ -402,7 +404,7 @@ void RAS_MeshObject::UpdateBuckets(void* clientobj, bool culled) { list::iterator it; - + for(it = m_materials.begin();it!=m_materials.end();++it) { RAS_MeshSlot **msp = it->m_slots[clientobj]; @@ -417,6 +419,8 @@ void RAS_MeshObject::UpdateBuckets(void* clientobj, ms->m_RGBAcolor = rgbavec; ms->m_bVisible = visible; ms->m_bCulled = culled || !visible; + if (!ms->m_bCulled) + ms->m_bucket->ActivateMesh(ms); /* split if necessary */ #ifdef USE_SPLIT diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index cc50f9c783d..a2283b9bc5d 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -130,7 +130,7 @@ public: RAS_Polygon* GetPolygon(int num) const; /* buckets */ - virtual void AddMeshUser(void *clientobj); + virtual void AddMeshUser(void *clientobj, SG_QList *head); virtual void UpdateBuckets( void* clientobj, double* oglmatrix, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index d061a449b7e..fe3d0f6aeea 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -32,6 +32,7 @@ SET(INC ../../../../intern/moto/include ../../../../source/gameengine/Rasterizer ../../../../source/gameengine/Ketsji + ../../../../source/gameengine/SceneGraph ../../../../extern/glew/include ../../../../source/blender/gpu ../../../../source/blender/makesdna diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile index b55f6492805..0327714dc5f 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile @@ -47,6 +47,7 @@ CPPFLAGS += -I../../../blender/blenlib CPPFLAGS += -I../../../blender/blenkernel CPPFLAGS += -I../../BlenderRoutines CPPFLAGS += -I../../Ketsji +CPPFLAGS += -I../../SceneGraph CPPFLAGS += -I.. CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index 06c61fb4b09..3ae4522f8e1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -214,7 +214,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) // workaround: note how we do not use vertex arrays for making display // lists, since glVertexAttribPointerARB doesn't seem to work correct // in display lists on ATI? either a bug in the driver or in Blender .. - if (mUseVertexArrays && !localSlot && !ms.m_pDerivedMesh) + if (mUseVertexArrays && /*!localSlot &&*/ !ms.m_pDerivedMesh) RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms); else RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index 314630297e0..d4b029ea34d 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines ' incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] -incs += ' #source/blender/gameengine/Ketsji #source/blender/makesdna #source/blender/blenkernel' +incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel' incs += ' #intern/guardedalloc #source/blender/blenlib' cxxflags = [] diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index a16a04b8514..771d3399485 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -4,7 +4,7 @@ Import ('env') sources = env.Glob('*.cpp') -incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/blender/blenkernel #source/blender/makesdna' +incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna' incs += ' ' + env['BF_PYTHON_INC'] cxxflags = [] diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h index d682be679e6..dc5afa2ee99 100644 --- a/source/gameengine/SceneGraph/SG_DList.h +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -83,6 +83,10 @@ public: { m_flink = m_blink = this; } + SG_DList(const SG_DList& other) + { + m_flink = m_blink = this; + } virtual ~SG_DList() { Delink(); diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h index efaa613bbb9..4a254ac36a4 100644 --- a/source/gameengine/SceneGraph/SG_QList.h +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -84,6 +84,10 @@ public: { m_fqlink = m_bqlink = this; } + SG_QList(const SG_QList& other) : SG_DList() + { + m_fqlink = m_bqlink = this; + } virtual ~SG_QList() { QDelink(); diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index b79d4bac91a..5a47f07f573 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -56,7 +56,8 @@ SG_Spatial( m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)), m_radius(1.0), - m_modified(false) + m_modified(false), + m_ogldirty(false) { } @@ -76,7 +77,9 @@ SG_Spatial( m_parent_relation(NULL), m_bbox(other.m_bbox), - m_radius(other.m_radius) + m_radius(other.m_radius), + m_modified(false), + m_ogldirty(false) { // duplicate the parent relation for this object m_parent_relation = other.m_parent_relation->NewCopy(); diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index eb1e87fbf19..d1fc95cceac 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -63,19 +63,24 @@ protected: SG_BBox m_bbox; MT_Scalar m_radius; bool m_modified; + bool m_ogldirty; // true if the openGL matrix for this object must be recomputed public: inline void ClearModified() { m_modified = false; + m_ogldirty = true; } inline void SetModified() { m_modified = true; ActivateScheduleUpdateCallback(); } - + inline void ClearDirty() + { + m_ogldirty = false; + } /** * Define the realtionship this node has with it's parent * node. You should pass an unshared instance of an SG_ParentRelation @@ -233,6 +238,7 @@ public: MT_Scalar Radius() const { return m_radius; } void SetRadius(MT_Scalar radius) { m_radius = radius; } bool IsModified() { return m_modified; } + bool IsDirty() { return m_ogldirty; } protected: friend class SG_Controller; diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 1e3a84c1efb..db4461325d8 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -255,9 +255,6 @@ void ImageRender::Render() // restore the stereo mode now that the matrix is computed m_rasterizer->SetStereoMode(stereomode); - // do not update the mesh transform, we don't want to do it more than once per frame - //m_scene->UpdateMeshTransformations(); - m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); diff --git a/source/kernel/gen_system/GEN_HashedPtr.cpp b/source/kernel/gen_system/GEN_HashedPtr.cpp index 6dbed1fb7a8..ff9de465a34 100644 --- a/source/kernel/gen_system/GEN_HashedPtr.cpp +++ b/source/kernel/gen_system/GEN_HashedPtr.cpp @@ -40,11 +40,12 @@ // is a 32-bit integer, use all the bits of the pointer as long // as possible. // - +#if 1 unsigned int GEN_Hash(void * inDWord) { uintptr_t key = (uintptr_t)inDWord; - +#if 0 + // this is way too complicated key += ~(key << 16); key ^= (key >> 5); key += (key << 3); @@ -53,4 +54,8 @@ unsigned int GEN_Hash(void * inDWord) key ^= (key >> 17); return (unsigned int)(key & 0xffffffff); +#else + return (unsigned int)(key ^ (key>>4)); +#endif } +#endif \ No newline at end of file From f590ffdadc0dceac9d37d30dc565ca083c3c7fca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 May 2009 14:53:40 +0000 Subject: [PATCH 179/444] [#18645] Texture painting smudge brush darkens images - 2.49RC1 not fixed but the problem is now less bad when projection painting, bilinear interpolation was rounding down. - added gameOb.attrDict to get the internal gameObject dict. - mesh.getVertex wasnt setting an exception. --- source/blender/imbuf/intern/imageprocess.c | 10 +++++---- source/gameengine/Ketsji/KX_GameObject.cpp | 12 +++++++++++ source/gameengine/Ketsji/KX_GameObject.h | 1 + source/gameengine/Ketsji/KX_MeshProxy.cpp | 25 ++++++++++------------ source/gameengine/PyDoc/KX_GameObject.py | 2 ++ 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index fe7e26eac2b..6be257ff737 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -294,10 +294,12 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float * b= v-floor(v); a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); - outI[0]= ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]; - outI[1]= ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]; - outI[2]= ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]; - outI[3]= ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]; + /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) + * tested with white images and this should not wrap back to zero */ + outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f; + outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f; + outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f; + outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f; } } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index b20c0dae97b..492f72584f5 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1208,6 +1208,7 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition), KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), KX_PYATTRIBUTE_RO_FUNCTION("worldScaling", KX_GameObject, pyattr_get_worldScaling), + KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict), /* Experemental, dont rely on these yet */ KX_PYATTRIBUTE_RO_FUNCTION("sensors", KX_GameObject, pyattr_get_sensors), @@ -1766,6 +1767,17 @@ PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE return resultlist; } +PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast(self_v); + + if(self->m_attr_dict==NULL) + self->m_attr_dict= PyDict_New(); + + Py_INCREF(self->m_attr_dict); + return self->m_attr_dict; +} + /* We need these because the macros have a return in them */ PyObject* KX_GameObject::py_getattro__internal(PyObject *attr) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 2869404ee9b..8fafcc1f9b6 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -895,6 +895,7 @@ public: static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_meshes(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); /* Experemental! */ static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index eede3a0e832..c0b05859539 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -221,24 +221,21 @@ PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* args, PyObject* kwds) PyObject* KX_MeshProxy::PyGetVertex(PyObject* args, PyObject* kwds) { - int vertexindex= 1; - int matindex= 1; + int vertexindex; + int matindex; PyObject* vertexob = NULL; - if (PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex)) - { - RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex); - if (vertex) - { - vertexob = (new KX_VertexProxy(this, vertex))->NewProxy(true); - } - } - else { + if (!PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex)) + return NULL; + + RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex); + + if(vertex==NULL) { + PyErr_SetString(PyExc_ValueError, "mesh.getVertex(mat_idx, vert_idx): KX_MeshProxy, could not get a vertex at the given indicies"); return NULL; } - - return vertexob; - + + return (new KX_VertexProxy(this, vertex))->NewProxy(true); } PyObject* KX_MeshProxy::PyGetPolygon(PyObject* args, PyObject* kwds) diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 2688de0d018..0f9bfea98f3 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -79,6 +79,8 @@ class KX_GameObject(SCA_IObject): - note: This attribute is experemental and may be removed (but probably wont be). - note: Changes to this list will not update the KX_GameObject. @type actuators: list + @ivar attrDict: get the objects internal python attribute dictionary for direct (faster) access. + @type attrDict: dict @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh """ def endObject(): From 1f5ccd19287dbf8faa5e7bdcd62502e35863ede3 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 7 May 2009 19:36:12 +0000 Subject: [PATCH 180/444] BGE: unfortunately VA+list still doesn't work on ATI card, so put a specific check for ATI. --- .../RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp | 8 +++++--- .../Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index 3ae4522f8e1..f5324c6fbc9 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -104,9 +104,11 @@ bool RAS_ListSlot::End() RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock) : RAS_VAOpenGLRasterizer(canvas, lock), - mUseVertexArrays(useVertexArrays) + mUseVertexArrays(useVertexArrays), + mATI(false) { - // -- + if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.")) + mATI = true; } RAS_ListRasterizer::~RAS_ListRasterizer() @@ -214,7 +216,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) // workaround: note how we do not use vertex arrays for making display // lists, since glVertexAttribPointerARB doesn't seem to work correct // in display lists on ATI? either a bug in the driver or in Blender .. - if (mUseVertexArrays && /*!localSlot &&*/ !ms.m_pDerivedMesh) + if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh) RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms); else RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index 19211894896..912f28af6aa 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -42,6 +42,7 @@ typedef std::map RAS_ArrayLists; class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer { bool mUseVertexArrays; + bool mATI; RAS_ArrayLists mArrayLists; RAS_ListSlot* FindOrAdd(class RAS_MeshSlot& ms); From e1c958c3648ef903777f49b9fb6d4230af316885 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 7 May 2009 20:00:09 +0000 Subject: [PATCH 181/444] BGE Dome: Implementation of FBO to handle warp mesh rendering. We are using an image twice as big to render the fisheye before warping. It'll slow down warping meshes a little, but we get way more resolution. Therefore I will bring Truncated Dome mode back in order to avoid using warping mesh for that. --- source/gameengine/Ketsji/KX_Dome.cpp | 105 +++++++++++++++++++++------ source/gameengine/Ketsji/KX_Dome.h | 6 +- 2 files changed, 86 insertions(+), 25 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 3802f260391..4a6575ff412 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -66,6 +66,7 @@ KX_Dome::KX_Dome ( m_engine(engine) { warp.usemesh = false; + fboSupported = false; if (mode >= DOME_NUM_MODES) m_mode = DOME_FISHEYE; @@ -131,16 +132,20 @@ KX_Dome::KX_Dome ( CreateGLImages(); + if(warp.usemesh) + fboSupported = CreateFBO(); + dlistSupported = CreateDL(); } // destructor KX_Dome::~KX_Dome (void) { - GLuint m_numimages = m_numfaces; - ClearGLImages(); + if(fboSupported) + glDeleteFramebuffersEXT(1, &warp.fboId); + if(dlistSupported) glDeleteLists(dlistId, (GLsizei) m_numimages); } @@ -174,9 +179,9 @@ void KX_Dome::CreateGLImages(void) } if(warp.usemesh){ glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagewidth, warp.imageheight, 0, GL_RGB8, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagesize, warp.imagesize, 0, GL_RGB8, GL_UNSIGNED_BYTE, 0); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagewidth, warp.imageheight, 0); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagesize, warp.imagesize, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -227,19 +232,21 @@ http://projects.blender.org/tracker/?func=detail&aid=18655&group_id=9&atid=125 m_imagesize = (1 << i); if (warp.usemesh){ - warp.bufferwidth = canvaswidth; + // trying to use twice the size of the cube faces + GLint glMaxTexDim; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); + + if (2 * m_imagesize > glMaxTexDim) + warp.imagesize = m_imagesize; + + else + warp.imagesize = 2 * m_imagesize; + + //if FBO is not working/supported, we use the canvas dimension as buffer + warp.bufferwidth = canvaswidth; warp.bufferheight = canvasheight; - - i = 0; - while ((1 << i) <= warp.bufferwidth) - i++; - warp.imagewidth = (1 << i); - - i = 0; - while ((1 << i) <= warp.bufferheight) - i++; - warp.imageheight = (1 << i); } + //XXX HACK canvaswidth = m_viewport.GetWidth(); canvasheight = m_viewport.GetHeight(); @@ -320,6 +327,40 @@ bool KX_Dome::CreateDL(){ return true; } +bool KX_Dome::CreateFBO(void) +{ + glGenFramebuffersEXT(1, &warp.fboId); + if(warp.fboId==0) + { + printf("Dome Error: Invalid frame buffer object. Using low resolution warp image."); + return false; + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId); + + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, domefacesId[m_numfaces], 0); + + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + + if(status == GL_FRAMEBUFFER_UNSUPPORTED_EXT) + { + printf("Dome Error: FrameBuffer unsupported. Using low resolution warp image."); + return false; + } + else if(status != GL_FRAMEBUFFER_COMPLETE_EXT) + { + glDeleteFramebuffersEXT(1, &warp.fboId); + return false; + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + //nothing failed: we can use the whole FBO as buffersize + warp.bufferwidth = warp.bufferheight = warp.imagesize; + return true; +} + void KX_Dome::GLDrawTriangles(vector & face, int nfaces) { int i,j; @@ -336,8 +377,9 @@ void KX_Dome::GLDrawTriangles(vector & face, int nfaces) void KX_Dome::GLDrawWarpQuads(void) { int i, j, i2; - float uv_width = (float)(warp.bufferwidth-1) / warp.imagewidth; - float uv_height = (float)(warp.bufferheight-1) / warp.imageheight; + + float uv_width = (float)(warp.bufferwidth) / warp.imagesize; + float uv_height = (float)(warp.bufferheight) / warp.imagesize; if(warp.mode ==2 ){ glBegin(GL_QUADS); @@ -394,7 +436,7 @@ void KX_Dome::GLDrawWarpQuads(void) } glEnd(); } else{ - printf("Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode); + printf("Dome Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode); } } @@ -430,7 +472,7 @@ i ranges from 0 to 1, if negative don't draw that mesh node lines = text.Explode('\n'); if(lines.size() < 6){ - printf("Error: Warp Mesh File with insufficient data!\n"); + printf("Dome Error: Warp Mesh File with insufficient data!\n"); return false; } columns = lines[1].Explode(' '); @@ -438,7 +480,7 @@ i ranges from 0 to 1, if negative don't draw that mesh node columns = lines[1].Explode('\t'); if(columns.size() !=2){ - printf("Error: Warp Mesh File incorrect. The second line should contain: width height.\n"); + printf("Dome Error: Warp Mesh File incorrect. The second line should contain: width height.\n"); return false; } @@ -448,7 +490,7 @@ i ranges from 0 to 1, if negative don't draw that mesh node warp.n_height = atoi(columns[1]); if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)){ - printf("Error: Warp Mesh File with insufficient data!\n"); + printf("Dome Error: Warp Mesh File with insufficient data!\n"); return false; }else{ warp.nodes = vector > (warp.n_height, vector(warp.n_width)); @@ -470,7 +512,7 @@ i ranges from 0 to 1, if negative don't draw that mesh node } else{ warp.nodes.clear(); - printf("Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n"); + printf("Dome Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n"); return false; } } @@ -1538,6 +1580,13 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i) void KX_Dome::Draw(void) { + if (fboSupported){ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId); + + glViewport(0,0,warp.imagesize, warp.imagesize); + glScissor(0,0,warp.imagesize, warp.imagesize); + } + switch(m_mode){ case DOME_FISHEYE: DrawDomeFisheye(); @@ -1552,8 +1601,16 @@ void KX_Dome::Draw(void) if(warp.usemesh) { - glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), warp.bufferwidth, warp.bufferheight); + if(fboSupported) + { + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + else + { + glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), warp.bufferwidth, warp.bufferheight); + } DrawDomeWarped(); } } diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 84f0c5c72ed..257172ac215 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -74,6 +74,7 @@ public: //openGL checks: bool dlistSupported; + bool fboSupported; //openGL names: GLuint domefacesId[7]; // ID of the images -- room for 7 images, using only 4 for 180º x 360º dome, 6 for panoramic and +1 for warp mesh @@ -93,8 +94,9 @@ public: bool usemesh; int mode; int n_width, n_height; //nodes width and height - int imagewidth, imageheight; + int imagesize; int bufferwidth, bufferheight; + GLuint fboId; vector > nodes; } warp; @@ -140,6 +142,8 @@ public: void ClearGLImages(void);//called on resize bool CreateDL(void); //create Display Lists void ClearDL(void); //remove Display Lists + bool CreateFBO(void);//create FBO (for warp mesh) + void ClearFBO(void); //remove FBO void CalculateCameraOrientation(); void CalculateImageSize(); //set m_imagesize From cdba1ddd5d454aca4d39dbb01866c155421b5d11 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 May 2009 22:06:27 +0000 Subject: [PATCH 182/444] BGE Python owned proxies had a problem being decref'd twice, this would crash on freeing KX_Vertex/Poly Proxy types when python was compiled with debug options enabled. add_mesh_torus.py wasnt tested from update, will go through all edited scripts and test :\ --- release/scripts/add_mesh_torus.py | 2 +- source/gameengine/Expressions/PyObjectPlus.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/release/scripts/add_mesh_torus.py b/release/scripts/add_mesh_torus.py index f2fc53ef275..2941c56420e 100644 --- a/release/scripts/add_mesh_torus.py +++ b/release/scripts/add_mesh_torus.py @@ -62,7 +62,7 @@ def main(): BPyAddMesh.add_mesh_simple('Torus', verts, [], faces) -if math: +if cos and sin and pi: main() else: Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 82f67a9b007..7d302246c70 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -95,6 +95,7 @@ void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper PyObjectPlus *self_plus= BGE_PROXY_REF(self); if(self_plus) { if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */ + self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */ delete self_plus; } From 57beadf40613b3c4ba6f20cbaddc1066c6800bbc Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Thu, 7 May 2009 22:31:19 +0000 Subject: [PATCH 183/444] Second fix for [#18697] 2.49RC1: Keyed Particles fine in viewport but give me a crash during render --- source/blender/blenkernel/intern/particle_system.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index d3ba3fa3802..f74e32acdbf 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -203,8 +203,11 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) if(psys->particles->keys) MEM_freeN(psys->particles->keys); - for(i=0, pa=psys->particles; ikeys) pa->keys= NULL; + for(i=totsaved, pa=psys->particles+totsaved; itotpart; i++, pa++) + if(pa->keys) { + pa->keys= NULL; + pa->totkey= 0; + } for(i=totsaved, pa=psys->particles+totsaved; itotpart; i++, pa++) if(pa->hair) MEM_freeN(pa->hair); From 1d11df17085bd4f1231a892089a0771887d155bb Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 8 May 2009 18:59:08 +0000 Subject: [PATCH 184/444] BGE Dome: Truncated Dome are back (Upright and Downright) + GLEW_EXT_framebuffer_object check before generating FBO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After last commit (20099) warping meshes got slower (more quality == less performance). Since we don't need an extra warping for truncated domes, It's better to handle them directly in openGL without the need of warping it. I'll talk with some Dome owners to see if we need both Upright and Downright modes. I may remove one of them by 2.49 them. *) also: a proper GLEW_EXT_framebuffer_object check before generating FBO (for warping meshes). **) next in line (maybe after RC2): tilt option to tilt the camera up to 90º upward. --- source/gameengine/Ketsji/KX_Dome.cpp | 73 +++++++++++++++++++++------- source/gameengine/Ketsji/KX_Dome.h | 7 +-- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 4a6575ff412..a302bf98cb8 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -124,6 +124,16 @@ KX_Dome::KX_Dome ( CreateMeshPanorama(); m_numfaces = 6; break; + default: //DOME_TRUNCATED_DOWN and DOME_TRUNCATED_UP + cubetop.resize(1); + cubebottom.resize(1); + cubeleft.resize(2); + cuberight.resize(2); + + m_angle = 180; + CreateMeshDome180(); + m_numfaces = 4; + break; } m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces); @@ -255,7 +265,7 @@ http://projects.blender.org/tracker/?func=detail&aid=18655&group_id=9&atid=125 bool KX_Dome::CreateDL(){ dlistId = glGenLists((GLsizei) m_numimages); if (dlistId != 0) { - if(m_mode == DOME_FISHEYE){ + if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_UP || m_mode == DOME_TRUNCATED_DOWN){ glNewList(dlistId, GL_COMPILE); GLDrawTriangles(cubetop, nfacestop); glEndList(); @@ -329,6 +339,12 @@ bool KX_Dome::CreateDL(){ bool KX_Dome::CreateFBO(void) { + if (!GLEW_EXT_framebuffer_object) + { + printf("Dome Error: FrameBuffer unsupported. Using low resolution warp image."); + return false; + } + glGenFramebuffersEXT(1, &warp.fboId); if(warp.fboId==0) { @@ -345,7 +361,7 @@ bool KX_Dome::CreateFBO(void) if(status == GL_FRAMEBUFFER_UNSUPPORTED_EXT) { - printf("Dome Error: FrameBuffer unsupported. Using low resolution warp image."); + printf("Dome Error: FrameBuffer settings unsupported. Using low resolution warp image."); return false; } else if(status != GL_FRAMEBUFFER_COMPLETE_EXT) @@ -1469,7 +1485,9 @@ Uses 6 cameras for angles up to 360 MT_Scalar c = cos(deg45); MT_Scalar s = sin(deg45); - if ((m_mode == DOME_FISHEYE && m_angle <= 180)){ + if ((m_mode == DOME_FISHEYE && m_angle <= 180) + || m_mode == DOME_TRUNCATED_UP + || m_mode == DOME_TRUNCATED_DOWN){ m_locRot[0] = MT_Matrix3x3( // 90º - Top c, -s, 0.0, @@ -1597,6 +1615,12 @@ void KX_Dome::Draw(void) case DOME_PANORAM_SPH: DrawPanorama(); break; + case DOME_TRUNCATED_UP: + DrawDomeFisheye(); + break; + case DOME_TRUNCATED_DOWN: + DrawDomeFisheye(); + break; } if(warp.usemesh) @@ -1760,22 +1784,37 @@ void KX_Dome::DrawDomeFisheye(void) float ortho_width, ortho_height; - if (warp.usemesh) - glOrtho((-1.0), 1.0, (-1.0), 1.0, -20.0, 10.0); //stretch the image to reduce resolution lost + if(m_mode == DOME_FISHEYE) { + if (warp.usemesh) + glOrtho((-1.0), 1.0, (-1.0), 1.0, -20.0, 10.0); //stretch the image to reduce resolution lost - else { - if (can_width < can_height){ - ortho_width = 1.0; - ortho_height = (float)can_height/can_width; - }else{ - ortho_width = (float)can_width/can_height; - ortho_height = 1.0; + else { + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + ortho_width /= m_size; + ortho_height /= m_size; + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); } - - ortho_width /= m_size; - ortho_height /= m_size; - - glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + } + else if(m_mode == DOME_TRUNCATED_UP) + { + ortho_width = 1.0; + ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0); + } + else { //m_mode == DOME_TRUNCATED_DOWN + ortho_width = 1.0; + ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; + + glOrtho((-ortho_width), ortho_width, (-ortho_width), ortho_height, -20.0, 10.0); } glMatrixMode(GL_TEXTURE); diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 257172ac215..30d02dce7a0 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -38,13 +38,14 @@ Developed as part of a Research and Development project for SAT - La Soci #include "MEM_guardedalloc.h" #include "BKE_text.h" -//#include "BLI_blenlib.h" //Dome modes: limit hardcoded in buttons_scene.c #define DOME_FISHEYE 1 #define DOME_ENVMAP 2 #define DOME_PANORAM_SPH 3 -#define DOME_NUM_MODES 4 +#define DOME_TRUNCATED_UP 4 +#define DOME_TRUNCATED_DOWN 5 +#define DOME_NUM_MODES 6 /// class for render 3d scene @@ -118,7 +119,7 @@ public: void CalculateFrustum(KX_Camera* cam); void RotateCamera(KX_Camera* cam, int i); - //Mesh Creating Functions + //Mesh creation Functions void CreateMeshDome180(void); void CreateMeshDome250(void); void CreateMeshPanorama(void); From cf8a37a3bb142a4ed8b7c7125092a408eea9fb10 Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Fri, 8 May 2009 19:37:14 +0000 Subject: [PATCH 185/444] Fix Copy & Paste not working inside Blender. My last patch remove the code that check if Blender is the owner of the selection, that is why stop working. --- intern/ghost/intern/GHOST_SystemX11.cpp | 91 +++++++++++++++---------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 0fb4b735f97..e7e47a6bf38 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -1182,49 +1182,68 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(int flag) const //0 = Regular clipboard 1 = selection // Options for where to get the selection from - Atom sseln= flag ? m_clipboard : m_primary; + Atom sseln= flag ? m_primary : m_clipboard; Atom target= m_string; + Window owner; // from xclip.c doOut() v0.11 - unsigned char *sel_buf; /* buffer for selection data */ - unsigned long sel_len= 0; /* length of sel_buf */ - XEvent evt; /* X Event Structures */ + unsigned char *sel_buf; + unsigned long sel_len= 0; + XEvent evt; unsigned int context= XCLIB_XCOUT_NONE; - if (sseln == m_string) - sel_buf= (unsigned char *)XFetchBuffer(m_display, (int *)&sel_len, 0); - else { - while (1) { - /* only get an event if xcout() is doing something */ - if (context != XCLIB_XCOUT_NONE) - XNextEvent(m_display, &evt); + vector & win_vec = m_windowManager->getWindows(); + vector::iterator win_it = win_vec.begin(); + GHOST_WindowX11 * window = static_cast(*win_it); + Window win = window->getXWindow(); - /* fetch the selection, or part of it */ - getClipboard_xcout(evt, sseln, target, &sel_buf, &sel_len, &context); - - /* fallback is needed. set XA_STRING to target and restart the loop. */ - if (context == XCLIB_XCOUT_FALLBACK) { - context= XCLIB_XCOUT_NONE; - target= m_string; - continue; - } - else if (context == XCLIB_XCOUT_FALLBACK_UTF8) { - /* utf8 fail, move to compouned text. */ - context= XCLIB_XCOUT_NONE; - target= m_compound_text; - continue; - } - else if (context == XCLIB_XCOUT_FALLBACK_COMP) { - /* compouned text faile, move to text. */ - context= XCLIB_XCOUT_NONE; - target= m_text; - continue; - } - - /* only continue if xcout() is doing something */ - if (context == XCLIB_XCOUT_NONE) - break; + /* check if we are the owner. */ + owner= XGetSelectionOwner(m_display, sseln); + if (owner == win) { + if (sseln == m_clipboard) { + sel_buf= (unsigned char *)malloc(strlen(txt_cut_buffer)+1); + strcpy((char *)sel_buf, txt_cut_buffer); + return((GHOST_TUns8*)sel_buf); } + else { + sel_buf= (unsigned char *)malloc(strlen(txt_select_buffer)+1); + strcpy((char *)sel_buf, txt_select_buffer); + return((GHOST_TUns8*)sel_buf); + } + } + else if (owner == None) + return(NULL); + + while (1) { + /* only get an event if xcout() is doing something */ + if (context != XCLIB_XCOUT_NONE) + XNextEvent(m_display, &evt); + + /* fetch the selection, or part of it */ + getClipboard_xcout(evt, sseln, target, &sel_buf, &sel_len, &context); + + /* fallback is needed. set XA_STRING to target and restart the loop. */ + if (context == XCLIB_XCOUT_FALLBACK) { + context= XCLIB_XCOUT_NONE; + target= m_string; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_UTF8) { + /* utf8 fail, move to compouned text. */ + context= XCLIB_XCOUT_NONE; + target= m_compound_text; + continue; + } + else if (context == XCLIB_XCOUT_FALLBACK_COMP) { + /* compouned text faile, move to text. */ + context= XCLIB_XCOUT_NONE; + target= m_text; + continue; + } + + /* only continue if xcout() is doing something */ + if (context == XCLIB_XCOUT_NONE) + break; } if (sel_len) { From 5d6b249c9bc38bd5b07b22d191aefdccc87e2090 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 9 May 2009 16:29:00 +0000 Subject: [PATCH 186/444] refcounting bugfix, gameOb.getParent() and gameOb.parent both added a reference when they should not have. --- source/gameengine/Ketsji/KX_GameObject.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 492f72584f5..4f3202aafea 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1440,8 +1440,10 @@ PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE { KX_GameObject* self= static_cast(self_v); KX_GameObject* parent = self->GetParent(); - if (parent) + if (parent) { + parent->Release(); /* self->GetParent() AddRef's */ return parent->GetProxy(); + } Py_RETURN_NONE; } @@ -2148,8 +2150,10 @@ PyObject* KX_GameObject::PyGetParent() { ShowDeprecationWarning("getParent()", "the parent property"); KX_GameObject* parent = this->GetParent(); - if (parent) + if (parent) { + parent->Release(); /* self->GetParent() AddRef's */ return parent->GetProxy(); + } Py_RETURN_NONE; } From cfc21667b98e1be9ba8ebabbd19a75541585ad24 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 9 May 2009 16:59:25 +0000 Subject: [PATCH 187/444] BGE: repair soft body - include this in RC2 please --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 3c93265c40b..1d2b275cab9 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2121,7 +2121,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, //tf.Add(gameobj->GetSGNode()); gameobj->NodeUpdateGS(0); - gameobj->AddMeshUser(); + //move to after finishing everything so that soft body deformer is included + //gameobj->AddMeshUser(); } else @@ -2311,7 +2312,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, //tf.Add(gameobj->GetSGNode()); gameobj->NodeUpdateGS(0); - gameobj->AddMeshUser(); + //move to after finishing everything so that soft body deformer is included + //gameobj->AddMeshUser(); } else { @@ -2665,6 +2667,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { KX_GameObject* gameobj = static_cast(objectlist->GetValue(i)); gameobj->ResetState(); + gameobj->AddMeshUser(); } #endif //CONVERT_LOGIC From 355b585447040e7f5697e4ee8adb951ca2aea4d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 9 May 2009 17:24:21 +0000 Subject: [PATCH 188/444] More refcount errors spotted by Benoit, one with python getting a list item so scene.objects["OBfoo"] would always mess up refcounts. --- source/gameengine/Expressions/ListValue.cpp | 8 +++++--- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 027d2594336..f4a801a965b 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -78,13 +78,15 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) STR_String index(PyString_AsString(pyindex)); CValue *item = ((CListValue*) list)->FindValue(index); if (item) + { + item->Release(); /* FindValue() AddRef's */ return item->GetProxy(); - + } } - if (PyInt_Check(pyindex)) + else if (PyInt_Check(pyindex)) { int index = PyInt_AsLong(pyindex); - return listvalue_buffer_item(self, index); + return listvalue_buffer_item(self, index); /* wont add a ref */ } PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */ diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index c3c738a8183..65a026656c5 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -715,6 +715,7 @@ void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras) mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame); if(!obj) return; + obj->Release(); /* FindValue() AddRef's */ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); From df01af5a1f05d03ad1464bca1fcbffe495ca0539 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 9 May 2009 18:18:04 +0000 Subject: [PATCH 189/444] Methods didn't check for zombies which could crash in the case where a method for an object is kept. func = ob.getMass ...remove ob... func() # crash 2 More refcount fixes spotted by Benoit too --- source/gameengine/Expressions/PyObjectPlus.h | 8 ++++++++ source/gameengine/Ketsji/KX_GameObject.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index c21dc3a6e57..b7f22404c7a 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -225,30 +225,35 @@ typedef struct { #define KX_PYMETHOD(class_name, method_name) \ PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ }; \ #define KX_PYMETHOD_VARARGS(class_name, method_name) \ PyObject* Py##method_name(PyObject* args); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ }; \ #define KX_PYMETHOD_NOARGS(class_name, method_name) \ PyObject* Py##method_name(); \ static PyObject* sPy##method_name( PyObject* self) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ }; \ #define KX_PYMETHOD_O(class_name, method_name) \ PyObject* Py##method_name(PyObject* value); \ static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ }; \ #define KX_PYMETHOD_DOC(class_name, method_name) \ PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ }; \ static const char method_name##_doc[]; \ @@ -256,6 +261,7 @@ typedef struct { #define KX_PYMETHOD_DOC_VARARGS(class_name, method_name) \ PyObject* Py##method_name(PyObject* args); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ }; \ static const char method_name##_doc[]; \ @@ -263,6 +269,7 @@ typedef struct { #define KX_PYMETHOD_DOC_O(class_name, method_name) \ PyObject* Py##method_name(PyObject* value); \ static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ }; \ static const char method_name##_doc[]; \ @@ -270,6 +277,7 @@ typedef struct { #define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \ PyObject* Py##method_name(); \ static PyObject* sPy##method_name( PyObject* self) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ }; \ static const char method_name##_doc[]; \ diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 4f3202aafea..c2216fd3514 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1726,7 +1726,7 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE for(i=0; i < (int)self->m_meshes.size(); i++) { KX_MeshProxy* meshproxy = new KX_MeshProxy(self->m_meshes[i]); - PyList_SET_ITEM(meshes, i, meshproxy->GetProxy()); + PyList_SET_ITEM(meshes, i, meshproxy->NewProxy(true)); } return meshes; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 7280071cd1d..208f8fc9461 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1847,5 +1847,9 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time); + + // release here because AddReplicaObject AddRef's + // the object is added to the scene so we dont want python to own a reference + replica->Release(); return replica->GetProxy(); } \ No newline at end of file From 4a2341fe9a53839c4be685070c41f7b0ea980017 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sat, 9 May 2009 21:04:03 +0000 Subject: [PATCH 190/444] =?UTF-8?q?BGE=20Dome:=20Allowing=20FOV=20differen?= =?UTF-8?q?t=20from=20180=C2=BA=20for=20Truncated=20Domes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *) a small note: In the end it turned out that we have upright and downright domes out there. So I may rearrange the order of the gui later: (1 = fisheye, 2 = truncated up, 3 = truncated down, 4 = envmap, 5 = spherical panoramic) I don't plan to do a doVersion() for that, so if you are using it already keep in mind that the modes may change before 249 final release. --- source/gameengine/Ketsji/KX_Dome.cpp | 33 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index a302bf98cb8..429c1b84918 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -125,15 +125,24 @@ KX_Dome::KX_Dome ( m_numfaces = 6; break; default: //DOME_TRUNCATED_DOWN and DOME_TRUNCATED_UP - cubetop.resize(1); - cubebottom.resize(1); - cubeleft.resize(2); - cuberight.resize(2); + if (m_angle <= 180){ + cubetop.resize(1); + cubebottom.resize(1); + cubeleft.resize(2); + cuberight.resize(2); - m_angle = 180; - CreateMeshDome180(); - m_numfaces = 4; - break; + CreateMeshDome180(); + m_numfaces = 4; + }else if (m_angle > 180){ + cubetop.resize(2); + cubebottom.resize(2); + cubeleft.resize(2); + cubefront.resize(2); + cuberight.resize(2); + + CreateMeshDome250(); + m_numfaces = 5; + } break; } m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces); @@ -1485,9 +1494,9 @@ Uses 6 cameras for angles up to 360 MT_Scalar c = cos(deg45); MT_Scalar s = sin(deg45); - if ((m_mode == DOME_FISHEYE && m_angle <= 180) + if (m_angle <= 180 && (m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_UP - || m_mode == DOME_TRUNCATED_DOWN){ + || m_mode == DOME_TRUNCATED_DOWN)){ m_locRot[0] = MT_Matrix3x3( // 90º - Top c, -s, 0.0, @@ -1509,7 +1518,9 @@ Uses 6 cameras for angles up to 360 0.0, 1.0, 0.0, s, 0.0, c); - } else if ((m_mode == DOME_FISHEYE && m_angle > 180) || m_mode == DOME_ENVMAP){ + } else if (m_mode == DOME_ENVMAP || (m_angle > 180 && (m_mode == DOME_FISHEYE + || m_mode == DOME_TRUNCATED_UP + || m_mode == DOME_TRUNCATED_DOWN))){ m_locRot[0] = MT_Matrix3x3( // 90º - Top 1.0, 0.0, 0.0, From f155da0039104af88379bb354674e32ef2595960 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sat, 9 May 2009 21:54:22 +0000 Subject: [PATCH 191/444] BGE Dome: Reducing FBO size to warped meshes. Commit 20099 started using a FBO way too big. According to Paul Bourke this is how it's done in other Engines: Projectors HD: 1920x1050 - buffersize = 1024; FBO size = 2048 1400x1050 - buffersize = 1024; FBO size = 2048 Projectors XGA: 1024x768 - buffersize = 512; FBO size = 1024 Now in Blender Game Engine we are using: Projectors HD: 1920x1050 - buffersize = 1050; FBO size = 2048 1400x1050 - buffersize = 1050; FBO size = 2048 Projectors XGA: 1024x768 - buffersize = 768; FBO size = 1024 (I guess I should be committing code to the ge_dome branch instead of the trunk. I feel bad doing all those adjustments in a hurry to 2.49 final release in the trunk. That is ok, right?) --- source/gameengine/Ketsji/KX_Dome.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 429c1b84918..25efe0a59c9 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -251,15 +251,10 @@ http://projects.blender.org/tracker/?func=detail&aid=18655&group_id=9&atid=125 m_imagesize = (1 << i); if (warp.usemesh){ - // trying to use twice the size of the cube faces - GLint glMaxTexDim; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); - - if (2 * m_imagesize > glMaxTexDim) - warp.imagesize = m_imagesize; - - else - warp.imagesize = 2 * m_imagesize; + // warp FBO needs to be up to twice as big as m_buffersize to get more resolution + warp.imagesize = m_imagesize; + if (m_buffersize == m_imagesize) + warp.imagesize *= 2; //if FBO is not working/supported, we use the canvas dimension as buffer warp.bufferwidth = canvaswidth; From 136d4c34badc12b72f5c3541fcdaf2b1459af408 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 May 2009 01:48:14 +0000 Subject: [PATCH 192/444] deprecate controller.getActuator(name) and controller.getSensor(name) for controller.actuators[name] and controller.sensors[name] Made a read-only sequence type for logic brick sensors and actuators which can access single items or be used like a list or dictionary. We could use a python dictionary or CValueList but that would be slower to create. So you can do... for s in controller.sensors: print s print controller.sensors["Sensor"] print controller.sensors[0] sensors = list(controller.sensors) This sequence type keeps a reference to the proxy it came from and will raise an error on access if the proxy has been removed. --- .../gameengine/Expressions/PyObjectPlus.cpp | 1 - .../gameengine/GameLogic/SCA_IController.cpp | 30 +- source/gameengine/Ketsji/KX_GameObject.cpp | 28 +- source/gameengine/Ketsji/KX_PythonSeq.cpp | 384 ++++++++++++++++++ source/gameengine/Ketsji/KX_PythonSeq.h | 60 +++ source/gameengine/PyDoc/KX_GameObject.py | 6 +- source/gameengine/PyDoc/SCA_IController.py | 8 +- 7 files changed, 465 insertions(+), 52 deletions(-) create mode 100644 source/gameengine/Ketsji/KX_PythonSeq.cpp create mode 100644 source/gameengine/Ketsji/KX_PythonSeq.h diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 7d302246c70..7026db5b8a4 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -981,6 +981,5 @@ void PyObjectPlus::SetDeprecationWarningFirst(WarnLink* wlink) {m_base_wlink_f void PyObjectPlus::SetDeprecationWarningLinkLast(WarnLink* wlink) {m_base_wlink_last= wlink;} void PyObjectPlus::NullDeprecationWarning() {m_base_wlink_first= m_base_wlink_last= NULL;} - #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index 8bf21ed8264..24509f6e6ed 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -31,6 +31,7 @@ #include "SCA_IActuator.h" #include "SCA_ISensor.h" #include "PyObjectPlus.h" +#include "../Ketsji/KX_PythonSeq.h" /* not nice, only need for KX_PythonSeq_CreatePyObject */ #ifdef HAVE_CONFIG_H #include @@ -241,10 +242,9 @@ PyParentObject SCA_IController::Parents[] = { }; PyMethodDef SCA_IController::Methods[] = { - {"getActuator", (PyCFunction) SCA_IController::sPyGetActuator, METH_O}, - {"getSensor", (PyCFunction) SCA_IController::sPyGetSensor, METH_O}, - //Deprecated functions ------> + {"getSensor", (PyCFunction) SCA_IController::sPyGetSensor, METH_O}, + {"getActuator", (PyCFunction) SCA_IController::sPyGetActuator, METH_O}, {"getSensors", (PyCFunction) SCA_IController::sPyGetSensors, METH_NOARGS}, {"getActuators", (PyCFunction) SCA_IController::sPyGetActuators, METH_NOARGS}, {"getState", (PyCFunction) SCA_IController::sPyGetState, METH_NOARGS}, @@ -290,7 +290,8 @@ PyObject* SCA_IController::PyGetActuators() PyObject* SCA_IController::PyGetSensor(PyObject* value) { - + ShowDeprecationWarning("getSensor(string)", "the sensors[string] property"); + char *scriptArg = PyString_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)"); @@ -313,7 +314,8 @@ PyObject* SCA_IController::PyGetSensor(PyObject* value) PyObject* SCA_IController::PyGetActuator(PyObject* value) { - + ShowDeprecationWarning("getActuator(string)", "the actuators[string] property"); + char *scriptArg = PyString_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)"); @@ -360,24 +362,10 @@ PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_D PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - SCA_IController* self= static_cast(self_v); - vector linkedsensors = self->GetLinkedSensors(); - PyObject* resultlist = PyList_New(linkedsensors.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_SENSORS); } PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - SCA_IController* self= static_cast(self_v); - vector linkedactuators = self->GetLinkedActuators(); - PyObject* resultlist = PyList_New(linkedactuators.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_ACTUATORS); } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index c2216fd3514..2f5b5631761 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -63,6 +63,7 @@ typedef unsigned long uint_ptr; #include "KX_RayCast.h" #include "KX_PythonInit.h" #include "KX_PyMath.h" +#include "KX_PythonSeq.h" #include "SCA_IActuator.h" #include "SCA_ISensor.h" #include "SCA_IController.h" @@ -1735,38 +1736,17 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE /* experemental! */ PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - KX_GameObject* self= static_cast(self_v); - SCA_SensorList& sensors= self->GetSensors(); - PyObject* resultlist = PyList_New(sensors.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_SENSORS); } PyObject* KX_GameObject::pyattr_get_controllers(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - KX_GameObject* self= static_cast(self_v); - SCA_ControllerList& controllers= self->GetControllers(); - PyObject* resultlist = PyList_New(controllers.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CONTROLLERS); } PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - KX_GameObject* self= static_cast(self_v); - SCA_ActuatorList& actuators= self->GetActuators(); - PyObject* resultlist = PyList_New(actuators.size()); - - for (unsigned int index=0;indexGetProxy()); - - return resultlist; + return KX_PythonSeq_CreatePyObject((static_cast(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_ACTUATORS); } PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp new file mode 100644 index 00000000000..c3ae35fa47c --- /dev/null +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -0,0 +1,384 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * Readonly sequence wrapper for lookups on logic bricks + */ + + +#include "KX_PythonSeq.h" +#include "KX_GameObject.h" +#include "SCA_ISensor.h" +#include "SCA_IController.h" +#include "SCA_IActuator.h" + + +PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type ) +{ + KX_PythonSeq *seq = PyObject_NEW( KX_PythonSeq, &KX_PythonSeq_Type); + seq->base = base; + Py_INCREF(base); /* so we can always access to check if its valid */ + seq->type = type; + seq->iter = -1; /* init */ + return (PyObject *)seq; + } + + static void KX_PythonSeq_dealloc( KX_PythonSeq * self ) +{ + Py_DECREF(self->base); + PyObject_DEL( self ); +} + +static int KX_PythonSeq_len( KX_PythonSeq * self ) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return -1; + } + + switch(self->type) { + case KX_PYGENSEQ_CONT_TYPE_SENSORS: + return ((SCA_IController *)self_plus)->GetLinkedSensors().size(); + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + return ((SCA_IController *)self_plus)->GetLinkedActuators().size(); + case KX_PYGENSEQ_OB_TYPE_SENSORS: + return ((KX_GameObject *)self_plus)->GetSensors().size(); + case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: + return ((KX_GameObject *)self_plus)->GetControllers().size(); + case KX_PYGENSEQ_OB_TYPE_ACTUATORS: + return ((KX_GameObject *)self_plus)->GetActuators().size(); + default: + /* Should never happen */ + PyErr_SetString(PyExc_SystemError, "invalid type, internal error"); + return -1; + } +} + +static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + NULL; + } + + switch(self->type) { + case KX_PYGENSEQ_CONT_TYPE_SENSORS: + { + vector linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + SCA_ISensor* sensor; + if(index<0) index += linkedsensors.size(); + if(index<0 || index>= linkedsensors.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedsensors[index]->GetProxy(); + } + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + { + vector linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + SCA_IActuator* sensor; + if(index<0) index += linkedactuators.size(); + if(index<0 || index>= linkedactuators.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedactuators[index]->GetProxy(); + } + case KX_PYGENSEQ_OB_TYPE_SENSORS: + { + SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); + SCA_ISensor *sensor; + if(index<0) index += linkedsensors.size(); + if(index<0 || index>= linkedsensors.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedsensors[index]->GetProxy(); + } + case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: + { + SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); + SCA_IController *controller; + if(index<0) index += linkedcontrollers.size(); + if(index<0 || index>= linkedcontrollers.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedcontrollers[index]->GetProxy(); + } + case KX_PYGENSEQ_OB_TYPE_ACTUATORS: + { + SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); + SCA_IActuator *actuator; + if(index<0) index += linkedactuators.size(); + if(index<0 || index>= linkedactuators.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedactuators[index]->GetProxy(); + } + } +} + + +static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); + char *name = NULL; + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return NULL; + } + + if (PyInt_Check(key)) { + return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key )); + } else if ( PyString_Check(key) ) { + name = PyString_AsString( key ); + } else { + PyErr_SetString( PyExc_TypeError, "expected a string or an index" ); + return NULL; + } + + switch(self->type) { + case KX_PYGENSEQ_CONT_TYPE_SENSORS: + { + vector linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + SCA_ISensor* sensor; + for (unsigned int index=0;indexGetName() == name) + return sensor->GetProxy(); + } + break; + } + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + { + vector linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + SCA_IActuator* sensor; + for (unsigned int index=0;indexGetName() == name) + return sensor->GetProxy(); + } + break; + } + case KX_PYGENSEQ_OB_TYPE_SENSORS: + { + SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); + SCA_ISensor *sensor; + for (unsigned int index=0;indexGetName() == name) + return sensor->GetProxy(); + } + break; + } + case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: + { + SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); + SCA_IController *controller; + for (unsigned int index=0;indexGetName() == name) + return controller->GetProxy(); + } + break; + } + case KX_PYGENSEQ_OB_TYPE_ACTUATORS: + { + SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); + SCA_IActuator *actuator; + for (unsigned int index=0;indexGetName() == name) + return actuator->GetProxy(); + } + break; + } + } + + PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name); + return NULL; +} + +static PyMappingMethods KX_PythonSeq_as_mapping = { + ( inquiry ) KX_PythonSeq_len, /* mp_length */ + ( binaryfunc ) KX_PythonSeq_subscript, /* mp_subscript */ + ( objobjargproc ) 0, /* mp_ass_subscript */ +}; + + +/* + * Initialize the interator index + */ + +static PyObject *KX_PythonSeq_getIter( KX_PythonSeq * self ) +{ + if(BGE_PROXY_REF(self->base)==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + NULL; + } + + /* create a new iterator if were alredy using this one */ + if (self->iter == -1) { + self->iter = 0; + Py_INCREF(self); + return (PyObject *)self; + } else { + return KX_PythonSeq_CreatePyObject(self->base, self->type); + } + } + + +/* + * Return next KX_PythonSeq iter. + */ + +static PyObject *KX_PythonSeq_nextIter( KX_PythonSeq * self ) +{ + PyObject *object = KX_PythonSeq_getIndex(self, self->iter); + + self->iter++; + if( object==NULL ) { + self->iter= -1; /* for reuse */ + PyErr_SetString(PyExc_StopIteration, "iterator at end"); + } + return object; /* can be NULL for end of iterator */ +} + + +static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) /* TODO - python3.x wants richcmp */ +{ + return ( a->type == b->type && a->base == b->base) ? 0 : -1; +} + +/* + * repr function + * convert to a list and get its string value + */ +static PyObject *KX_PythonSeq_repr( KX_PythonSeq * self ) +{ + PyObject *list = PySequence_List((PyObject *)self); + PyObject *repr = PyObject_Repr(list); + Py_DECREF(list); + return repr; +} + + +/*****************************************************************************/ +/* Python KX_PythonSeq_Type structure definition: */ +/*****************************************************************************/ +PyTypeObject KX_PythonSeq_Type = { +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif + /* For printing, in format "." */ + "KX_PythonSeq", /* char *tp_name; */ + sizeof( KX_PythonSeq ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) KX_PythonSeq_dealloc, /* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + ( cmpfunc ) KX_PythonSeq_compare, /* cmpfunc tp_compare; */ + ( reprfunc ) KX_PythonSeq_repr, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + &KX_PythonSeq_as_mapping, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + ( getiterfunc) KX_PythonSeq_getIter, /* getiterfunc tp_iter; */ + ( iternextfunc ) KX_PythonSeq_nextIter, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h new file mode 100644 index 00000000000..15a016224a9 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PythonSeq.h @@ -0,0 +1,60 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * Readonly sequence wrapper for lookups on logic bricks + */ + +#ifndef _adr_py_seq_h_ // only process once, +#define _adr_py_seq_h_ // even if multiply included + +#include "PyObjectPlus.h" + +// ------------------------- +enum KX_PYGENSEQ_TYPE { + KX_PYGENSEQ_CONT_TYPE_SENSORS, + KX_PYGENSEQ_CONT_TYPE_ACTUATORS, + KX_PYGENSEQ_OB_TYPE_SENSORS, + KX_PYGENSEQ_OB_TYPE_CONTROLLERS, + KX_PYGENSEQ_OB_TYPE_ACTUATORS +}; + +/* The Main PyType Object defined in Main.c */ +extern PyTypeObject KX_PythonSeq_Type; + +#define BPy_KX_PythonSeq_Check(v) \ + ((v)->ob_type == &KX_PythonSeq_Type) + +typedef struct { + PyObject_VAR_HEAD + PyObject *base; + short type; + short iter; +} KX_PythonSeq; + +PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type); + +#endif // _adr_py_seq_h_ diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 0f9bfea98f3..257a25e8ad9 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -67,15 +67,15 @@ class KX_GameObject(SCA_IObject): - note: Most objects use only 1 mesh. - note: Changes to this list will not update the KX_GameObject. @type meshes: list of L{KX_MeshProxy} - @ivar sensors: a list of L{SCA_ISensor} objects. + @ivar sensors: a sequence of L{SCA_ISensor} objects with string/index lookups and iterator support. - note: This attribute is experemental and may be removed (but probably wont be). - note: Changes to this list will not update the KX_GameObject. @type sensors: list - @ivar controllers: a list of L{SCA_IController} objects. + @ivar controllers: a sequence of L{SCA_IController} objects with string/index lookups and iterator support. - note: This attribute is experemental and may be removed (but probably wont be). - note: Changes to this list will not update the KX_GameObject. @type controllers: list of L{SCA_ISensor}. - @ivar actuators: a list of L{SCA_IActuator} objects. + @ivar actuators: a list of L{SCA_IActuator} with string/index lookups and iterator support. - note: This attribute is experemental and may be removed (but probably wont be). - note: Changes to this list will not update the KX_GameObject. @type actuators: list diff --git a/source/gameengine/PyDoc/SCA_IController.py b/source/gameengine/PyDoc/SCA_IController.py index 3e6ee45e115..cfb4c18a826 100644 --- a/source/gameengine/PyDoc/SCA_IController.py +++ b/source/gameengine/PyDoc/SCA_IController.py @@ -12,13 +12,13 @@ class SCA_IController(SCA_ILogicBrick): @ivar sensors: a list of sensors linked to this controller - note: the sensors are not necessarily owned by the same object. - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. - @type sensors: list + @type sensors: sequence supporting index/string lookups and iteration. @ivar actuators: a list of actuators linked to this controller. - note: the sensors are not necessarily owned by the same object. - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. - @type actuators: list + @type actuators: sequence supporting index/string lookups and iteration. - @group Deprecated: getState, getSensors, getActuators + @group Deprecated: getState, getSensors, getActuators, getSensor, getActuator """ def getState(): @@ -39,6 +39,7 @@ class SCA_IController(SCA_ILogicBrick): """ def getSensor(name): """ + DEPRECATED: use the sensors[name] property Gets the named linked sensor. @type name: string @@ -53,6 +54,7 @@ class SCA_IController(SCA_ILogicBrick): """ def getActuator(name): """ + DEPRECATED: use the actuators[name] property Gets the named linked actuator. @type name: string From 6f5ef6044dabdd383a91a14c65a2f9f454fb5c42 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 May 2009 15:23:18 +0000 Subject: [PATCH 193/444] remove unneeded vars and wasn't returning on some errors --- source/gameengine/Ketsji/KX_PythonSeq.cpp | 24 +++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index c3ae35fa47c..039cf640a6f 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -52,7 +52,7 @@ PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type ) PyObject_DEL( self ); } -static int KX_PythonSeq_len( KX_PythonSeq * self ) +static Py_ssize_t KX_PythonSeq_len( KX_PythonSeq * self ) { PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); @@ -85,14 +85,13 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) if(self_plus==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - NULL; + return NULL; } switch(self->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: { vector linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); - SCA_ISensor* sensor; if(index<0) index += linkedsensors.size(); if(index<0 || index>= linkedsensors.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -103,7 +102,6 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: { vector linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); - SCA_IActuator* sensor; if(index<0) index += linkedactuators.size(); if(index<0 || index>= linkedactuators.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -114,7 +112,6 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) case KX_PYGENSEQ_OB_TYPE_SENSORS: { SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); - SCA_ISensor *sensor; if(index<0) index += linkedsensors.size(); if(index<0 || index>= linkedsensors.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -125,7 +122,6 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: { SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); - SCA_IController *controller; if(index<0) index += linkedcontrollers.size(); if(index<0 || index>= linkedcontrollers.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -136,7 +132,6 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) case KX_PYGENSEQ_OB_TYPE_ACTUATORS: { SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); - SCA_IActuator *actuator; if(index<0) index += linkedactuators.size(); if(index<0 || index>= linkedactuators.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -145,6 +140,9 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) return linkedactuators[index]->GetProxy(); } } + + PyErr_SetString(PyExc_SystemError, "invalid sequence type, this is a bug"); + return NULL; } @@ -182,11 +180,11 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: { vector linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); - SCA_IActuator* sensor; + SCA_IActuator* actuator; for (unsigned int index=0;indexGetName() == name) - return sensor->GetProxy(); + actuator = linkedactuators[index]; + if (actuator->GetName() == name) + return actuator->GetProxy(); } break; } @@ -232,7 +230,7 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) static PyMappingMethods KX_PythonSeq_as_mapping = { ( inquiry ) KX_PythonSeq_len, /* mp_length */ ( binaryfunc ) KX_PythonSeq_subscript, /* mp_subscript */ - ( objobjargproc ) 0, /* mp_ass_subscript */ + 0, /* mp_ass_subscript */ }; @@ -244,7 +242,7 @@ static PyObject *KX_PythonSeq_getIter( KX_PythonSeq * self ) { if(BGE_PROXY_REF(self->base)==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - NULL; + return NULL; } /* create a new iterator if were alredy using this one */ From 386122ada6432b29437c3ca7f1eea2b5b919d377 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 10 May 2009 20:53:58 +0000 Subject: [PATCH 194/444] BGE performance, 4th round: logic This commit extends the technique of dynamic linked list to the logic system to eliminate as much as possible temporaries, map lookup or full scan. The logic engine is now free of memory allocation, which is an important stability factor. The overhead of the logic system is reduced by a factor between 3 and 6 depending on the logic setup. This is the speed-up you can expect on a logic setup using simple bricks. Heavy bricks like python controllers and ray sensors will still take about the same time to execute so the speed up will be less important. The core of the logic engine has been much reworked but the functionality is still the same except for one thing: the priority system on the execution of controllers. The exact same remark applies to actuators but I'll explain for controllers only: Previously, it was possible, with the "executePriority" attribute to set a controller to run before any other controllers in the game. Other than that, the sequential execution of controllers, as defined in Blender was guaranteed by default. With the new system, the sequential execution of controllers is still guaranteed but only within the controllers of one object. the user can no longer set a controller to run before any other controllers in the game. The "executePriority" attribute controls the execution of controllers within one object. The priority is a small number starting from 0 for the first controller and incrementing for each controller. If this missing feature is a must, a special method can be implemented to set a controller to run before all other controllers. Other improvements: - Systematic use of reference in parameter passing to avoid unnecessary data copy - Use pre increment in iterator instead of post increment to avoid temporary allocation - Use const char* instead of STR_String whenever possible to avoid temporary allocation - Fix reference counting bugs (memory leak) - Fix a crash in certain cases of state switching and object deletion - Minor speed up in property sensor - Removal of objects during the game is a lot faster --- .../expression/EXP_expressions.vcproj | 13 +- .../gameengine/gamelogic/SCA_GameLogic.vcproj | 13 +- .../gameengine/ketsji/KX_ketsji.vcproj | 8 + .../ketsji/network/KX_network.vcproj | 13 +- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 2 +- .../Converter/BL_ActionActuator.cpp | 13 +- .../Converter/BL_BlenderDataConversion.cpp | 8 +- .../Converter/BL_ShapeActionActuator.cpp | 13 +- .../Converter/KX_ConvertActuators.cpp | 14 +- .../Converter/KX_ConvertActuators.h | 1 - .../Converter/KX_ConvertControllers.cpp | 21 +- .../Converter/KX_ConvertControllers.h | 1 - .../Converter/KX_ConvertSensors.cpp | 310 +++++++++-------- .../gameengine/Converter/KX_ConvertSensors.h | 1 - source/gameengine/Expressions/BoolValue.cpp | 8 +- source/gameengine/Expressions/BoolValue.h | 5 +- source/gameengine/Expressions/CMakeLists.txt | 1 + source/gameengine/Expressions/ErrorValue.cpp | 6 +- source/gameengine/Expressions/ErrorValue.h | 2 +- source/gameengine/Expressions/FloatValue.cpp | 2 +- source/gameengine/Expressions/FloatValue.h | 2 +- source/gameengine/Expressions/IfExpr.cpp | 7 +- source/gameengine/Expressions/InputParser.cpp | 10 +- source/gameengine/Expressions/InputParser.h | 10 +- source/gameengine/Expressions/IntValue.cpp | 2 +- source/gameengine/Expressions/IntValue.h | 2 +- source/gameengine/Expressions/ListValue.cpp | 12 +- source/gameengine/Expressions/ListValue.h | 2 +- source/gameengine/Expressions/Makefile | 1 + .../gameengine/Expressions/PyObjectPlus.cpp | 2 +- source/gameengine/Expressions/PyObjectPlus.h | 14 +- source/gameengine/Expressions/SConscript | 2 +- source/gameengine/Expressions/StringValue.cpp | 2 +- source/gameengine/Expressions/StringValue.h | 2 +- source/gameengine/Expressions/Value.cpp | 10 +- source/gameengine/Expressions/Value.h | 39 +-- source/gameengine/Expressions/VectorValue.cpp | 2 +- source/gameengine/Expressions/VectorValue.h | 2 +- source/gameengine/GameLogic/CMakeLists.txt | 1 + source/gameengine/GameLogic/Makefile | 1 + .../GameLogic/SCA_2DFilterActuator.cpp | 2 +- .../GameLogic/SCA_2DFilterActuator.h | 2 +- .../GameLogic/SCA_ANDController.cpp | 11 +- .../GameLogic/SCA_ActuatorEventManager.cpp | 10 +- .../GameLogic/SCA_ActuatorSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_ActuatorSensor.h | 2 +- .../GameLogic/SCA_AlwaysEventManager.cpp | 5 +- .../gameengine/GameLogic/SCA_AlwaysSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_AlwaysSensor.h | 2 +- .../gameengine/GameLogic/SCA_DelaySensor.cpp | 2 +- source/gameengine/GameLogic/SCA_DelaySensor.h | 2 +- .../gameengine/GameLogic/SCA_EventManager.cpp | 7 +- .../gameengine/GameLogic/SCA_EventManager.h | 5 +- .../GameLogic/SCA_ExpressionController.cpp | 25 +- source/gameengine/GameLogic/SCA_IActuator.cpp | 75 ++-- source/gameengine/GameLogic/SCA_IActuator.h | 61 +++- .../gameengine/GameLogic/SCA_IController.cpp | 88 +++-- source/gameengine/GameLogic/SCA_IController.h | 38 ++- .../gameengine/GameLogic/SCA_ILogicBrick.cpp | 10 +- source/gameengine/GameLogic/SCA_ILogicBrick.h | 11 +- source/gameengine/GameLogic/SCA_IObject.cpp | 18 +- source/gameengine/GameLogic/SCA_IObject.h | 30 ++ source/gameengine/GameLogic/SCA_IScene.cpp | 2 +- source/gameengine/GameLogic/SCA_IScene.h | 2 +- source/gameengine/GameLogic/SCA_ISensor.cpp | 87 +++-- source/gameengine/GameLogic/SCA_ISensor.h | 28 +- .../GameLogic/SCA_JoystickManager.cpp | 11 +- .../GameLogic/SCA_JoystickSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_JoystickSensor.h | 2 +- .../GameLogic/SCA_KeyboardManager.cpp | 7 +- .../GameLogic/SCA_KeyboardSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_KeyboardSensor.h | 2 +- .../gameengine/GameLogic/SCA_LogicManager.cpp | 320 +++--------------- .../gameengine/GameLogic/SCA_LogicManager.h | 50 +-- .../gameengine/GameLogic/SCA_MouseManager.cpp | 6 +- .../gameengine/GameLogic/SCA_MouseSensor.cpp | 2 +- source/gameengine/GameLogic/SCA_MouseSensor.h | 2 +- .../GameLogic/SCA_NANDController.cpp | 11 +- .../GameLogic/SCA_NORController.cpp | 11 +- .../gameengine/GameLogic/SCA_ORController.cpp | 9 +- .../GameLogic/SCA_PropertyEventManager.cpp | 5 +- .../GameLogic/SCA_PropertySensor.cpp | 18 +- .../gameengine/GameLogic/SCA_PropertySensor.h | 2 +- .../GameLogic/SCA_PythonController.cpp | 17 +- .../GameLogic/SCA_RandomEventManager.cpp | 5 +- .../gameengine/GameLogic/SCA_RandomSensor.cpp | 2 +- .../gameengine/GameLogic/SCA_RandomSensor.h | 2 +- .../GameLogic/SCA_TimeEventManager.cpp | 6 +- .../GameLogic/SCA_XNORController.cpp | 11 +- .../GameLogic/SCA_XORController.cpp | 11 +- source/gameengine/GameLogic/SConscript | 2 +- .../Ketsji/KXNetwork/CMakeLists.txt | 1 + .../KXNetwork/KX_NetworkEventManager.cpp | 8 +- .../KXNetwork/KX_NetworkMessageActuator.cpp | 2 +- .../KXNetwork/KX_NetworkMessageSensor.cpp | 10 +- .../KXNetwork/KX_NetworkMessageSensor.h | 2 +- source/gameengine/Ketsji/KXNetwork/Makefile | 1 + source/gameengine/Ketsji/KXNetwork/SConscript | 2 +- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 5 +- .../gameengine/Ketsji/KX_CameraActuator.cpp | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 20 +- source/gameengine/Ketsji/KX_GameObject.h | 4 +- source/gameengine/Ketsji/KX_IpoActuator.cpp | 6 +- source/gameengine/Ketsji/KX_MeshProxy.cpp | 13 +- source/gameengine/Ketsji/KX_MeshProxy.h | 6 +- .../gameengine/Ketsji/KX_MouseFocusSensor.cpp | 4 +- .../gameengine/Ketsji/KX_MouseFocusSensor.h | 2 +- source/gameengine/Ketsji/KX_NearSensor.cpp | 2 +- source/gameengine/Ketsji/KX_NearSensor.h | 2 +- .../gameengine/Ketsji/KX_ParentActuator.cpp | 2 +- source/gameengine/Ketsji/KX_PolyProxy.cpp | 10 +- source/gameengine/Ketsji/KX_PolyProxy.h | 6 +- source/gameengine/Ketsji/KX_PythonSeq.cpp | 8 +- .../gameengine/Ketsji/KX_RayEventManager.cpp | 5 +- source/gameengine/Ketsji/KX_RaySensor.cpp | 2 +- source/gameengine/Ketsji/KX_RaySensor.h | 2 +- .../Ketsji/KX_SCA_AddObjectActuator.cpp | 26 +- source/gameengine/Ketsji/KX_Scene.cpp | 64 ++-- source/gameengine/Ketsji/KX_Scene.h | 7 - source/gameengine/Ketsji/KX_SoundActuator.cpp | 18 +- source/gameengine/Ketsji/KX_SoundActuator.h | 1 + .../Ketsji/KX_TouchEventManager.cpp | 25 +- source/gameengine/Ketsji/KX_TouchSensor.cpp | 4 +- source/gameengine/Ketsji/KX_TouchSensor.h | 2 +- .../gameengine/Ketsji/KX_TrackToActuator.cpp | 17 +- source/gameengine/Ketsji/KX_VertexProxy.cpp | 12 +- source/gameengine/Ketsji/KX_VertexProxy.h | 6 +- source/gameengine/Network/NG_NetworkScene.cpp | 4 +- .../Rasterizer/RAS_BucketManager.cpp | 12 - .../gameengine/Rasterizer/RAS_MeshObject.cpp | 4 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 4 +- source/gameengine/SceneGraph/SG_DList.h | 44 ++- source/gameengine/SceneGraph/SG_QList.h | 43 ++- 133 files changed, 961 insertions(+), 1086 deletions(-) diff --git a/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj b/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj index 436a007dffb..a8b94c3f4a0 100644 --- a/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj +++ b/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="EXP_expressions" ProjectGUID="{EADC3C5A-6C51-4F03-8038-1553E7D7F740}" + RootNamespace="EXP_expressions" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ + + @@ -890,6 +894,10 @@ RelativePath="..\..\..\source\gameengine\Ketsji\KX_PythonInitTypes.h" > + + diff --git a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj index a3f43b01763..b6d3aa5e4bb 100644 --- a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj +++ b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="KX_network" ProjectGUID="{6E24BF09-9653-4166-A871-F65CC9E98A9B}" + RootNamespace="KX_network" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ GetPropertyText("Text"); + const STR_String& mytext = ((CValue*)m_clientobject)->GetPropertyText("Text"); const unsigned int flag = polymat->GetFlag(); struct MTFace* tface = 0; diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 646a65d347b..145cb1f22de 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -156,16 +156,9 @@ bool BL_ActionActuator::Update(double curtime, bool frame) // maybe there are events for us in the queue ! if (frame) { - for (vector::iterator i=m_events.begin(); !(i==m_events.end());i++) - { - if ((*i)->GetNumber() == 0.0f) - bNegativeEvent = true; - else - bPositiveEvent= true; - (*i)->Release(); - - } - m_events.clear(); + bNegativeEvent = m_negevent; + bPositiveEvent = m_posevent; + RemoveAllEvents(); if (bPositiveEvent) m_flag |= ACT_FLAG_ACTIVE; diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 1d2b275cab9..7d0bbbe107c 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2610,8 +2610,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, templist->Release(); sumolist->Release(); - int executePriority=0; /* incremented by converter routines */ - // convert global sound stuff /* XXX, glob is the very very wrong place for this @@ -2642,7 +2640,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, struct Object* blenderobj = converter->FindBlenderObject(gameobj); int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; - BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,isInActiveLayer,rendertools,converter); + BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,layerMask,isInActiveLayer,rendertools,converter); } for ( i=0;iGetCount();i++) { @@ -2650,7 +2648,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, struct Object* blenderobj = converter->FindBlenderObject(gameobj); int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; - BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,isInActiveLayer,converter); + BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,layerMask,isInActiveLayer,converter); } for ( i=0;iGetCount();i++) { @@ -2658,7 +2656,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, struct Object* blenderobj = converter->FindBlenderObject(gameobj); int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; - BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter); + BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,keydev,layerMask,isInActiveLayer,canvas,converter); // set the init state to all objects gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 5fea568dcb2..29bbe9b3d7d 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -160,16 +160,9 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame) // maybe there are events for us in the queue ! if (frame) { - for (vector::iterator i=m_events.begin(); !(i==m_events.end());i++) - { - if ((*i)->GetNumber() == 0.0f) - bNegativeEvent = true; - else - bPositiveEvent= true; - (*i)->Release(); - - } - m_events.clear(); + bNegativeEvent = m_negevent; + bPositiveEvent = m_posevent; + RemoveAllEvents(); if (bPositiveEvent) m_flag |= ACT_FLAG_ACTIVE; diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 73d35a78ded..76b8540118a 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -105,7 +105,6 @@ void BL_ConvertActuators(char* maggiename, SCA_LogicManager* logicmgr, KX_Scene* scene, KX_KetsjiEngine* ketsjiEngine, - int & executePriority, int activeLayerBitInfo, bool isInActiveLayer, RAS_IRenderTools* rendertools, @@ -114,11 +113,20 @@ void BL_ConvertActuators(char* maggiename, { int uniqueint = 0; + int actcount = 0; + int executePriority = 0; bActuator* bact = (bActuator*) blenderobject->actuators.first; + while (bact) + { + actcount++; + bact = bact->next; + } + gameobj->ReserveActuator(actcount); + bact = (bActuator*) blenderobject->actuators.first; while(bact) { STR_String uniquename = bact->name; - STR_String objectname = gameobj->GetName(); + STR_String& objectname = gameobj->GetName(); SCA_IActuator* baseact = NULL; switch (bact->type) @@ -1144,7 +1152,7 @@ void BL_ConvertActuators(char* maggiename, CIntValue* uniqueval = new CIntValue(uniqueint); uniquename += uniqueval->GetText(); uniqueval->Release(); - baseact->SetName(STR_String(bact->name)); + baseact->SetName(bact->name); //gameobj->SetProperty(uniquename,baseact); gameobj->AddActuator(baseact); diff --git a/source/gameengine/Converter/KX_ConvertActuators.h b/source/gameengine/Converter/KX_ConvertActuators.h index 03ea0db99b9..e38a9c74efc 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.h +++ b/source/gameengine/Converter/KX_ConvertActuators.h @@ -35,7 +35,6 @@ void BL_ConvertActuators(char* maggiename, class SCA_LogicManager* logicmgr, class KX_Scene* scene, class KX_KetsjiEngine* ketsjiEngine, - int & executePriority, int activeLayerBitInfo, bool isInActiveLayer, class RAS_IRenderTools* rendertools, diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp index 856f3f79588..9b0e27b573a 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.cpp +++ b/source/gameengine/Converter/KX_ConvertControllers.cpp @@ -76,6 +76,7 @@ LinkControllerToActuators( // Iterate through the actuators of the game blender // controller and find the corresponding ketsji actuator. + game_controller->ReserveActuator(bcontr->totlinks); for (int i=0;itotlinks;i++) { bActuator* bact = (bActuator*) bcontr->links[i]; @@ -92,14 +93,22 @@ void BL_ConvertControllers( class KX_GameObject* gameobj, SCA_LogicManager* logicmgr, PyObject* pythondictionary, - int &executePriority, int activeLayerBitInfo, bool isInActiveLayer, KX_BlenderSceneConverter* converter ) { int uniqueint=0; + int count = 0; + int executePriority=0; bController* bcontr = (bController*)blenderobject->controllers.first; while (bcontr) + { + bcontr = bcontr->next; + count++; + } + gameobj->ReserveController(count); + bcontr = (bController*)blenderobject->controllers.first; + while (bcontr) { SCA_IController* gamecontroller = NULL; switch(bcontr->type) @@ -107,37 +116,31 @@ void BL_ConvertControllers( case CONT_LOGIC_AND: { gamecontroller = new SCA_ANDController(gameobj); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } case CONT_LOGIC_OR: { gamecontroller = new SCA_ORController(gameobj); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } case CONT_LOGIC_NAND: { gamecontroller = new SCA_NANDController(gameobj); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } case CONT_LOGIC_NOR: { gamecontroller = new SCA_NORController(gameobj); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } case CONT_LOGIC_XOR: { gamecontroller = new SCA_XORController(gameobj); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } case CONT_LOGIC_XNOR: { gamecontroller = new SCA_XNORController(gameobj); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } case CONT_EXPRESSION: @@ -147,8 +150,6 @@ void BL_ConvertControllers( if (expressiontext.Length() > 0) { gamecontroller = new SCA_ExpressionController(gameobj,expressiontext); - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); - } break; } @@ -186,7 +187,6 @@ void BL_ConvertControllers( pyctrl->SetDebug(true); } - LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); break; } default: @@ -197,6 +197,7 @@ void BL_ConvertControllers( if (gamecontroller) { + LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); gamecontroller->SetExecutePriority(executePriority++); gamecontroller->SetState(bcontr->state_mask); STR_String uniquename = bcontr->name; diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h index 3e8a87fc90b..d340778290c 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.h +++ b/source/gameengine/Converter/KX_ConvertControllers.h @@ -36,7 +36,6 @@ void BL_ConvertControllers( class KX_GameObject* gameobj, class SCA_LogicManager* logicmgr, PyObject* pythondictionary, - int & executePriority, int activeLayerBitInfo, bool isInActiveLayer, class KX_BlenderSceneConverter* converter diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index af57094b2b5..07b0abae6df 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -94,161 +94,166 @@ void BL_ConvertSensors(struct Object* blenderobject, KX_Scene* kxscene, KX_KetsjiEngine* kxengine, SCA_IInputDevice* keydev, - int & executePriority, int activeLayerBitInfo, bool isInActiveLayer, RAS_ICanvas* canvas, KX_BlenderSceneConverter* converter ) { + static bool reverseTableConverted = false; - - - /* The reverse table. In order to not confuse ourselves, we */ - /* immediately convert all events that come in to KX codes. */ - gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; - gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; - gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; - gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; - gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; - gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; - gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; - - // TIMERS - - gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; - gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; - gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; - gReverseKeyTranslateTable[TIMER3 ] = SCA_IInputDevice::KX_TIMER3; - - // SYSTEM - - gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD; - gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; - gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW; - gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; - gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL; - gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; - gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; - gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; - gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; - gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; - - // standard keyboard - - gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY; - gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY; - gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY; - gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY; - gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY; - gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY; - gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY; - gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY; - gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY; - gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY; - gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY; - gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY; - gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY; - gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY; - gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY; - gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY; - gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY; - gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY; - gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY; - gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY; - gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY; - gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY; - gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY; - gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY; - gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY; - gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY; - - gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; - gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; - gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; - gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; - gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; - gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; - gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; - gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; - gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; - gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; - - gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; - - gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; - gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; - gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; - gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; - gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; - gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; - - gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; - gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY; - gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY; - gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; - gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; - gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; - gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY; - gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; - gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; - gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; - gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; - gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; - gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; - gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; - gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; - gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; - gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; - gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; - - gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; - gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; - gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; - gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; - - gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2; - gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4; - gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6; - gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8; - - gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1; - gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3; - gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5; - gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7; - gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9; - - gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; - gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; - gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; - - gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0; - gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; - gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER; - gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; - - - gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY; - gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY; - gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY; - gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY; - gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY; - gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY; - gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY; - gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY; - gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY; - gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY; - gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY; - gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY; - - gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; - gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; - gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; - gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; - gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; - gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; - + if (!reverseTableConverted) + { + reverseTableConverted = true; + + /* The reverse table. In order to not confuse ourselves, we */ + /* immediately convert all events that come in to KX codes. */ + gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; + gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; + gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; + gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; + gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; + gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; + gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; + + // TIMERS + + gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; + gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; + gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; + gReverseKeyTranslateTable[TIMER3 ] = SCA_IInputDevice::KX_TIMER3; + + // SYSTEM + + gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD; + gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; + gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW; + gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; + gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL; + gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; + gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; + gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; + gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; + gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; + + // standard keyboard + + gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY; + gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY; + gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY; + gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY; + gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY; + gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY; + gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY; + gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY; + gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY; + gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY; + gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY; + gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY; + gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY; + gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY; + gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY; + gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY; + gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY; + gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY; + gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY; + gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY; + gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY; + gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY; + gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY; + gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY; + gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY; + gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY; + + gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; + gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; + gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; + gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; + gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; + gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; + gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; + gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; + gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; + gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; + + gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; + + gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; + gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; + gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; + gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; + gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; + gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; + + gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; + gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY; + gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY; + gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; + gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; + gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; + gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY; + gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; + gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; + gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; + gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; + gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; + gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; + gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; + gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; + gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; + gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; + gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; + + gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; + gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; + gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; + gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; + + gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2; + gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4; + gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6; + gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8; + + gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1; + gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3; + gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5; + gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7; + gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9; + + gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; + gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; + gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; + + gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0; + gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; + gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER; + gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; + + + gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY; + gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY; + gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY; + gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY; + gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY; + gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY; + gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY; + gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY; + gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY; + gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY; + gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY; + gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY; + + gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; + gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; + gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; + gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; + gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; + gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; + } + + int executePriority = 0; int uniqueint = 0; + int count = 0; bSensor* sens = (bSensor*)blenderobject->sensors.first; bool pos_pulsemode = false; bool neg_pulsemode = false; @@ -257,6 +262,13 @@ void BL_ConvertSensors(struct Object* blenderobject, bool level = false; bool tap = false; + while (sens) + { + sens = sens->next; + count++; + } + gameobj->ReserveSensor(count); + sens = (bSensor*)blenderobject->sensors.first; while(sens) { SCA_ISensor* gamesensor=NULL; @@ -758,7 +770,7 @@ void BL_ConvertSensors(struct Object* blenderobject, gamesensor->SetInvert(invert); gamesensor->SetLevel(level); gamesensor->SetTap(tap); - gamesensor->SetName(STR_String(sens->name)); + gamesensor->SetName(sens->name); gameobj->AddSensor(gamesensor); @@ -767,7 +779,7 @@ void BL_ConvertSensors(struct Object* blenderobject, //if (isInActiveLayer) // gamesensor->RegisterToManager(); - + gamesensor->ReserveController(sens->totlinks); for (int i=0;itotlinks;i++) { bController* linkedcont = (bController*) sens->links[i]; diff --git a/source/gameengine/Converter/KX_ConvertSensors.h b/source/gameengine/Converter/KX_ConvertSensors.h index b18ffc10a2a..9162a866768 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.h +++ b/source/gameengine/Converter/KX_ConvertSensors.h @@ -35,7 +35,6 @@ void BL_ConvertSensors(struct Object* blenderobject, class KX_Scene* kxscene, class KX_KetsjiEngine* kxengine, class SCA_IInputDevice* keydev, - int & executePriority , int activeLayerBitInfo, bool isInActiveLayer, class RAS_ICanvas* canvas, diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp index 4e0a71e5a19..d90da8b3a92 100644 --- a/source/gameengine/Expressions/BoolValue.cpp +++ b/source/gameengine/Expressions/BoolValue.cpp @@ -26,6 +26,9 @@ // Construction/Destruction ////////////////////////////////////////////////////////////////////// +const STR_String CBoolValue::sTrueString = "TRUE"; +const STR_String CBoolValue::sFalseString = "FALSE"; + CBoolValue::CBoolValue() /* @@ -45,7 +48,7 @@ CBoolValue::CBoolValue(bool inBool) -CBoolValue::CBoolValue(bool innie,STR_String name,AllocationTYPE alloctype) +CBoolValue::CBoolValue(bool innie,const char *name,AllocationTYPE alloctype) { m_bool = innie; SetName(name); @@ -190,9 +193,6 @@ double CBoolValue::GetNumber() const STR_String& CBoolValue::GetText() { - static STR_String sTrueString = STR_String("TRUE"); - static STR_String sFalseString = STR_String("FALSE"); - return m_bool ? sTrueString : sFalseString; } diff --git a/source/gameengine/Expressions/BoolValue.h b/source/gameengine/Expressions/BoolValue.h index 9352b9d4b92..726619e7193 100644 --- a/source/gameengine/Expressions/BoolValue.h +++ b/source/gameengine/Expressions/BoolValue.h @@ -28,9 +28,12 @@ class CBoolValue : public CPropValue //PLUGIN_DECLARE_SERIAL(CBoolValue,CValue) public: + static const STR_String sTrueString; + static const STR_String sFalseString; + CBoolValue(); CBoolValue(bool inBool); - CBoolValue(bool innie, STR_String name, AllocationTYPE alloctype = CValue::HEAPVALUE); + CBoolValue(bool innie, const char *name, AllocationTYPE alloctype = CValue::HEAPVALUE); virtual const STR_String& GetText(); virtual double GetNumber(); diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index 6b2a835d648..eb87fdcee81 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -31,6 +31,7 @@ SET(INC ../../../source/kernel/gen_system ../../../intern/string ../../../intern/moto/include + ../../../source/gameengine/Scenegraph ${PYTHON_INC} ) diff --git a/source/gameengine/Expressions/ErrorValue.cpp b/source/gameengine/Expressions/ErrorValue.cpp index 651a772db19..a44abf8b22e 100644 --- a/source/gameengine/Expressions/ErrorValue.cpp +++ b/source/gameengine/Expressions/ErrorValue.cpp @@ -34,13 +34,15 @@ effect: constructs a new CErrorValue containing errormessage "Error" -CErrorValue::CErrorValue(STR_String errmsg) +CErrorValue::CErrorValue(const char *errmsg) /* pre: effect: constructs a new CErrorValue containing errormessage errmsg */ { - m_strErrorText = "[" + errmsg + "]"; + m_strErrorText = "["; + m_strErrorText += errmsg; + m_strErrorText += "]"; SetError(true); } diff --git a/source/gameengine/Expressions/ErrorValue.h b/source/gameengine/Expressions/ErrorValue.h index 5b5795196ba..b4b758feea7 100644 --- a/source/gameengine/Expressions/ErrorValue.h +++ b/source/gameengine/Expressions/ErrorValue.h @@ -25,7 +25,7 @@ public: virtual const STR_String & GetText(); virtual double GetNumber(); CErrorValue(); - CErrorValue(STR_String errmsg); + CErrorValue(const char *errmsg); virtual ~CErrorValue(); virtual CValue* Calc(VALUE_OPERATOR op, CValue* val); virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp index a31d3b9a528..4de685a82c1 100644 --- a/source/gameengine/Expressions/FloatValue.cpp +++ b/source/gameengine/Expressions/FloatValue.cpp @@ -50,7 +50,7 @@ effect: constructs a new CFloatValue containing value fl -CFloatValue::CFloatValue(float fl,STR_String name,AllocationTYPE alloctype) +CFloatValue::CFloatValue(float fl,const char *name,AllocationTYPE alloctype) /* pre: effect: constructs a new CFloatValue containing value fl diff --git a/source/gameengine/Expressions/FloatValue.h b/source/gameengine/Expressions/FloatValue.h index 41f70b5c54c..fb75b7c702b 100644 --- a/source/gameengine/Expressions/FloatValue.h +++ b/source/gameengine/Expressions/FloatValue.h @@ -23,7 +23,7 @@ class CFloatValue : public CPropValue public: CFloatValue(); CFloatValue(float fl); - CFloatValue(float fl,STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE); + CFloatValue(float fl,const char *name,AllocationTYPE alloctype=CValue::HEAPVALUE); virtual const STR_String & GetText(); diff --git a/source/gameengine/Expressions/IfExpr.cpp b/source/gameengine/Expressions/IfExpr.cpp index 5d3eb3641ca..fcb37bff52d 100644 --- a/source/gameengine/Expressions/IfExpr.cpp +++ b/source/gameengine/Expressions/IfExpr.cpp @@ -15,6 +15,7 @@ #include "IfExpr.h" #include "EmptyValue.h" #include "ErrorValue.h" +#include "BoolValue.h" #ifdef HAVE_CONFIG_H #include @@ -72,14 +73,14 @@ ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE { CValue *guardval; guardval = m_guard->Calculate(); - STR_String text = guardval->GetText(); + const STR_String& text = guardval->GetText(); guardval->Release(); - if (text == STR_String("TRUE")) + if (&text == &CBoolValue::sTrueString) { return m_e1->Calculate(); } - else if (text == STR_String("FALSE")) + else if (&text == &CBoolValue::sFalseString) { return m_e2->Calculate(); } diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index 91a14f97851..b15b206a38a 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -66,7 +66,7 @@ CParser::~CParser() -void CParser::ScanError(STR_String str) +void CParser::ScanError(const char *str) { // sets the global variable errmsg to an errormessage with // contents str, appending if it already exists @@ -81,7 +81,7 @@ void CParser::ScanError(STR_String str) -CExpression* CParser::Error(STR_String str) +CExpression* CParser::Error(const char *str) { // makes and returns a new CConstExpr filled with an CErrorValue // with string str @@ -537,7 +537,7 @@ CExpression *CParser::Expr() { } CExpression* CParser::ProcessText -(STR_String intext) { +(const char *intext) { // and parses the string in intext and returns it. @@ -574,7 +574,7 @@ CExpression* CParser::ProcessText -float CParser::GetFloat(STR_String txt) +float CParser::GetFloat(STR_String& txt) { // returns parsed text into a float // empty string returns -1 @@ -599,7 +599,7 @@ float CParser::GetFloat(STR_String txt) return result; } -CValue* CParser::GetValue(STR_String txt, bool bFallbackToText) +CValue* CParser::GetValue(STR_String& txt, bool bFallbackToText) { // returns parsed text into a value, // empty string returns NULL value ! diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h index 3d517222639..810bdc244a8 100644 --- a/source/gameengine/Expressions/InputParser.h +++ b/source/gameengine/Expressions/InputParser.h @@ -27,9 +27,9 @@ public: CParser(); virtual ~CParser(); - float GetFloat(STR_String txt); - CValue* GetValue(STR_String txt, bool bFallbackToText=false); - CExpression* ProcessText(STR_String intext); + float GetFloat(STR_String& txt); + CValue* GetValue(STR_String& txt, bool bFallbackToText=false); + CExpression* ProcessText(const char *intext); void SetContext(CValue* context); private: @@ -86,8 +86,8 @@ private: CValue* m_identifierContext;// context in which identifiers are looked up - void ScanError(STR_String str); - CExpression* Error(STR_String str); + void ScanError(const char *str); + CExpression* Error(const char *str); void NextCh(); void TermChar(char c); void DigRep(); diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index 74ec9865fec..227518e9439 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -54,7 +54,7 @@ effect: constructs a new CIntValue containing cInt innie -CIntValue::CIntValue(cInt innie,STR_String name,AllocationTYPE alloctype) +CIntValue::CIntValue(cInt innie,const char *name,AllocationTYPE alloctype) { m_int = innie; SetName(name); diff --git a/source/gameengine/Expressions/IntValue.h b/source/gameengine/Expressions/IntValue.h index 0f3a38b274b..06bf1755749 100644 --- a/source/gameengine/Expressions/IntValue.h +++ b/source/gameengine/Expressions/IntValue.h @@ -32,7 +32,7 @@ public: CIntValue(); CIntValue(cInt innie); CIntValue(cInt innie, - STR_String name, + const char *name, AllocationTYPE alloctype=CValue::HEAPVALUE); virtual CValue* Calc(VALUE_OPERATOR op, diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index f4a801a965b..75ae2cb787f 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -18,6 +18,7 @@ #include "StringValue.h" #include "VoidValue.h" #include +#include "BoolValue.h" #ifdef HAVE_CONFIG_H #include @@ -75,7 +76,7 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) if (PyString_Check(pyindex)) { - STR_String index(PyString_AsString(pyindex)); + const char *index = PyString_AsString(pyindex); CValue *item = ((CListValue*) list)->FindValue(index); if (item) { @@ -394,7 +395,7 @@ void CListValue::ReleaseAndRemoveAll() -CValue* CListValue::FindValue(const STR_String & name) +CValue* CListValue::FindValue(const char * name) { CValue* resultval = NULL; int i=0; @@ -497,13 +498,12 @@ bool CListValue::CheckEqual(CValue* first,CValue* second) if (eqval==NULL) return false; - - STR_String txt = eqval->GetText(); - eqval->Release(); - if (txt=="TRUE") + const STR_String& text = eqval->GetText(); + if (&text==&CBoolValue::sTrueString) { result = true; } + eqval->Release(); return result; } diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 3d88b5aea9c..ad918cbb925 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -45,7 +45,7 @@ public: void SetReleaseOnDestruct(bool bReleaseContents); bool SearchValue(CValue* val); - CValue* FindValue(const STR_String & name); + CValue* FindValue(const char *name); void ReleaseAndRemoveAll(); virtual void SetModified(bool bModified); diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile index 6736149bbcd..a1400c4e461 100644 --- a/source/gameengine/Expressions/Makefile +++ b/source/gameengine/Expressions/Makefile @@ -41,4 +41,5 @@ CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../kernel/gen_system +CPPFLAGS += -I../../gameengine/Scenegraph diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 7026db5b8a4..83c0b25df24 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -104,7 +104,7 @@ void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper PyObject_DEL( self ); }; -PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor +PyObjectPlus::PyObjectPlus(PyTypeObject *T) : SG_QList() // constructor { MT_assert(T != NULL); m_proxy= NULL; diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index b7f22404c7a..b69697f3290 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -38,6 +38,7 @@ #include "KX_Python.h" #include "STR_String.h" +#include "SG_QList.h" /*------------------------------ * Python defines @@ -462,7 +463,18 @@ typedef struct KX_PYATTRIBUTE_DEF { ------------------------------*/ typedef PyTypeObject * PyParentObject; // Define the PyParent Object -class PyObjectPlus +// By making SG_QList the ultimate parent for PyObjectPlus objects, it +// allows to put them in 2 different dynamic lists at the same time +// The use of these links is interesting because they free of memory allocation +// but it's very important not to mess up with them. If you decide that +// the SG_QList or SG_DList component is used for something for a certain class, +// they cannot can be used for anything else at a parent level! +// What these lists are and what they are used for must be carefully documented +// at the level where they are used. +// DON'T MAKE ANY USE OF THESE LIST AT THIS LEVEL, they are already used +// at SCA_IActuator, SCA_ISensor, SCA_IController level which rules out the +// possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level. +class PyObjectPlus : public SG_QList { // The PyObjectPlus abstract class Py_Header; // Always start with Py_Header diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 3d855d40623..9d6823e3879 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('*.cpp') -incs ='. #source/kernel/gen_system #intern/string #intern/moto/include' +incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Scenegraph' incs += ' ' + env['BF_PYTHON_INC'] cxxflags = [] diff --git a/source/gameengine/Expressions/StringValue.cpp b/source/gameengine/Expressions/StringValue.cpp index 857aa97b420..a7033fcf11c 100644 --- a/source/gameengine/Expressions/StringValue.cpp +++ b/source/gameengine/Expressions/StringValue.cpp @@ -34,7 +34,7 @@ effect: constructs a new CStringValue m_strString = "[Illegal String constructor call]"; } -CStringValue::CStringValue(STR_String txt,STR_String name,AllocationTYPE alloctype) +CStringValue::CStringValue(const char *txt,const char *name,AllocationTYPE alloctype) /* pre: effect: constructs a new CStringValue containing text txt diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h index 16575ed7ffa..52f8a580f4d 100644 --- a/source/gameengine/Expressions/StringValue.h +++ b/source/gameengine/Expressions/StringValue.h @@ -26,7 +26,7 @@ class CStringValue : public CPropValue public: /// Construction / destruction CStringValue(); - CStringValue (STR_String txt, STR_String name , AllocationTYPE alloctype = CValue::HEAPVALUE); + CStringValue (const char *txt, const char *name , AllocationTYPE alloctype = CValue::HEAPVALUE); virtual ~CStringValue() { }; diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index a811b39d790..83deeef91a3 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -291,13 +291,17 @@ CValue* CValue::GetProperty(const char *inName) // // Get text description of property with name , returns an empty string if there is no property named // -STR_String CValue::GetPropertyText(const STR_String & inName,const STR_String& deftext) +const STR_String& CValue::GetPropertyText(const STR_String & inName,const char *deftext) { + const static STR_String sEmpty(""); + CValue *property = GetProperty(inName); if (property) return property->GetText(); + else if (deftext) + return STR_String(deftext); else - return deftext;//String::sEmpty; + return sEmpty; } float CValue::GetPropertyNumber(const STR_String& inName,float defnumber) @@ -647,7 +651,7 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) int CValue::py_delattro(PyObject *attr) { char *attr_str= PyString_AsString(attr); - if (RemoveProperty(STR_String(attr_str))) + if (RemoveProperty(attr_str)) return 0; PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str); diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index c5c8229ebcf..e5c95df1c5c 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -308,7 +308,7 @@ public: virtual void SetProperty(const char* name,CValue* ioProperty); virtual CValue* GetProperty(const char* inName); // Get pointer to a property with name , returns NULL if there is no property named virtual CValue* GetProperty(const STR_String & inName); - STR_String GetPropertyText(const STR_String & inName,const STR_String& deftext=""); // Get text description of property with name , returns an empty string if there is no property named + const STR_String& GetPropertyText(const STR_String & inName,const char *deftext=NULL); // Get text description of property with name , returns an empty string if there is no property named float GetPropertyNumber(const STR_String& inName,float defnumber); virtual bool RemoveProperty(const char *inName); // Remove the property named , returns true if the property was succesfully removed, false if property was not found or could not be removed virtual vector GetPropertyNames(); @@ -331,8 +331,8 @@ public: double* ZeroVector() { return m_sZeroVec; }; virtual double* GetVector3(bool bGetTransformedVec = false); - virtual STR_String GetName() = 0; // Retrieve the name of the value - virtual void SetName(STR_String name) = 0; // Set the name of the value + virtual STR_String& GetName() = 0; // Retrieve the name of the value + virtual void SetName(const char *name) = 0; // Set the name of the value /** Sets the value to this cvalue. * @attention this particular function should never be called. Why not abstract? */ virtual void SetValue(CValue* newval); @@ -420,49 +420,28 @@ public: #else CPropValue() : #endif //NO_EXP_PYTHON_EMBEDDING - m_pstrNewName(NULL) + m_strNewName() { } virtual ~CPropValue() { - if (m_pstrNewName) - { - delete m_pstrNewName; - m_pstrNewName = NULL; - } } - virtual void SetName(STR_String name) { - if (m_pstrNewName) - { - delete m_pstrNewName; - m_pstrNewName = NULL; - } - if (name.Length()) - m_pstrNewName = new STR_String(name); - } - virtual void ProcessReplica() { - CValue::ProcessReplica(); - if (m_pstrNewName) - m_pstrNewName = new STR_String(*m_pstrNewName); + virtual void SetName(const char *name) { + m_strNewName = name; } - virtual STR_String GetName() { + virtual STR_String& GetName() { //STR_String namefromprop = GetPropertyText("Name"); //if (namefromprop.Length() > 0) // return namefromprop; - - if (m_pstrNewName) - { - return *m_pstrNewName; - } - return STR_String(""); + return m_strNewName; }; // name of Value protected: - STR_String* m_pstrNewName; // Identification + STR_String m_strNewName; // Identification }; #endif // !defined _VALUEBASECLASS_H diff --git a/source/gameengine/Expressions/VectorValue.cpp b/source/gameengine/Expressions/VectorValue.cpp index e8e1d45c356..c58c78e6ebe 100644 --- a/source/gameengine/Expressions/VectorValue.cpp +++ b/source/gameengine/Expressions/VectorValue.cpp @@ -48,7 +48,7 @@ CVectorValue::CVectorValue(float x,float y,float z, AllocationTYPE alloctype) m_vec[KX_Z] = m_transformedvec[KX_Z] = z; } -CVectorValue::CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype) { +CVectorValue::CVectorValue(double vec[],const char *name,AllocationTYPE alloctype) { SetCustomFlag1(false);//FancyOutput=false; diff --git a/source/gameengine/Expressions/VectorValue.h b/source/gameengine/Expressions/VectorValue.h index 99bf0abb11b..19c7dd30076 100644 --- a/source/gameengine/Expressions/VectorValue.h +++ b/source/gameengine/Expressions/VectorValue.h @@ -41,7 +41,7 @@ public: CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); - CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE); + CVectorValue(double vec[],const char *name,AllocationTYPE alloctype=CValue::HEAPVALUE); CVectorValue() {}; CVectorValue(double vec[],AllocationTYPE alloctype=CValue::HEAPVALUE); diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt index a7519196d50..449aae3ac84 100644 --- a/source/gameengine/GameLogic/CMakeLists.txt +++ b/source/gameengine/GameLogic/CMakeLists.txt @@ -31,6 +31,7 @@ SET(INC ../../../source/kernel/gen_system ../../../intern/string ../../../source/gameengine/Expressions + ../../../source/gameengine/Scenegraph ../../../intern/moto/include ../../../source/gameengine/Rasterizer ${PYTHON_INC} diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile index 355ece6e8bd..6e9af674549 100644 --- a/source/gameengine/GameLogic/Makefile +++ b/source/gameengine/GameLogic/Makefile @@ -39,6 +39,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I../Expressions +CPPFLAGS += -I../Scenegraph CPPFLAGS += -I../Rasterizer CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index fb72eefb4a4..1aaa59ee207 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -95,7 +95,7 @@ bool SCA_2DFilterActuator::Update() } -void SCA_2DFilterActuator::SetShaderText(STR_String text) +void SCA_2DFilterActuator::SetShaderText(STR_String& text) { m_shaderText = text; } diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index b43dc092ddb..aea3a35d404 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -60,7 +60,7 @@ public: PyTypeObject* T=&Type ); - void SetShaderText(STR_String text); + void SetShaderText(STR_String& text); virtual ~SCA_2DFilterActuator(); virtual bool Update(); diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index 7991e82168f..87f7c612e7c 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -73,19 +73,12 @@ void SCA_ANDController::Trigger(SCA_LogicManager* logicmgr) } } - CValue* newevent = new CBoolValue(sensorresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - logicmgr->AddActiveActuator(actua,newevent); + SCA_IActuator* actua = *i; + logicmgr->AddActiveActuator(actua,sensorresult); } - - // every actuator that needs the event, has a it's own reference to it now so - // release it (so to be clear: if there is no actuator, it's deleted right now) - newevent->Release(); - } diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp index 768a3a45937..a80b2af55c8 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp @@ -51,17 +51,19 @@ SCA_ActuatorEventManager::~SCA_ActuatorEventManager() void SCA_ActuatorEventManager::NextFrame() { // check for changed actuator - for (set::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - (*it)->Activate(m_logicmgr,NULL); + (*it)->Activate(m_logicmgr); } } void SCA_ActuatorEventManager::UpdateFrame() { // update the state of actuator before executing them - for (set::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - ((SCA_ActuatorSensor*)(*it))->Update(); + (*it)->Update(); } } \ No newline at end of file diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index 464797fd776..4dad65c5a25 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -89,7 +89,7 @@ SCA_ActuatorSensor::~SCA_ActuatorSensor() -bool SCA_ActuatorSensor::Evaluate(CValue* event) +bool SCA_ActuatorSensor::Evaluate() { if (m_actuator) { diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 974b2e43d78..6655e08dc70 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -52,7 +52,7 @@ public: virtual ~SCA_ActuatorSensor(); virtual CValue* GetReplica(); virtual void Init(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void ReParent(SCA_IObject* parent); void Update(); diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp index 4cd2dfba994..dd3b55abcc9 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp @@ -51,9 +51,10 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr) void SCA_AlwaysEventManager::NextFrame() { - for (set::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - (*i)->Activate(m_logicmgr, NULL); + (*it)->Activate(m_logicmgr); } } diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index 19d19b6e0be..ff02680f191 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -86,7 +86,7 @@ bool SCA_AlwaysSensor::IsPositiveTrigger() -bool SCA_AlwaysSensor::Evaluate(CValue* event) +bool SCA_AlwaysSensor::Evaluate() { /* Nice! :) */ //return true; diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 769e1e883bc..0f85a641ef1 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -43,7 +43,7 @@ public: PyTypeObject* T =&Type); virtual ~SCA_AlwaysSensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index 4752d0eb345..dcdae0b4e75 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -89,7 +89,7 @@ bool SCA_DelaySensor::IsPositiveTrigger() return (m_invert ? !m_lastResult : m_lastResult); } -bool SCA_DelaySensor::Evaluate(CValue* event) +bool SCA_DelaySensor::Evaluate() { bool trigger = false; bool result; diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index 31394fdc961..5ccb33f8a16 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -51,7 +51,7 @@ public: PyTypeObject* T =&Type); virtual ~SCA_DelaySensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp index e4fd0379597..d1301541a0a 100644 --- a/source/gameengine/GameLogic/SCA_EventManager.cpp +++ b/source/gameengine/GameLogic/SCA_EventManager.cpp @@ -28,6 +28,7 @@ #include #include "SCA_EventManager.h" +#include "SCA_ISensor.h" #ifdef HAVE_CONFIG_H #include @@ -43,16 +44,18 @@ SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype) SCA_EventManager::~SCA_EventManager() { + // all sensors should be removed + assert(m_sensors.Empty()); } void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor) { - m_sensors.insert(sensor); + m_sensors.AddBack(sensor); } void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor) { - m_sensors.erase(sensor); + sensor->Delink(); } void SCA_EventManager::NextFrame(double curtime, double fixedtime) diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h index 9dbb5a6d24f..5ff55849bfe 100644 --- a/source/gameengine/GameLogic/SCA_EventManager.h +++ b/source/gameengine/GameLogic/SCA_EventManager.h @@ -33,11 +33,14 @@ #include #include +#include "SG_DList.h" + class SCA_EventManager { protected: // use a set to speed-up insertion/removal - std::set m_sensors; + //std::set m_sensors; + SG_DList m_sensors; public: enum EVENT_MANAGER_TYPE { diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index a4e898a808f..8e044b89c71 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -115,37 +115,14 @@ void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr) value->Release(); } - //m_exprCache->Release(); - //m_exprCache = NULL; } - /* - - for (vector::const_iterator is=m_linkedsensors.begin(); - !(is==m_linkedsensors.end());is++) - { - SCA_ISensor* sensor = *is; - if (!sensor->IsPositiveTrigger()) - { - sensorresult = false; - break; - } - } - - */ - - CValue* newevent = new CBoolValue(expressionresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { SCA_IActuator* actua = *i; - logicmgr->AddActiveActuator(actua,newevent); + logicmgr->AddActiveActuator(actua,expressionresult); } - //printf("expr %d.",expressionresult); - // every actuator that needs the event, has a it's own reference to it now so - // release it (so to be clear: if there is no actuator, it's deleted right now) - newevent->Release(); } diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index 214c7dded76..5f71bb3f9e4 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -37,46 +37,13 @@ using namespace std; SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, PyTypeObject* T) : SCA_ILogicBrick(gameobj,T), - m_links(0) + m_links(0), + m_posevent(false), + m_negevent(false) { // nothing to do } - - -void SCA_IActuator::RemoveAllEvents() -{ // remove event queue! - for (vector::iterator i=m_events.begin(); !(i==m_events.end());i++) - { - (*i)->Release(); - } - m_events.clear(); -} - - - - - -bool SCA_IActuator::IsNegativeEvent() const -{ - bool bPositiveEvent(false); - bool bNegativeEvent(false); - - for (vector::const_iterator i=m_events.begin(); i!=m_events.end();++i) - { - if ((*i)->GetNumber() == 0.0f) - { - bNegativeEvent = true; - } else { - bPositiveEvent = true; - } - } - - // if at least 1 positive event, return false - - return !bPositiveEvent && bNegativeEvent; -} - bool SCA_IActuator::Update(double curtime, bool frame) { if (frame) @@ -94,7 +61,8 @@ bool SCA_IActuator::Update() void SCA_IActuator::ProcessReplica() { SCA_ILogicBrick::ProcessReplica(); - m_events.clear(); + RemoveAllEvents(); + m_linkedcontrollers.clear(); } @@ -113,3 +81,36 @@ void SCA_IActuator::DecLink() m_links = 0; } } + +void SCA_IActuator::LinkToController(SCA_IController* controller) +{ + m_linkedcontrollers.push_back(controller); +} + +void SCA_IActuator::UnlinkController(SCA_IController* controller) +{ + std::vector::iterator contit; + for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit) + { + if ((*contit) == controller) + { + *contit = m_linkedcontrollers.back(); + m_linkedcontrollers.pop_back(); + return; + } + } + printf("Missing link from actuator %s:%s to controller %s:%s\n", + m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), + controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr()); +} + +void SCA_IActuator::UnlinkAllControllers() +{ + std::vector::iterator contit; + for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit) + { + (*contit)->UnlinkActuator(this); + } + m_linkedcontrollers.clear(); +} + diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index e5f0a2cf4cc..3055e1d946f 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -29,17 +29,33 @@ #ifndef __KX_IACTUATOR #define __KX_IACTUATOR -#include "SCA_ILogicBrick.h" +#include "SCA_IController.h" #include +/* + * Use of SG_DList : element of actuator being deactivated + * Head: SCA_LogicManager::m_removedActuators + * Use of SG_QList : element of activated actuator list of their owner + * Head: SCA_IObject::m_activeActuators + */ class SCA_IActuator : public SCA_ILogicBrick { friend class SCA_LogicManager; protected: int m_links; // number of active links to controllers // when 0, the actuator is automatically stopped - std::vector m_events; - void RemoveAllEvents(); + //std::vector m_events; + bool m_posevent; + bool m_negevent; + + std::vector m_linkedcontrollers; + + void RemoveAllEvents() + { + m_posevent = false; + m_negevent = false; + } + public: /** @@ -75,9 +91,13 @@ public: /** * Add an event to an actuator. */ - void AddEvent(CValue* event) + //void AddEvent(CValue* event) + void AddEvent(bool event) { - m_events.push_back(event); + if (event) + m_posevent = true; + else + m_negevent = true; } virtual void ProcessReplica(); @@ -88,9 +108,38 @@ public: * not immediately clear. But usually refers to key-up events * or events where no action is required. */ - bool IsNegativeEvent() const; + bool IsNegativeEvent() const + { + return !m_posevent && m_negevent; + } + virtual ~SCA_IActuator(); + /** + * remove this actuator from the list of active actuators + */ + void Deactivate() + { + if (QDelink()) + // the actuator was in the active list + if (m_gameobj->m_activeActuators.QEmpty()) + // the owner object has no more active actuators, remove it from the global list + m_gameobj->m_activeActuators.Delink(); + } + + void Activate(SG_DList& head) + { + if (QEmpty()) + { + InsertActiveQList(m_gameobj->m_activeActuators); + head.AddBack(&m_gameobj->m_activeActuators); + } + } + + void LinkToController(SCA_IController* controller); + void UnlinkController(class SCA_IController* cont); + void UnlinkAllControllers(); + void ClrLink() { m_links=0; } void IncLink() { m_links++; } void DecLink(); diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index 24509f6e6ed..f8b081ef050 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -41,7 +41,8 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj, PyTypeObject* T) : SCA_ILogicBrick(gameobj,T), - m_statemask(0) + m_statemask(0), + m_justActivated(false) { } @@ -49,19 +50,19 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj, SCA_IController::~SCA_IController() { - UnlinkAllActuators(); + //UnlinkAllActuators(); } -const std::vector& SCA_IController::GetLinkedSensors() +std::vector& SCA_IController::GetLinkedSensors() { return m_linkedsensors; } -const std::vector& SCA_IController::GetLinkedActuators() +std::vector& SCA_IController::GetLinkedActuators() { return m_linkedactuators; } @@ -70,13 +71,14 @@ const std::vector& SCA_IController::GetLinkedActuators() void SCA_IController::UnlinkAllSensors() { - if (IsActive()) + std::vector::iterator sensit; + for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) { - std::vector::iterator sensit; - for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) + if (IsActive()) { (*sensit)->DecLink(); } + (*sensit)->UnlinkController(this); } m_linkedsensors.clear(); } @@ -85,34 +87,18 @@ void SCA_IController::UnlinkAllSensors() void SCA_IController::UnlinkAllActuators() { - if (IsActive()) + std::vector::iterator actit; + for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit) { - std::vector::iterator actit; - for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit) + if (IsActive()) { (*actit)->DecLink(); } + (*actit)->UnlinkController(this); } m_linkedactuators.clear(); } - - -/* -void SCA_IController::Trigger(SCA_LogicManager* logicmgr) -{ - //for (int i=0;i::const_iterator i=m_linkedactuators.begin(); - !(i==m_linkedactuators.end());i++) - { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - - logicmgr->AddActiveActuator(actua); - } - -} -*/ - void SCA_IController::LinkToActuator(SCA_IActuator* actua) { m_linkedactuators.push_back(actua); @@ -129,18 +115,18 @@ void SCA_IController::UnlinkActuator(class SCA_IActuator* actua) { if ((*actit) == actua) { - break; + if (IsActive()) + { + (*actit)->DecLink(); + } + *actit = m_linkedactuators.back(); + m_linkedactuators.pop_back(); + return; } - - } - if (!(actit==m_linkedactuators.end())) - { - if (IsActive()) - { - (*actit)->DecLink(); - } - m_linkedactuators.erase(actit); } + printf("Missing link from controller %s:%s to actuator %s:%s\n", + m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), + actua->GetParent()->GetName().ReadPtr(), actua->GetName().ReadPtr()); } void SCA_IController::LinkToSensor(SCA_ISensor* sensor) @@ -159,20 +145,21 @@ void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor) { if ((*sensit) == sensor) { - break; + if (IsActive()) + { + sensor->DecLink(); + } + *sensit = m_linkedsensors.back(); + m_linkedsensors.pop_back(); + return; } - - } - if (!(sensit==m_linkedsensors.end())) - { - if (IsActive()) - { - (*sensit)->DecLink(); - } - m_linkedsensors.erase(sensit); } + printf("Missing link from controller %s:%s to sensor %s:%s\n", + m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), + sensor->GetParent()->GetName().ReadPtr(), sensor->GetName().ReadPtr()); } + void SCA_IController::ApplyState(unsigned int state) { std::vector::iterator actit; @@ -187,13 +174,13 @@ void SCA_IController::ApplyState(unsigned int state) { (*actit)->IncLink(); } + for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) { (*sensit)->IncLink(); - // remember that this controller just activated that sensor - (*sensit)->AddNewController(this); } SetActive(true); + m_justActivated = true; } } else if (IsActive()) { @@ -206,6 +193,7 @@ void SCA_IController::ApplyState(unsigned int state) (*sensit)->DecLink(); } SetActive(false); + m_justActivated = false; } } @@ -301,7 +289,7 @@ PyObject* SCA_IController::PyGetSensor(PyObject* value) for (unsigned int index=0;indexGetName(); + STR_String& realname = sensor->GetName(); if (realname == scriptArg) { return sensor->GetProxy(); diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 7ed83bc90b8..1b9d8fb0d2b 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -32,6 +32,11 @@ #include "SCA_ILogicBrick.h" #include "PyObjectPlus.h" +/* + * Use of SG_DList element: none + * Use of SG_QList element: build ordered list of activated controller on the owner object + * Head: SCA_IObject::m_activeControllers + */ class SCA_IController : public SCA_ILogicBrick { Py_Header; @@ -39,21 +44,48 @@ protected: std::vector m_linkedsensors; std::vector m_linkedactuators; unsigned int m_statemask; + bool m_justActivated; public: SCA_IController(SCA_IObject* gameobj,PyTypeObject* T); virtual ~SCA_IController(); virtual void Trigger(class SCA_LogicManager* logicmgr)=0; void LinkToSensor(SCA_ISensor* sensor); void LinkToActuator(SCA_IActuator*); - const std::vector& GetLinkedSensors(); - const std::vector& GetLinkedActuators(); + std::vector& GetLinkedSensors(); + std::vector& GetLinkedActuators(); + void ReserveActuator(int num) + { + m_linkedactuators.reserve(num); + } void UnlinkAllSensors(); void UnlinkAllActuators(); void UnlinkActuator(class SCA_IActuator* actua); void UnlinkSensor(class SCA_ISensor* sensor); void SetState(unsigned int state) { m_statemask = state; } void ApplyState(unsigned int state); - + void Deactivate() + { + // the controller can only be part of a sensor m_newControllers list + Delink(); + } + bool IsJustActivated() + { + return m_justActivated; + } + void ClrJustActivated() + { + m_justActivated = false; + } + + void Activate(SG_DList& head) + { + if (QEmpty()) + { + InsertActiveQList(m_gameobj->m_activeControllers); + head.AddBack(&m_gameobj->m_activeControllers); + } + } + virtual PyObject* py_getattro(PyObject *attr); virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *value); diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 6de9986b03a..2dc80f54568 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -123,14 +123,14 @@ double SCA_ILogicBrick::GetNumber() -STR_String SCA_ILogicBrick::GetName() +STR_String& SCA_ILogicBrick::GetName() { return m_name; } -void SCA_ILogicBrick::SetName(STR_String name) +void SCA_ILogicBrick::SetName(const char *name) { m_name = name; } @@ -222,7 +222,7 @@ PyMethodDef SCA_ILogicBrick::Methods[] = { PyAttributeDef SCA_ILogicBrick::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("owner", SCA_ILogicBrick, pyattr_get_owner), - KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Ueber_Priority), + KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Priority), KX_PYATTRIBUTE_STRING_RO("name", SCA_ILogicBrick, m_name), {NULL} //Sentinel }; @@ -286,7 +286,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args) return NULL; } - m_Execute_Ueber_Priority = priority; + m_Execute_Priority = priority; Py_RETURN_NONE; } @@ -296,7 +296,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args) PyObject* SCA_ILogicBrick::PyGetExecutePriority() { ShowDeprecationWarning("getExecutePriority()", "the executePriority property"); - return PyInt_FromLong(m_Execute_Ueber_Priority); + return PyInt_FromLong(m_Execute_Priority); } diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index b1384e88826..90881c0536f 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -71,8 +71,8 @@ public: virtual const STR_String & GetText(); virtual double GetNumber(); - virtual STR_String GetName(); - virtual void SetName(STR_String name); + virtual STR_String& GetName(); + virtual void SetName(const char *); bool IsActive() { @@ -84,6 +84,13 @@ public: m_bActive=active; } + // insert in a QList at position corresponding to m_Execute_Priority + void InsertActiveQList(SG_QList& head) + { + SG_QList::iterator it(head); + for(it.begin(); !it.end() && m_Execute_Priority > (*it)->m_Execute_Priority; ++it); + it.add_back(this); + } virtual bool LessComparedTo(SCA_ILogicBrick* other); diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 7eaa5c607be..8962c8e8580 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -70,7 +70,7 @@ SCA_IObject::~SCA_IObject() } for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita) { - ((CValue*)(*ita))->Release(); + (*ita)->Delete(); } //T_InterpolatorList::iterator i; @@ -110,7 +110,7 @@ void SCA_IObject::RegisterActuator(SCA_IActuator* act) void SCA_IObject::UnregisterActuator(SCA_IActuator* act) { SCA_ActuatorList::iterator ita; - for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ita++) + for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita) { if ((*ita) == act) { (*ita) = m_registeredActuators.back(); @@ -171,7 +171,7 @@ SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname) { SCA_ISensor* foundsensor = NULL; - for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());its++) + for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its) { if ((*its)->GetName() == sensorname) { @@ -188,7 +188,7 @@ SCA_IController* SCA_IObject::FindController(const STR_String& controllername) { SCA_IController* foundcontroller = NULL; - for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());itc++) + for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc) { if ((*itc)->GetName() == controllername) { @@ -205,7 +205,7 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname) { SCA_IActuator* foundactuator = NULL; - for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());ita++) + for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita) { if ((*ita)->GetName() == actuatorname) { @@ -272,7 +272,7 @@ void SCA_IObject::Suspend() SCA_SensorList::iterator i = m_sensors.begin(); while (i != m_sensors.end()) { (*i)->Suspend(); - i++; + ++i; } } } @@ -287,7 +287,7 @@ void SCA_IObject::Resume(void) SCA_SensorList::iterator i = m_sensors.begin(); while (i != m_sensors.end()) { (*i)->Resume(); - i++; + ++i; } } } @@ -307,7 +307,7 @@ void SCA_IObject::SetState(unsigned int state) if (tmpstate != m_state) { // update the status of the controllers - for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++) + for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit) { (*contit)->ApplyState(tmpstate); } @@ -315,7 +315,7 @@ void SCA_IObject::SetState(unsigned int state) m_state = state; if (m_state != tmpstate) { - for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++) + for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit) { (*contit)->ApplyState(m_state); } diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 10cf551aeb6..281c72ecd46 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -52,10 +52,24 @@ class SCA_IObject : public CValue Py_Header; protected: + friend class SCA_IActuator; + friend class SCA_IController; SCA_SensorList m_sensors; SCA_ControllerList m_controllers; SCA_ActuatorList m_actuators; SCA_ActuatorList m_registeredActuators; // actuators that use a pointer to this object + + // SG_Dlist: element of objects with active actuators + // Head: SCA_LogicManager::m_activeActuators + // SG_QList: Head of active actuators list on this object + // Elements: SCA_IActuator + SG_QList m_activeActuators; + // SG_Dlist: element of objects with active controllers + // Head: SCA_LogicManager::m_activeControllers + // SG_QList: Head of active controller list on this object + // Elements: SCA_IController + SG_QList m_activeControllers; + static class MT_Point3 m_sDummy; /** @@ -95,10 +109,26 @@ public: { return m_actuators; } + SG_QList& GetActiveActuators() + { + return m_activeActuators; + } void AddSensor(SCA_ISensor* act); + void ReserveSensor(int num) + { + m_sensors.reserve(num); + } void AddController(SCA_IController* act); + void ReserveController(int num) + { + m_controllers.reserve(num); + } void AddActuator(SCA_IActuator* act); + void ReserveActuator(int num) + { + m_actuators.reserve(num); + } void RegisterActuator(SCA_IActuator* act); void UnregisterActuator(SCA_IActuator* act); diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp index 9fbeb706910..86b176a38b0 100644 --- a/source/gameengine/GameLogic/SCA_IScene.cpp +++ b/source/gameengine/GameLogic/SCA_IScene.cpp @@ -50,7 +50,7 @@ SCA_IScene::SCA_IScene() void SCA_IScene::RemoveAllDebugProperties() { for (std::vector::iterator it = m_debugList.begin(); - !(it==m_debugList.end());it++) + !(it==m_debugList.end());++it) { delete (*it); } diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h index d18778a37c2..b641efc6ee1 100644 --- a/source/gameengine/GameLogic/SCA_IScene.h +++ b/source/gameengine/GameLogic/SCA_IScene.h @@ -52,7 +52,7 @@ public: int lifespan=0)=0; virtual void RemoveObject(class CValue* gameobj)=0; virtual void DelayedRemoveObject(class CValue* gameobj)=0; - virtual void DelayedReleaseObject(class CValue* gameobj)=0; + //virtual void DelayedReleaseObject(class CValue* gameobj)=0; virtual void ReplaceMesh(class CValue* gameobj, void* meshobj)=0; diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index 1e9a4521df5..2783bf14600 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -45,7 +45,7 @@ void SCA_ISensor::ReParent(SCA_IObject* parent) SCA_ILogicBrick::ReParent(parent); // will be done when the sensor is activated //m_eventmgr->RegisterSensor(this); - this->SetActive(false); + //this->SetActive(false); } @@ -77,6 +77,12 @@ SCA_ISensor::~SCA_ISensor() // intentionally empty } +void SCA_ISensor::ProcessReplica() +{ + SCA_ILogicBrick::ProcessReplica(); + m_linkedcontrollers.clear(); +} + bool SCA_ISensor::IsPositiveTrigger() { bool result = false; @@ -150,29 +156,72 @@ void SCA_ISensor::RegisterToManager() // sensor is just activated, initialize it Init(); m_state = false; - m_newControllers.erase(m_newControllers.begin(), m_newControllers.end()); m_eventmgr->RegisterSensor(this); } +void SCA_ISensor::LinkToController(SCA_IController* controller) +{ + m_linkedcontrollers.push_back(controller); +} + +void SCA_ISensor::UnlinkController(SCA_IController* controller) +{ + std::vector::iterator contit; + for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit) + { + if ((*contit) == controller) + { + *contit = m_linkedcontrollers.back(); + m_linkedcontrollers.pop_back(); + return; + } + } + printf("Missing link from sensor %s:%s to controller %s:%s\n", + m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), + controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr()); +} + +void SCA_ISensor::UnlinkAllControllers() +{ + std::vector::iterator contit; + for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit) + { + (*contit)->UnlinkSensor(this); + } + m_linkedcontrollers.clear(); +} + void SCA_ISensor::UnregisterToManager() { m_eventmgr->RemoveSensor(this); + m_links = 0; } -void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) +void SCA_ISensor::ActivateControllers(class SCA_LogicManager* logicmgr) +{ + for(vector::const_iterator c= m_linkedcontrollers.begin(); + c!=m_linkedcontrollers.end();++c) + { + SCA_IController* contr = *c; + if (contr->IsActive()) + logicmgr->AddTriggeredController(contr, this); + } +} + +void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr) { // calculate if a __triggering__ is wanted // don't evaluate a sensor that is not connected to any controller if (m_links && !m_suspended) { - bool result = this->Evaluate(event); + bool result = this->Evaluate(); // store the state for the rest of the logic system m_prev_state = m_state; m_state = this->IsPositiveTrigger(); if (result) { // the sensor triggered this frame if (m_state || !m_tap) { - logicmgr->AddActivatedSensor(this); + ActivateControllers(logicmgr); // reset these counters so that pulse are synchronized with transition m_pos_ticks = 0; m_neg_ticks = 0; @@ -190,7 +239,7 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) if (m_pos_ticks > m_pulse_frequency) { if ( m_state ) { - logicmgr->AddActivatedSensor(this); + ActivateControllers(logicmgr); result = true; } m_pos_ticks = 0; @@ -203,7 +252,8 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) if (m_neg_ticks > m_pulse_frequency) { if (!m_state ) { - logicmgr->AddActivatedSensor(this); + ActivateControllers(logicmgr); + result = true; } m_neg_ticks = 0; } @@ -218,27 +268,24 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) if (m_prev_state) { // but it triggered on previous frame => send a negative pulse - logicmgr->AddActivatedSensor(this); + ActivateControllers(logicmgr); + result = true; } // in any case, absence of trigger means sensor off m_state = false; } } - if (!m_newControllers.empty()) + if (!result && m_level) { - if (!IsActive() && m_level) + // This level sensor is connected to at least one controller that was just made + // active but it did not generate an event yet, do it now to those controllers only + for(vector::const_iterator c= m_linkedcontrollers.begin(); + c!=m_linkedcontrollers.end();++c) { - // This level sensor is connected to at least one controller that was just made - // active but it did not generate an event yet, do it now to those controllers only - for (std::vector::iterator ci=m_newControllers.begin(); - ci != m_newControllers.end(); ci++) - { - logicmgr->AddTriggeredController(*ci, this); - } + SCA_IController* contr = *c; + if (contr->IsJustActivated()) + logicmgr->AddTriggeredController(contr, this); } - // clear the list. Instead of using clear, which also release the memory, - // use erase, which keeps the memory available for next time. - m_newControllers.erase(m_newControllers.begin(), m_newControllers.end()); } } } diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 7bbef5fef2f..9aeda728caf 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -32,16 +32,21 @@ #ifndef __SCA_ISENSOR #define __SCA_ISENSOR -#include "SCA_ILogicBrick.h" +#include "SCA_IController.h" #include /** * Interface Class for all logic Sensors. Implements - * pulsemode,pulsefrequency */ + * pulsemode,pulsefrequency + * Use of SG_DList element: link sensors to their respective event manager + * Head: SCA_EventManager::m_sensors + * Use of SG_QList element: not used + */ class SCA_ISensor : public SCA_ILogicBrick { Py_Header; +protected: class SCA_EventManager* m_eventmgr; /** Pulse positive pulses? */ @@ -83,8 +88,7 @@ class SCA_ISensor : public SCA_ILogicBrick /** previous state (for tap option) */ bool m_prev_state; - /** list of controllers that have just activated this sensor because of a state change */ - std::vector m_newControllers; + std::vector m_linkedcontrollers; public: SCA_ISensor(SCA_IObject* gameobj, @@ -97,8 +101,8 @@ public: /* an implementation on this level. It requires an evaluate on the lower */ /* level of individual sensors. Mapping the old activate()s is easy. */ /* The IsPosTrig() also has to change, to keep things consistent. */ - void Activate(class SCA_LogicManager* logicmgr,CValue* event); - virtual bool Evaluate(CValue* event) = 0; + void Activate(class SCA_LogicManager* logicmgr); + virtual bool Evaluate() = 0; virtual bool IsPositiveTrigger(); virtual void Init(); @@ -121,6 +125,16 @@ public: virtual void RegisterToManager(); virtual void UnregisterToManager(); + void ReserveController(int num) + { + m_linkedcontrollers.reserve(num); + } + void LinkToController(SCA_IController* controller); + void UnlinkController(SCA_IController* controller); + void UnlinkAllControllers(); + void ActivateControllers(class SCA_LogicManager* logicmgr); + + virtual void ProcessReplica(); virtual double GetNumber(); @@ -139,8 +153,6 @@ public: /** Resume sensing. */ void Resume(); - void AddNewController(class SCA_IController* controller) - { m_newControllers.push_back(controller); } void ClrLink() { m_links = 0; } void IncLink() diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp index f3ce549a637..ff8f3b1c81f 100644 --- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp @@ -59,20 +59,21 @@ SCA_JoystickManager::~SCA_JoystickManager() void SCA_JoystickManager::NextFrame(double curtime,double deltatime) { - if (m_sensors.size()==0) { + if (m_sensors.Empty()) { return; } else { - set::iterator it; + ; #ifndef DISABLE_SDL SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */ #endif - for (it = m_sensors.begin(); it != m_sensors.end(); it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it); + SCA_JoystickSensor* joysensor = *it; if(!joysensor->IsSuspended()) { - joysensor->Activate(m_logicmgr, NULL); + joysensor->Activate(m_logicmgr); } } } diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 34d63a4ee2b..906d454b728 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -102,7 +102,7 @@ bool SCA_JoystickSensor::IsPositiveTrigger() } -bool SCA_JoystickSensor::Evaluate(CValue* event) +bool SCA_JoystickSensor::Evaluate() { SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(m_joyindex); bool result = false; diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index 20fff66f66c..e8185d1911e 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -110,7 +110,7 @@ public: virtual ~SCA_JoystickSensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp index 6a96442b124..279adab94d8 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp @@ -62,12 +62,11 @@ void SCA_KeyboardManager::NextFrame() { //const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0; // cerr << "SCA_KeyboardManager::NextFrame"<< endl; - set::iterator it; - for (it=m_sensors.begin(); it != m_sensors.end(); it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - (*it)->Activate(m_logicmanager,NULL); + (*it)->Activate(m_logicmanager); } - } bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode) diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index a9ea4272531..f8ee8ed8b41 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -118,7 +118,7 @@ bool SCA_KeyboardSensor::TriggerOnAllKeys() -bool SCA_KeyboardSensor::Evaluate(CValue* eventval) +bool SCA_KeyboardSensor::Evaluate() { bool result = false; bool reset = m_reset && m_level; diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 1dd6ea21fcd..033225cd9be 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -102,7 +102,7 @@ public: short int GetHotkey(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); bool TriggerOnAllKeys(); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index c43875a0047..74370f89cf2 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -49,42 +49,12 @@ SCA_LogicManager::SCA_LogicManager() SCA_LogicManager::~SCA_LogicManager() { - /* AddRef() is not used when the objects are added to m_mapStringToGameObjects - so Release() should not be used either. The memory leak big is fixed - in BL_ConvertBlenderObjects() - - int numgameobj = m_mapStringToGameObjects.size(); - for (int i = 0; i < numgameobj; i++) - { - CValue** gameobjptr = m_mapStringToGameObjects.at(i); - assert(gameobjptr); - if (gameobjptr) - (*gameobjptr)->Release(); - - } - */ - /*for (int i=0;i* controllerarray = *(m_sensorcontrollermap[i]); - delete controllerarray; - } - */ - for (vector::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++) + for (vector::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());++it) { delete (*it); } m_eventmanagers.clear(); - m_sensorcontrollermapje.clear(); - m_removedActuators.clear(); - m_activeActuators.clear(); -} - -// this function is a performance helper when the scene is destoyed -// without it, the map updated for each object... a massive slow down when there are -// large number of objects. By clearing the map upfront we avoid the waster of time. -void SCA_LogicManager::RemoveSensorMap() -{ - m_sensorcontrollermapje.clear(); + assert(m_activeActuators.Empty()); } /* @@ -178,62 +148,30 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) { - sensormap_t::const_iterator mit = m_sensorcontrollermapje.find(sensor); - if (mit != m_sensorcontrollermapje.end()) - { - const controllerlist& contlist = mit->second; - for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++) - { - (*c)->UnlinkSensor(sensor); - } - m_sensorcontrollermapje.erase(sensor); - } + sensor->UnlinkAllControllers(); sensor->UnregisterToManager(); } void SCA_LogicManager::RemoveController(SCA_IController* controller) { - sensormap_t::iterator sit; - sit = m_sensorcontrollermapje.begin(); - if (sit==m_sensorcontrollermapje.end()) - { - //TRICK: either there is no sensor at all, or the scene is being deleted - //(see KX_Scene::~KX_Scene()). In the first case, this is harmless. - //In the second case, we cannot rely on the sensor being still available, - //make the controller inactive to avoid link count. - //Need a better solution, maybe something similar to m_removedActuators. - controller->SetActive(false); - } controller->UnlinkAllSensors(); controller->UnlinkAllActuators(); - for (;!(sit==m_sensorcontrollermapje.end());++sit) - { - (*sit).second.remove(controller); - } + controller->Deactivate(); } -void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator) +void SCA_LogicManager::RemoveActuator(SCA_IActuator* actuator) { - m_removedActuators.push_back(SmartActuatorPtr(actuator,0)); - // take care that no controller can use this actuator again ! - - sensormap_t::const_iterator sit; - for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) - { - const controllerlist& contlist = sit->second; - for (list::const_iterator c= contlist.begin();!(c==contlist.end());c++) - { - (*c)->UnlinkActuator(actuator); - } - } + actuator->UnlinkAllControllers(); + actuator->Deactivate(); + actuator->SetActive(false); } void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor) { - m_sensorcontrollermapje[sensor].push_back(controller); + sensor->LinkToController(controller); controller->LinkToSensor(sensor); } @@ -241,6 +179,7 @@ void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua) { + actua->LinkToController(controller); controller->LinkToActuator(actua); } @@ -251,88 +190,60 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime) for (vector::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++) (*ie)->NextFrame(curtime, fixedtime); - // for this frame, look up for activated sensors, and build the collection of triggered controllers - // int numsensors = this->m_activatedsensors.size(); /*unused*/ - - for (vector::const_iterator is=m_activatedsensors.begin(); - !(is==m_activatedsensors.end());is++) + for(SG_QList* obj = (SG_QList*)m_triggeredControllerSet.Remove(); + obj != NULL; + obj = (SG_QList*)m_triggeredControllerSet.Remove()) { - SCA_ISensor* sensor = *is; - const controllerlist& contlist = m_sensorcontrollermapje[sensor]; - for (list::const_iterator c= contlist.begin(); - !(c==contlist.end());c++) + for(SCA_IController* contr = (SCA_IController*)obj->QRemove(); + contr != NULL; + contr = (SCA_IController*)obj->QRemove()) { - SCA_IController* contr = *c;//controllerarray->at(c); - if (contr->IsActive()) - { - m_triggeredControllerSet.insert(SmartControllerPtr(contr,0)); - // So that the controller knows which sensor has activited it. - // Only needed for the python controller though. - if (contr->GetType() == &SCA_PythonController::Type) - { - SCA_PythonController* pythonController = (SCA_PythonController*)contr; - pythonController->AddTriggeredSensor(sensor); - } - } + contr->Trigger(this); + contr->ClrJustActivated(); } - //sensor->SetActive(false); } - - - // int numtriggered = triggeredControllerSet.size(); /*unused*/ - for (set::iterator tit=m_triggeredControllerSet.begin(); - !(tit==m_triggeredControllerSet.end());tit++) - { - (*tit)->Trigger(this); - } - m_triggeredControllerSet.clear(); } void SCA_LogicManager::UpdateFrame(double curtime, bool frame) { - vector::iterator ra; - for (ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++) - { - m_activeActuators.erase(*ra); - (*ra)->SetActive(false); - } - m_removedActuators.clear(); - - // About to run actuators, but before update the sensors for those which depends on actuators for (vector::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++) (*ie)->UpdateFrame(); - for (set::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++) + SG_DList::iterator io(m_activeActuators); + for (io.begin(); !io.end(); ++io) { - //SCA_IActuator* actua = *ia; - if (!(*ia)->Update(curtime, frame)) + SG_QList::iterator ia(*(*io)); + for (ia.begin(); !ia.end(); ++ia) { - //*ia = m_activeactuators.back(); - m_removedActuators.push_back(*ia); - - (*ia)->SetActive(false); - //m_activeactuators.pop_back(); - } else if ((*ia)->IsNoLink()) - { - // This actuator has no more links but it still active - // make sure it will get a negative event on next frame to stop it - // Do this check after Update() rather than before to make sure - // that all the actuators that are activated at same time than a state - // actuator have a chance to execute. - CValue* event = new CBoolValue(false); - (*ia)->RemoveAllEvents(); - (*ia)->AddEvent(event); + SCA_IActuator* actua = *ia; + if (!actua->Update(curtime, frame)) + { + // cannot deactive the actuator now as it will disturb the list + m_removedActuators.AddBack(actua); + actua->SetActive(false); + } else if (actua->IsNoLink()) + { + // This actuator has no more links but it still active + // make sure it will get a negative event on next frame to stop it + // Do this check after Update() rather than before to make sure + // that all the actuators that are activated at same time than a state + // actuator have a chance to execute. + bool event = false; + actua->RemoveAllEvents(); + actua->AddEvent(event); + } } } - - for ( ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++) + + for (SCA_IActuator* act = (SCA_IActuator*)m_removedActuators.Remove(); + act != NULL; + act = (SCA_IActuator*)m_removedActuators.Remove()) { - m_activeActuators.erase(*ra); - (*ra)->SetActive(false); + act->Deactivate(); + act->SetActive(false); } - m_removedActuators.clear(); } @@ -381,39 +292,17 @@ void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action void SCA_LogicManager::EndFrame() { - for (vector::const_iterator is=m_activatedsensors.begin(); - !(is==m_activatedsensors.end());is++) - { - SCA_ISensor* sensor = *is; - sensor->SetActive(false); - } - m_activatedsensors.clear(); - for (vector::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end());ie++) { (*ie)->EndFrame(); } - - } - -void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor) -{ - // each frame, only add sensor once, and to avoid a seek, or bloated container - // hold a flag in each sensor, with the 'framenr' - if (!sensor->IsActive()) - { - sensor->SetActive(true); - m_activatedsensors.push_back(sensor); - } -} - void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor) { - m_triggeredControllerSet.insert(SmartControllerPtr(controller,0)); + controller->Activate(m_triggeredControllerSet); // so that the controller knows which sensor has activited it // only needed for python controller if (controller->GetType() == &SCA_PythonController::Type) @@ -424,14 +313,11 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I } -void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event) +void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,bool event) { - if (!actua->IsActive()) - { - actua->SetActive(true); - m_activeActuators.insert(SmartActuatorPtr(actua,0)); - } - actua->AddEvent(event->AddRef()); + actua->SetActive(true); + actua->Activate(m_activeActuators); + actua->AddEvent(event); } @@ -453,109 +339,3 @@ SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype) } return eventmgr; } - - - -SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other) -{ - this->m_actuator = other.m_actuator; - this->m_actuator->AddRef(); -} - - - -SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy) -: m_actuator(actua) -{ - actua->AddRef(); -} - - - -SmartActuatorPtr::~SmartActuatorPtr() -{ - m_actuator->Release(); -} - - - -bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const -{ - - return m_actuator->LessComparedTo(*other); -} - - - -bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const -{ - bool result2 = other->LessComparedTo(m_actuator); - return (m_actuator->LessComparedTo(*other) && result2); -} - - - -SCA_IActuator* SmartActuatorPtr::operator->() const -{ - return m_actuator; -} - - - -SCA_IActuator* SmartActuatorPtr::operator*() const -{ - return m_actuator; -} - - - -SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy) -{ - this->m_controller = copy.m_controller; - this->m_controller->AddRef(); -} - - - -SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy) -: m_controller(contr) -{ - m_controller->AddRef(); -} - - - -SmartControllerPtr::~SmartControllerPtr() -{ - m_controller->Release(); -} - - - -bool SmartControllerPtr::operator <(const SmartControllerPtr& other) const -{ - return m_controller->LessComparedTo(*other); -} - - - -bool SmartControllerPtr::operator ==(const SmartControllerPtr& other) const -{ - return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller)); -} - - - -SCA_IController* SmartControllerPtr::operator->() const -{ - return m_controller; -} - - - -SCA_IController* SmartControllerPtr::operator*() const -{ - return m_controller; -} - - diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index 17971c219e5..0d610c9cc46 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -43,6 +43,7 @@ #include "GEN_Map.h" #include "STR_HashedString.h" #include "Value.h" +#include "SG_QList.h" #include "KX_HashedPtr.h" @@ -65,44 +66,17 @@ typedef std::map sensormap_t; #include "SCA_ILogicBrick.h" -// todo: make this into a template, but first I want to think about what exactly to put in -class SmartActuatorPtr -{ - SCA_IActuator* m_actuator; -public: - SmartActuatorPtr(SCA_IActuator* actua,int dummy); - SmartActuatorPtr(const SmartActuatorPtr& other); - virtual ~SmartActuatorPtr(); - bool operator <(const SmartActuatorPtr& other) const; - bool operator ==(const SmartActuatorPtr& other) const; - SCA_IActuator* operator->() const; - SCA_IActuator* operator*() const; - -}; - -class SmartControllerPtr -{ - SCA_IController* m_controller; -public: - SmartControllerPtr(const SmartControllerPtr& copy); - SmartControllerPtr(SCA_IController* contr,int dummy); - virtual ~SmartControllerPtr(); - bool operator <(const SmartControllerPtr& other) const; - bool operator ==(const SmartControllerPtr& other) const; - SCA_IController* operator->() const; - SCA_IController* operator*() const; - -}; class SCA_LogicManager { vector m_eventmanagers; - vector m_activatedsensors; - set m_activeActuators; - set m_triggeredControllerSet; - - sensormap_t m_sensorcontrollermapje; + // SG_DList: Head of objects having activated actuators + // element: SCA_IObject::m_activeActuators + SG_DList m_activeActuators; + // SG_DList: Head of objects having activated controllers + // element: SCA_IObject::m_activeControllers + SG_DList m_triggeredControllerSet; // need to find better way for this // also known as FactoryManager... @@ -113,12 +87,11 @@ class SCA_LogicManager GEN_Map m_map_gamemeshname_to_blendobj; GEN_Map m_map_blendobj_to_gameobj; - vector m_removedActuators; + // head of actuators being deactivated during the logic update + SG_DList m_removedActuators; public: SCA_LogicManager(); virtual ~SCA_LogicManager(); - // can ONLY be used during scene destruction, avoid massive slow down when scene has many many objects - void RemoveSensorMap(); //void SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;} void RegisterEventManager(SCA_EventManager* eventmgr); @@ -130,8 +103,7 @@ public: void BeginFrame(double curtime, double fixedtime); void UpdateFrame(double curtime, bool frame); void EndFrame(); - void AddActivatedSensor(SCA_ISensor* sensor); - void AddActiveActuator(SCA_IActuator* sensor,class CValue* event); + void AddActiveActuator(SCA_IActuator* sensor,bool event); void AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor); SCA_EventManager* FindEventManager(int eventmgrtype); @@ -142,7 +114,7 @@ public: */ void RemoveSensor(SCA_ISensor* sensor); void RemoveController(SCA_IController* controller); - void RemoveDestroyedActuator(SCA_IActuator* actuator); + void RemoveActuator(SCA_IActuator* actuator); // for the scripting... needs a FactoryManager later (if we would have time... ;) diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp index ca875dad07c..d407647cec3 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.cpp +++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp @@ -75,8 +75,8 @@ void SCA_MouseManager::NextFrame() { if (m_mousedevice) { - set::iterator it; - for (it=m_sensors.begin(); it!=m_sensors.end(); it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it); // (0,0) is the Upper Left corner in our local window @@ -93,7 +93,7 @@ void SCA_MouseManager::NextFrame() mousesensor->setX(mx); mousesensor->setY(my); - mousesensor->Activate(m_logicmanager,NULL); + mousesensor->Activate(m_logicmanager); } } } diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index 46be6ad9e16..c5e1c3c0441 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -144,7 +144,7 @@ SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey() -bool SCA_MouseSensor::Evaluate(CValue* event) +bool SCA_MouseSensor::Evaluate() { bool result = false; bool reset = m_reset && m_level; diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index 528237475db..6d6302b514a 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -97,7 +97,7 @@ class SCA_MouseSensor : public SCA_ISensor virtual ~SCA_MouseSensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual void Init(); virtual bool IsPositiveTrigger(); short int GetModeKey(); diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index df62f91aaed..d27aea5e6f7 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -73,19 +73,12 @@ void SCA_NANDController::Trigger(SCA_LogicManager* logicmgr) } } - CValue* newevent = new CBoolValue(sensorresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - logicmgr->AddActiveActuator(actua,newevent); + SCA_IActuator* actua = *i; + logicmgr->AddActiveActuator(actua,sensorresult); } - - // every actuator that needs the event, has a it's own reference to it now so - // release it (so to be clear: if there is no actuator, it's deleted right now) - newevent->Release(); - } diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index b87af965a50..6c9141636b2 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -73,19 +73,12 @@ void SCA_NORController::Trigger(SCA_LogicManager* logicmgr) } } - CValue* newevent = new CBoolValue(sensorresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - logicmgr->AddActiveActuator(actua,newevent); + SCA_IActuator* actua = *i; + logicmgr->AddActiveActuator(actua,sensorresult); } - - // every actuator that needs the event, has a it's own reference to it now so - // release it (so to be clear: if there is no actuator, it's deleted right now) - newevent->Release(); - } diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 7aa58b6c320..42c0a67d657 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -80,17 +80,12 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr) is++; } - CValue* newevent = new CBoolValue(sensorresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - logicmgr->AddActiveActuator(actua,newevent); + SCA_IActuator* actua = *i; + logicmgr->AddActiveActuator(actua,sensorresult); } - - - newevent->Release(); } /* ------------------------------------------------------------------------- */ diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp index e5e3f9cced5..764465309df 100644 --- a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp @@ -50,8 +50,9 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager() void SCA_PropertyEventManager::NextFrame() { // check for changed properties - for (set::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - (*it)->Activate(m_logicmgr,NULL); + (*it)->Activate(m_logicmgr); } } diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index e8a291b0a92..2632cbd3dac 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -37,6 +37,7 @@ #include "StringValue.h" #include "SCA_EventManager.h" #include "SCA_LogicManager.h" +#include "BoolValue.h" #ifdef HAVE_CONFIG_H #include @@ -152,7 +153,7 @@ SCA_PropertySensor::~SCA_PropertySensor() -bool SCA_PropertySensor::Evaluate(CValue* event) +bool SCA_PropertySensor::Evaluate() { bool result = CheckPropertyCondition(); bool reset = m_reset && m_level; @@ -182,17 +183,14 @@ bool SCA_PropertySensor::CheckPropertyCondition() CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname); if (!orgprop->IsError()) { - STR_String testprop = orgprop->GetText(); + const STR_String& testprop = orgprop->GetText(); // Force strings to upper case, to avoid confusion in // bool tests. It's stupid the prop's identity is lost // on the way here... - if ((testprop == "TRUE") || (testprop == "FALSE")) { - STR_String checkprop = m_checkpropval; - checkprop.Upper(); - result = (testprop == checkprop); - } else { - result = (orgprop->GetText() == m_checkpropval); + if ((&testprop == &CBoolValue::sTrueString) || (&testprop == &CBoolValue::sFalseString)) { + m_checkpropval.Upper(); } + result = (testprop == m_checkpropval); } orgprop->Release(); @@ -232,8 +230,8 @@ bool SCA_PropertySensor::CheckPropertyCondition() CValue* vallie = m_range_expr->Calculate(); if (vallie) { - STR_String errtext = vallie->GetText(); - if (errtext == "TRUE") + const STR_String& errtext = vallie->GetText(); + if (&errtext == &CBoolValue::sTrueString) { result = true; } else diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index 7abf4d44a5b..538ecd65949 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -81,7 +81,7 @@ public: void PrecalculateRangeExpression(); bool CheckPropertyCondition(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual CValue* FindIdentifier(const STR_String& identifiername); diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 063a7b47321..212366e6526 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -178,7 +178,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) if (PyString_Check(value)) { /* get the actuator from the name */ char *name= PyString_AsString(value); - for(it = lacts.begin(); it!= lacts.end(); it++) { + for(it = lacts.begin(); it!= lacts.end(); ++it) { if( name == (*it)->GetName() ) { return *it; } @@ -186,7 +186,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) } else if (BGE_PROXY_CHECK_TYPE(value)) { PyObjectPlus *value_plus= BGE_PROXY_REF(value); - for(it = lacts.begin(); it!= lacts.end(); it++) { + for(it = lacts.begin(); it!= lacts.end(); ++it) { if( static_cast(value_plus) == (*it) ) { return *it; } @@ -215,9 +215,8 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* a if(actu==NULL) return NULL; - CValue* boolval = new CBoolValue(activate!=0); + bool boolval = (activate!=0); m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval); - boolval->Release(); Py_RETURN_NONE; } @@ -473,7 +472,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) Py_DECREF(excdict); } - m_triggeredSensors.erase(m_triggeredSensors.begin(), m_triggeredSensors.end()); + m_triggeredSensors.clear(); m_sCurrentController = NULL; } @@ -499,9 +498,7 @@ PyObject* SCA_PythonController::PyActivate(PyObject *value) if(actu==NULL) return NULL; - CValue* boolval = new CBoolValue(true); - m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval); - boolval->Release(); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, true); Py_RETURN_NONE; } @@ -511,9 +508,7 @@ PyObject* SCA_PythonController::PyDeActivate(PyObject *value) if(actu==NULL) return NULL; - CValue* boolval = new CBoolValue(false); - m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval); - boolval->Release(); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, false); Py_RETURN_NONE; } diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp index 156478d866d..976597aa812 100644 --- a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp @@ -50,9 +50,10 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr) void SCA_RandomEventManager::NextFrame() { - for (set::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - (*i)->Activate(m_logicmgr, NULL); + (*it)->Activate(m_logicmgr); } } diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 5c109bac024..1581a29480e 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -89,7 +89,7 @@ bool SCA_RandomSensor::IsPositiveTrigger() } -bool SCA_RandomSensor::Evaluate(CValue* event) +bool SCA_RandomSensor::Evaluate() { /* Random generator is the generator from Line 25 of Table 1 in */ /* [KNUTH 1981, The Art of Computer Programming Vol. 2 */ diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 63a96dd72d0..27b41841f0b 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -52,7 +52,7 @@ public: PyTypeObject* T=&Type); virtual ~SCA_RandomSensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp index b7fadd3d62c..911ea772bef 100644 --- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp @@ -52,7 +52,7 @@ SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr) SCA_TimeEventManager::~SCA_TimeEventManager() { for (vector::iterator it = m_timevalues.begin(); - !(it == m_timevalues.end()); it++) + !(it == m_timevalues.end()); ++it) { (*it)->Release(); } @@ -80,7 +80,7 @@ void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime) // update sensors, but ... need deltatime ! for (vector::iterator it = m_timevalues.begin(); - !(it == m_timevalues.end()); it++) + !(it == m_timevalues.end()); ++it) { float newtime = (*it)->GetNumber() + fixedtime; floatval->SetFloat(newtime); @@ -104,7 +104,7 @@ void SCA_TimeEventManager::AddTimeProperty(CValue* timeval) void SCA_TimeEventManager::RemoveTimeProperty(CValue* timeval) { for (vector::iterator it = m_timevalues.begin(); - !(it == m_timevalues.end()); it++) + !(it == m_timevalues.end()); ++it) { if ((*it) == timeval) { diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index 9b0fe51c5b8..aee8e26c21a 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -77,19 +77,12 @@ void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr) } } - CValue* newevent = new CBoolValue(sensorresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - logicmgr->AddActiveActuator(actua,newevent); + SCA_IActuator* actua = *i; + logicmgr->AddActiveActuator(actua,sensorresult); } - - // every actuator that needs the event, has a it's own reference to it now so - // release it (so to be clear: if there is no actuator, it's deleted right now) - newevent->Release(); - } diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 9232120075f..5afb3a750f5 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -77,19 +77,12 @@ void SCA_XORController::Trigger(SCA_LogicManager* logicmgr) } } - CValue* newevent = new CBoolValue(sensorresult); - for (vector::const_iterator i=m_linkedactuators.begin(); !(i==m_linkedactuators.end());i++) { - SCA_IActuator* actua = *i;//m_linkedactuators.at(i); - logicmgr->AddActiveActuator(actua,newevent); + SCA_IActuator* actua = *i; + logicmgr->AddActiveActuator(actua,sensorresult); } - - // every actuator that needs the event, has a it's own reference to it now so - // release it (so to be clear: if there is no actuator, it's deleted right now) - newevent->Release(); - } diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index ebf225f728f..189c39ee237 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp') incs = '. #/source/kernel/gen_system #/intern/string' incs += ' #/source/gameengine/Expressions #/intern/moto/include' -incs += ' #/source/gameengine/Rasterizer' +incs += ' #/source/gameengine/Rasterizer #/source/gameengine/Scenegraph' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt index fa0ca378c6b..eb1d5fc67a3 100644 --- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt +++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt @@ -33,6 +33,7 @@ SET(INC ../../../../source/gameengine/Ketsji ../../../../source/gameengine/GameLogic ../../../../source/gameengine/Expressions + ../../../../source/gameengine/Scenegraph ../../../../source/gameengine/Network ${PYTHON_INC} ) diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp index eee8e9f6827..738f64713b0 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp @@ -61,12 +61,12 @@ void KX_NetworkEventManager::NextFrame() // each frame, the logicmanager will call the network // eventmanager to look for network events, and process it's // 'network' sensors - set::iterator it; - - for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) { + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) + { // printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime); // process queue - (*it)->Activate(m_logicmgr, NULL); + (*it)->Activate(m_logicmgr); } // now a list of triggerer sensors has been built diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp index 7f21c490e67..63773352d96 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp @@ -75,7 +75,7 @@ bool KX_NetworkMessageActuator::Update() m_toPropName, GetParent()->GetName(), m_subject, - GetParent()->GetPropertyText(m_body,"")); + GetParent()->GetPropertyText(m_body)); } else { m_networkscene->SendMessage( diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index 82e2437064b..8ddcd87b66f 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -85,7 +85,7 @@ CValue* KX_NetworkMessageSensor::GetReplica() { } // Return true only for flank (UP and DOWN) -bool KX_NetworkMessageSensor::Evaluate(CValue* event) +bool KX_NetworkMessageSensor::Evaluate() { bool result = false; bool WasUp = m_IsUp; @@ -102,8 +102,8 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event) m_SubjectList = NULL; } - STR_String toname=GetParent()->GetName(); - STR_String subject = this->m_subject; + STR_String& toname=GetParent()->GetName(); + STR_String& subject = this->m_subject; vector messages = m_NetworkScene->FindMessages(toname,"",subject,true); @@ -123,9 +123,9 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event) for (mesit=messages.begin();mesit!=messages.end();mesit++) { // save the body - STR_String body = (*mesit)->GetMessageText(); + const STR_String& body = (*mesit)->GetMessageText(); // save the subject - STR_String messub = (*mesit)->GetSubject(); + const STR_String& messub = (*mesit)->GetSubject(); #ifdef NAN_NET_DEBUG if (body) { cout << "body [" << body << "]\n"; diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 3abba7cfffd..53183f33826 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -63,7 +63,7 @@ public: virtual ~KX_NetworkMessageSensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); void EndFrame(); diff --git a/source/gameengine/Ketsji/KXNetwork/Makefile b/source/gameengine/Ketsji/KXNetwork/Makefile index ddcb03600d5..ec3099611e0 100644 --- a/source/gameengine/Ketsji/KXNetwork/Makefile +++ b/source/gameengine/Ketsji/KXNetwork/Makefile @@ -40,6 +40,7 @@ CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I../../Expressions CPPFLAGS += -I../../GameLogic +CPPFLAGS += -I../../Scenegraph CPPFLAGS += -I../../Network CPPFLAGS += -I../../../kernel/gen_system CPPFLAGS += -I.. diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 2476ed1f275..26f95fab8af 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Ketsji' incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions' -incs += ' #source/gameengine/Network' +incs += ' #source/gameengine/Network #source/gameengine/Scenegraph' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 65a026656c5..3b8917efe90 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -643,8 +643,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const if (mode &USECUSTOMUV) { - STR_String str = mMaterial->mapping[i].uvCoName; - if (!str.IsEmpty()) + if (!mMaterial->mapping[i].uvCoName.IsEmpty()) ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i); continue; } @@ -717,6 +716,8 @@ void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras) if(!obj) return; obj->Release(); /* FindValue() AddRef's */ + obj->Release(); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index e701a680511..5f7197e31f1 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -454,7 +454,7 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_ob->GetName()); + return PyString_FromString(m_ob->GetName().ReadPtr()); else return m_ob->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 2f5b5631761..4d01d96ced4 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -188,14 +188,14 @@ double KX_GameObject::GetNumber() -STR_String KX_GameObject::GetName() +STR_String& KX_GameObject::GetName() { return m_name; } -void KX_GameObject::SetName(STR_String name) +void KX_GameObject::SetName(const char *name) { m_name = name; }; // Set the name of the value @@ -452,14 +452,6 @@ void KX_GameObject::AddMeshUser() double* fl = GetOpenGLMatrixPtr()->getPointer(); RAS_Deformer *deformer = GetDeformer(); - //RAS_MeshSlot *ms; - //for(ms =static_cast(m_meshSlots.QPeek()); - // ms!=static_cast(m_meshSlots.Self()); - // ms =static_cast(ms->QPeek())) - //{ - // ms->m_OpenGLMatrix = fl; - // ms->SetDeformer(deformer); - //} SG_QList::iterator mit(m_meshSlots); for(mit.begin(); !mit.end(); ++mit) { @@ -493,9 +485,7 @@ void KX_GameObject::UpdateBuckets( bool recursive ) if (GetSGNode()->IsDirty()) GetOpenGLMatrix(); - //for(ms =static_cast(m_meshSlots.QPeek()); - // ms!=static_cast(m_meshSlots.Self()); - // ms =static_cast(ms->QPeek())) + SG_QList::iterator mit(m_meshSlots); for(mit.begin(); !mit.end(); ++mit) { @@ -1844,7 +1834,7 @@ int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro m if (ret==PY_SET_ATTR_COERCE_FAIL) { /* CValue attribute exists, remove CValue and add PyDict value */ - RemoveProperty(STR_String(PyString_AsString(attr))); + RemoveProperty(PyString_AsString(attr)); ret= PY_SET_ATTR_MISSING; } @@ -1871,7 +1861,7 @@ int KX_GameObject::py_delattro(PyObject *attr) { char *attr_str= PyString_AsString(attr); - if (RemoveProperty(STR_String(attr_str))) // XXX - should call CValues instead but its only 2 lines here + if (RemoveProperty(attr_str)) // XXX - should call CValues instead but its only 2 lines here return 0; if (m_attr_dict && (PyDict_DelItem(m_attr_dict, attr) == 0)) diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 8fafcc1f9b6..e5b26539d4d 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -241,7 +241,7 @@ public: /** * Inherited from CValue -- returns the name of this object. */ - STR_String + STR_String& GetName( ); @@ -250,7 +250,7 @@ public: */ void SetName( - STR_String name + const char *name ); /** diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index efe01993b08..5e1785e9c21 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -164,14 +164,14 @@ bool KX_IpoActuator::Update(double curtime, bool frame) // result = true if animation has to be continued, false if animation stops // maybe there are events for us in the queue ! bool bNegativeEvent = false; - int numevents = 0; + bool numevents = false; bool bIpoStart = false; curtime -= KX_KetsjiEngine::GetSuspendedDelta(); if (frame) { - numevents = m_events.size(); + numevents = m_posevent || m_negevent; bNegativeEvent = IsNegativeEvent(); RemoveAllEvents(); } @@ -273,7 +273,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame) { result = false; m_bNegativeEvent = false; - numevents = 0; + numevents = false; } if (!m_bIpoPlaying) { diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index c0b05859539..0d1bc289a5c 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -71,7 +71,6 @@ PyTypeObject KX_MeshProxy::Type = { PyParentObject KX_MeshProxy::Parents[] = { &KX_MeshProxy::Type, - &SCA_IObject::Type, &CValue::Type, &PyObjectPlus::Type, NULL @@ -110,21 +109,21 @@ void KX_MeshProxy::SetMeshModified(bool v) PyObject* KX_MeshProxy::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IObject); + py_getattro_up(CValue); } PyObject* KX_MeshProxy::py_getattro_dict() { - py_getattro_dict_up(SCA_IObject); + py_getattro_dict_up(CValue); } int KX_MeshProxy::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IObject); + py_setattro_up(CValue); } KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh) - : SCA_IObject(&Type), m_meshobj(mesh) + : CValue(&Type), m_meshobj(mesh) { } @@ -140,8 +139,8 @@ CValue* KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValu const STR_String & KX_MeshProxy::GetText() {return m_meshobj->GetName();}; double KX_MeshProxy::GetNumber() { return -1;} -STR_String KX_MeshProxy::GetName() { return m_meshobj->GetName();} -void KX_MeshProxy::SetName(STR_String name) { }; +STR_String& KX_MeshProxy::GetName() { return m_meshobj->GetName();} +void KX_MeshProxy::SetName(const char *name) { }; CValue* KX_MeshProxy::GetReplica() { return NULL;} diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index f775c963c1e..bfdd4be4118 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -34,7 +34,7 @@ /* utility conversion function */ bool ConvertPythonToMesh(PyObject * value, class RAS_MeshObject **object, bool py_none_ok, const char *error_prefix); -class KX_MeshProxy : public SCA_IObject +class KX_MeshProxy : public CValue { Py_Header; @@ -51,8 +51,8 @@ public: virtual const STR_String & GetText(); virtual double GetNumber(); virtual RAS_MeshObject* GetMesh() { return m_meshobj; } - virtual STR_String GetName(); - virtual void SetName(STR_String name); // Set the name of the value + virtual STR_String& GetName(); + virtual void SetName(const char *name); // Set the name of the value virtual CValue* GetReplica(); // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 8b7c3cb928b..74b5c923db8 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -86,7 +86,7 @@ void KX_MouseFocusSensor::Init() m_hitNormal.setValue(0,0,1); } -bool KX_MouseFocusSensor::Evaluate(CValue* event) +bool KX_MouseFocusSensor::Evaluate() { bool result = false; bool obHasFocus = false; @@ -119,7 +119,7 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event) * mode is never used, because the converter never makes this * sensor for a mouse-key event. It is here for * completeness. */ - result = SCA_MouseSensor::Evaluate(event); + result = SCA_MouseSensor::Evaluate(); m_positive_event = (m_val!=0); } diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 350fda198db..29d674eb305 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -69,7 +69,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor /** * @attention Overrides default evaluate. */ - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual void Init(); virtual bool IsPositiveTrigger() { diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index e7f05555b64..a3c4e95ae24 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -160,7 +160,7 @@ KX_NearSensor::~KX_NearSensor() } -bool KX_NearSensor::Evaluate(CValue* event) +bool KX_NearSensor::Evaluate() { bool result = false; // KX_GameObject* parent = static_cast(GetParent()); diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 5b65312472a..35136b79d13 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -71,7 +71,7 @@ public: virtual void SynchronizeTransform(); virtual CValue* GetReplica(); virtual void ProcessReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual void ReParent(SCA_IObject* parent); virtual bool NewHandleCollision(void* obj1,void* obj2, diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index f55ffd4f69a..c5248785b12 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -267,7 +267,7 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_ob->GetName()); + return PyString_FromString(m_ob->GetName().ReadPtr()); else return m_ob->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index ca38117a9e7..b56b5500c39 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -64,8 +64,8 @@ PyTypeObject KX_PolyProxy::Type = { PyParentObject KX_PolyProxy::Parents[] = { &KX_PolyProxy::Type, - &SCA_IObject::Type, &CValue::Type, + &PyObjectPlus::Type, NULL }; @@ -162,11 +162,11 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr) { return PyInt_FromLong(m_polygon->IsCollider()); } - py_getattro_up(SCA_IObject); + py_getattro_up(CValue); } PyObject* KX_PolyProxy::py_getattro_dict() { - py_getattro_dict_up(SCA_IObject); + py_getattro_dict_up(CValue); } KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon) @@ -186,8 +186,8 @@ CValue* KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { re STR_String sPolyName="polygone"; const STR_String & KX_PolyProxy::GetText() {return sPolyName;}; double KX_PolyProxy::GetNumber() { return -1;} -STR_String KX_PolyProxy::GetName() { return sPolyName;} -void KX_PolyProxy::SetName(STR_String) { }; +STR_String& KX_PolyProxy::GetName() { return sPolyName;} +void KX_PolyProxy::SetName(const char *) { }; CValue* KX_PolyProxy::GetReplica() { return NULL;} // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index 223193ec519..d8fd36fec6c 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -31,7 +31,7 @@ #include "SCA_IObject.h" -class KX_PolyProxy : public SCA_IObject +class KX_PolyProxy : public CValue { Py_Header; protected: @@ -46,8 +46,8 @@ public: CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); const STR_String & GetText(); double GetNumber(); - STR_String GetName(); - void SetName(STR_String name); // Set the name of the value + STR_String& GetName(); + void SetName(const char *name); // Set the name of the value CValue* GetReplica(); diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 039cf640a6f..42b1850a454 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -91,7 +91,7 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) switch(self->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: { - vector linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + vector& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); if(index<0) index += linkedsensors.size(); if(index<0 || index>= linkedsensors.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -101,7 +101,7 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) } case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: { - vector linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + vector& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); if(index<0) index += linkedactuators.size(); if(index<0 || index>= linkedactuators.size()) { PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); @@ -168,7 +168,7 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) switch(self->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: { - vector linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + vector& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); SCA_ISensor* sensor; for (unsigned int index=0;index linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + vector& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); SCA_IActuator* actuator; for (unsigned int index=0;index::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - (*i)->Activate(m_logicmgr, NULL); + (*it)->Activate(m_logicmgr); } } diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 43d8806fc68..fdde5fdcf7b 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -178,7 +178,7 @@ bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo* client) return true; } -bool KX_RaySensor::Evaluate(CValue* event) +bool KX_RaySensor::Evaluate() { bool result = false; bool reset = m_reset && m_level; diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 558840e2f17..9efb046742f 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -67,7 +67,7 @@ public: virtual ~KX_RaySensor(); virtual CValue* GetReplica(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 2fd786e44e3..3c72eac3e62 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -87,7 +87,7 @@ KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator() if (m_OriginalObject) m_OriginalObject->UnregisterActuator(this); if (m_lastCreatedObject) - m_lastCreatedObject->Release(); + m_lastCreatedObject->UnregisterActuator(this); } @@ -145,6 +145,12 @@ bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj) m_OriginalObject = NULL; return true; } + if (clientobj == m_lastCreatedObject) + { + // this object is being deleted, we cannot continue to track it. + m_lastCreatedObject = NULL; + return true; + } return false; } @@ -356,7 +362,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_OriginalObject->GetName()); + return PyString_FromString(m_OriginalObject->GetName().ReadPtr()); else return m_OriginalObject->GetProxy(); } @@ -464,13 +470,21 @@ void KX_SCA_AddObjectActuator::InstantAddObject() // keep a copy of the last object, to allow python scripters to change it if (m_lastCreatedObject) { - //careful with destruction, it might still have outstanding collision callbacks - m_scene->DelayedReleaseObject(m_lastCreatedObject); - m_lastCreatedObject->Release(); + //Let's not keep a reference to the object: it's bad, if the object is deleted + //this will force to keep a "zombie" in the game for no good reason. + //m_scene->DelayedReleaseObject(m_lastCreatedObject); + //m_lastCreatedObject->Release(); + + //Instead we use the registration mechanism + m_lastCreatedObject->UnregisterActuator(this); + m_lastCreatedObject = NULL; } m_lastCreatedObject = replica; - m_lastCreatedObject->AddRef(); + // no reference + //m_lastCreatedObject->AddRef(); + // but registration + m_lastCreatedObject->RegisterActuator(this); // finished using replica? then release it replica->Release(); } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 208f8fc9461..84c6d374386 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -164,7 +164,6 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, m_lightlist= new CListValue(); m_inactivelist = new CListValue(); m_euthanasyobjects = new CListValue(); - m_delayReleaseObjects = new CListValue(); m_logicmgr = new SCA_LogicManager(); @@ -223,8 +222,6 @@ KX_Scene::~KX_Scene() // It's still there but we remove all properties here otherwise some // reference might be hanging and causing late release of objects RemoveAllDebugProperties(); - // early removal of sensor map to avoid massive slow down when there are many objects - m_logicmgr->RemoveSensorMap(); while (GetRootParentList()->GetCount() > 0) { @@ -249,8 +246,6 @@ KX_Scene::~KX_Scene() if (m_euthanasyobjects) m_euthanasyobjects->Release(); - if (m_delayReleaseObjects) - m_delayReleaseObjects->Release(); if (m_logicmgr) delete m_logicmgr; @@ -419,11 +414,11 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam KX_GameObject* orgobj = (KX_GameObject*)gameobj; if (NewRemoveObject(orgobj) != 0) { - // object is not yet deleted (this can happen when it hangs in an add object actuator - // last object created reference. It's a bad situation, don't know how to fix it exactly - // The least I can do, is remove the reference to the node in the object as the node - // will in any case be deleted. This ensures that the object will not try to use the node - // when it is finally deleted (see KX_GameObject destructor) + // object is not yet deleted because a reference is hanging somewhere. + // This should not happen anymore since we use proxy object for Python + // confident enough to put an assert? + //assert(false); + printf("Zombie object! name=%s\n", orgobj->GetName().ReadPtr()); orgobj->SetSGNode(NULL); PHY_IGraphicController* ctrl = orgobj->GetGraphicController(); if (ctrl) @@ -550,8 +545,9 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj) vector linkedactuators = cont->GetLinkedActuators(); // disconnect the sensors and actuators - cont->UnlinkAllSensors(); - cont->UnlinkAllActuators(); + // do it directly on the list at this controller is not connected to anything at this stage + cont->GetLinkedSensors().clear(); + cont->GetLinkedActuators().clear(); // now relink each sensor for (vector::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++) @@ -908,14 +904,6 @@ void KX_Scene::RemoveObject(class CValue* gameobj) { KX_GameObject* newobj = (KX_GameObject*) gameobj; - /* Invalidate the python reference, since the object may exist in script lists - * its possible that it wont be automatically invalidated, so do it manually here, - * - * if for some reason the object is added back into the scene python can always get a new Proxy - */ - gameobj->InvalidateProxy(); - - // disconnect child from parent SG_Node* node = newobj->GetSGNode(); @@ -930,12 +918,6 @@ void KX_Scene::RemoveObject(class CValue* gameobj) //newobj->SetSGNode(0); } -void KX_Scene::DelayedReleaseObject(CValue* gameobj) -{ - m_delayReleaseObjects->Add(gameobj->AddRef()); -} - - void KX_Scene::DelayedRemoveObject(class CValue* gameobj) { //KX_GameObject* newobj = (KX_GameObject*) gameobj; @@ -952,6 +934,13 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) int ret; KX_GameObject* newobj = (KX_GameObject*) gameobj; + /* Invalidate the python reference, since the object may exist in script lists + * its possible that it wont be automatically invalidated, so do it manually here, + * + * if for some reason the object is added back into the scene python can always get a new Proxy + */ + newobj->InvalidateProxy(); + // keep the blender->game object association up to date // note that all the replicas of an object will have the same // blender object, that's why we need to check the game object @@ -981,7 +970,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) for (SCA_ActuatorList::iterator ita = actuators.begin(); !(ita==actuators.end());ita++) { - m_logicmgr->RemoveDestroyedActuator(*ita); + m_logicmgr->RemoveActuator(*ita); } // the sensors/controllers/actuators must also be released, this is done in ~SCA_IObject @@ -1464,23 +1453,16 @@ void KX_Scene::LogicEndFrame() m_logicmgr->EndFrame(); int numobj = m_euthanasyobjects->GetCount(); int i; - for (i = numobj - 1; i >= 0; i--) - { - KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i); - // KX_Scene::RemoveObject will also remove the object from this list - // that's why we start from the end - this->RemoveObject(gameobj); - } + KX_GameObject* obj; - numobj= m_delayReleaseObjects->GetCount(); - for (i = numobj-1;i>=0;i--) + while ((numobj = m_euthanasyobjects->GetCount()) > 0) { - KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i); - // This list is not for object removal, but just object release - gameobj->Release(); + // remove the object from this list to make sure we will not hit it again + obj = (KX_GameObject*)m_euthanasyobjects->GetValue(numobj-1); + m_euthanasyobjects->Remove(numobj-1); + obj->Release(); + RemoveObject(obj); } - // empty the list as we have removed all references - m_delayReleaseObjects->Resize(0); } diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 0cfef8b7bd1..128f8d23135 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -108,11 +108,6 @@ protected: * LogicEndFrame() via a call to RemoveObject(). */ CListValue* m_euthanasyobjects; - /** - * The list of objects that couldn't be released during logic update. - * for example, AddObject actuator sometimes releases an object that was cached from previous frame - */ - CListValue* m_delayReleaseObjects; CListValue* m_objectlist; CListValue* m_parentlist; // all 'root' parents @@ -331,8 +326,6 @@ public: void RemoveObject(CValue* gameobj); void DelayedRemoveObject(CValue* gameobj); - void DelayedReleaseObject(CValue* gameobj); - int NewRemoveObject(CValue* gameobj); void ReplaceMesh(CValue* gameobj, void* meshobj); diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 15eb354ee79..07a880c950b 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -83,17 +83,19 @@ CValue* KX_SoundActuator::GetReplica() { KX_SoundActuator* replica = new KX_SoundActuator(*this); replica->ProcessReplica(); - if (m_soundObject) - { - SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject); - replica->setSoundObject(soundobj); - m_soundScene->AddObject(soundobj); - } - return replica; }; - +void KX_SoundActuator::ProcessReplica() +{ + SCA_IActuator::ProcessReplica(); + if (m_soundObject) + { + SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject); + setSoundObject(soundobj); + m_soundScene->AddObject(soundobj); + } +} bool KX_SoundActuator::Update(double curtime, bool frame) { diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index ad58087dc57..a7491355667 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -75,6 +75,7 @@ public: virtual bool Update(double curtime, bool frame); CValue* GetReplica(); + void ProcessReplica(); /* -------------------------------------------------------------------- */ /* Python interface --------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 48d4cf59a2b..8ae5fae8fa3 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -100,7 +100,7 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data, void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor) { KX_TouchSensor* touchsensor = static_cast(sensor); - if (m_sensors.insert(touchsensor).second) + if (m_sensors.AddBack(touchsensor)) // the sensor was effectively inserted, register it touchsensor->RegisterSumo(this); } @@ -108,7 +108,7 @@ void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor) void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor) { KX_TouchSensor* touchsensor = static_cast(sensor); - if (m_sensors.erase(touchsensor)) + if (touchsensor->Delink()) // the sensor was effectively removed, unregister it touchsensor->UnregisterSumo(this); } @@ -117,12 +117,10 @@ void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor) void KX_TouchEventManager::EndFrame() { - set::iterator it; - for ( it = m_sensors.begin(); - !(it==m_sensors.end());it++) + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) { - ((KX_TouchSensor*)*it)->EndFrame(); - + (*it)->EndFrame(); } } @@ -130,12 +128,11 @@ void KX_TouchEventManager::EndFrame() void KX_TouchEventManager::NextFrame() { - if (m_sensors.size() > 0) + if (!m_sensors.Empty()) { - set::iterator it; - - for (it = m_sensors.begin();!(it==m_sensors.end());++it) - static_cast(*it)->SynchronizeTransform(); + SG_DList::iterator it(m_sensors); + for (it.begin();!it.end();++it) + (*it)->SynchronizeTransform(); for (std::set::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit) { @@ -161,7 +158,7 @@ void KX_TouchEventManager::NextFrame() m_newCollisions.clear(); - for (it = m_sensors.begin();!(it==m_sensors.end());++it) - (*it)->Activate(m_logicmgr,NULL); + for (it.begin();!it.end();++it) + (*it)->Activate(m_logicmgr); } } diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index f000c16041a..2c02d949c63 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -66,10 +66,10 @@ void KX_TouchSensor::UnregisterToManager() { // before unregistering the sensor, make sure we release all references EndFrame(); - m_eventmgr->RemoveSensor(this); + SCA_ISensor::UnregisterToManager(); } -bool KX_TouchSensor::Evaluate(CValue* event) +bool KX_TouchSensor::Evaluate() { bool result = false; bool reset = m_reset && m_level; diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 056b5701937..9c9c6bf5816 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -86,7 +86,7 @@ public: virtual CValue* GetReplica(); virtual void ProcessReplica(); virtual void SynchronizeTransform(); - virtual bool Evaluate(CValue* event); + virtual bool Evaluate(); virtual void Init(); virtual void ReParent(SCA_IObject* parent); diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 672b9e739ba..800da83dc3d 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -83,6 +83,10 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, // if so, store the initial local rotation // this is needed to revert the effect of the parent inverse node (TBC) m_parentlocalmat = m_parentobj->GetSGNode()->GetLocalOrientation(); + // use registration mechanism rather than AddRef, it creates zombie objects + m_parentobj->RegisterActuator(this); + // GetParent did AddRef, undo here + m_parentobj->Release(); } } } @@ -189,7 +193,7 @@ KX_TrackToActuator::~KX_TrackToActuator() if (m_object) m_object->UnregisterActuator(this); if (m_parentobj) - m_parentobj->Release(); + m_parentobj->UnregisterActuator(this); } /* end of destructor */ void KX_TrackToActuator::ProcessReplica() @@ -198,7 +202,7 @@ void KX_TrackToActuator::ProcessReplica() if (m_object) m_object->RegisterActuator(this); if (m_parentobj) - m_parentobj->AddRef(); + m_parentobj->RegisterActuator(this); SCA_IActuator::ProcessReplica(); } @@ -211,6 +215,11 @@ bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj) m_object = NULL; return true; } + if (clientobj == m_parentobj) + { + m_parentobj = NULL; + return true; + } return false; } @@ -227,9 +236,9 @@ void KX_TrackToActuator::Relink(GEN_Map *obj_map) void **h_parobj = (*obj_map)[m_parentobj]; if (h_parobj) { if (m_parentobj) - m_parentobj->Release(); + m_parentobj->UnregisterActuator(this); m_parentobj= (KX_GameObject*)(*h_parobj); - m_parentobj->AddRef(); + m_parentobj->RegisterActuator(this); } } diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 6563d0446eb..4b0ad083473 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -62,8 +62,8 @@ PyTypeObject KX_VertexProxy::Type = { PyParentObject KX_VertexProxy::Parents[] = { &KX_VertexProxy::Type, - &SCA_IObject::Type, &CValue::Type, + &PyObjectPlus::Type, NULL }; @@ -162,11 +162,11 @@ KX_VertexProxy::py_getattro(PyObject *attr) return PyObjectFrom(MT_Vector3(m_vertex->getNormal())); } - py_getattro_up(SCA_IObject); + py_getattro_up(CValue); } PyObject* KX_VertexProxy::py_getattro_dict() { - py_getattro_dict_up(SCA_IObject); + py_getattro_dict_up(CValue); } int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) @@ -322,7 +322,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } } - return SCA_IObject::py_setattro(attr, pyvalue); + return CValue::py_setattro(attr, pyvalue); } KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex) @@ -343,8 +343,8 @@ CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { STR_String sVertexName="vertex"; const STR_String & KX_VertexProxy::GetText() {return sVertexName;}; double KX_VertexProxy::GetNumber() { return -1;} -STR_String KX_VertexProxy::GetName() { return sVertexName;} -void KX_VertexProxy::SetName(STR_String) { }; +STR_String& KX_VertexProxy::GetName() { return sVertexName;} +void KX_VertexProxy::SetName(const char *) { }; CValue* KX_VertexProxy::GetReplica() { return NULL;} // stuff for python integration diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 81dd0d222a7..42db5fbc322 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -31,7 +31,7 @@ #include "SCA_IObject.h" -class KX_VertexProxy : public SCA_IObject +class KX_VertexProxy : public CValue { Py_Header; protected: @@ -47,8 +47,8 @@ public: CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); const STR_String & GetText(); double GetNumber(); - STR_String GetName(); - void SetName(STR_String name); // Set the name of the value + STR_String& GetName(); + void SetName(const char *name); // Set the name of the value CValue* GetReplica(); diff --git a/source/gameengine/Network/NG_NetworkScene.cpp b/source/gameengine/Network/NG_NetworkScene.cpp index 22263a2bdda..f8e489a8f48 100644 --- a/source/gameengine/Network/NG_NetworkScene.cpp +++ b/source/gameengine/Network/NG_NetworkScene.cpp @@ -119,7 +119,7 @@ void NG_NetworkScene::AddObject(NG_NetworkObject* object) { if (! m_networkdevice->IsOnline()) return; - STR_String name = object->GetName(); + const STR_String& name = object->GetName(); m_networkObjects.insert(name, object); } @@ -130,7 +130,7 @@ void NG_NetworkScene::RemoveObject(NG_NetworkObject* object) { if (! m_networkdevice->IsOnline()) return; - STR_String name = object->GetName(); + const STR_String& name = object->GetName(); m_networkObjects.remove(name); } diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index a111ac2786f..200b1c6c89f 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -114,22 +114,15 @@ void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList for (bit = buckets.begin(); bit != buckets.end(); ++bit) { -#if 1 SG_DList::iterator mit((*bit)->GetActiveMeshSlots()); for(mit.begin(); !mit.end(); ++mit) size++; -#else - for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) - if (!mit->IsCulled()) - size++; -#endif } slots.resize(size); for (bit = buckets.begin(); bit != buckets.end(); ++bit) { -#if 1 RAS_MaterialBucket* bucket = *bit; RAS_MeshSlot* ms; // remove the mesh slot form the list, it culls them automatically for next frame @@ -139,11 +132,6 @@ void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList { slots[i++].set(ms, bucket, pnorm); } -#else - for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) - if (!mit->IsCulled()) - slots[i++].set(&*mit, *bit, pnorm); -#endif } if(alpha) diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index c3223cb9448..edd7615efd4 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -179,14 +179,14 @@ list::iterator RAS_MeshObject::GetLastMaterial() -void RAS_MeshObject::SetName(STR_String name) +void RAS_MeshObject::SetName(const char *name) { m_name = name; } -const STR_String& RAS_MeshObject::GetName() +STR_String& RAS_MeshObject::GetName() { return m_name; } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index a2283b9bc5d..fbc3c549a7a 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -97,8 +97,8 @@ public: unsigned int GetLightLayer(); /* name */ - void SetName(STR_String name); - const STR_String& GetName(); + void SetName(const char *name); + STR_String& GetName(); /* modification state */ bool MeshModified(); diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h index dc5afa2ee99..7bef13cc9e3 100644 --- a/source/gameengine/SceneGraph/SG_DList.h +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -54,14 +54,18 @@ public: void begin() { m_current = (T*)m_head.Peek(); - if (m_current == (T*)m_head.Self()) - { - m_current = NULL; - } + } + void back() + { + m_current = (T*)m_head.Back(); } bool end() { - return (NULL == m_current); + return (m_current == (T*)m_head.Self()); + } + bool add_back(T* item) + { + return m_current->AddBack(item); } T* operator*() { @@ -69,12 +73,14 @@ public: } _myT& operator++() { - assert(m_current); + // no check of NULL! make sure you don't try to increment beyond end m_current = (T*)m_current->Peek(); - if (m_current == (T*)m_head.Self()) - { - m_current = NULL; - } + return *this; + } + _myT& operator--() + { + // no check of NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->Back(); return *this; } }; @@ -128,19 +134,23 @@ public: item->m_flink = item->m_blink = item; return item; } - void Delink() // Remove from the middle + bool Delink() // Remove from the middle { - if (!Empty()) - { - m_blink->m_flink = m_flink; - m_flink->m_blink = m_blink; - m_flink = m_blink = this; - } + if (Empty()) + return false; + m_blink->m_flink = m_flink; + m_flink->m_blink = m_blink; + m_flink = m_blink = this; + return true; } inline SG_DList *Peek() // Look at front without removing { return m_flink; } + inline SG_DList *Back() // Look at front without removing + { + return m_blink; + } inline SG_DList *Self() { return this; diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h index 4a254ac36a4..7a6b2e466c9 100644 --- a/source/gameengine/SceneGraph/SG_QList.h +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -55,14 +55,18 @@ public: void begin() { m_current = (T*)m_head.QPeek(); - if (m_current == (T*)m_head.Self()) - { - m_current = NULL; - } + } + void back() + { + m_current = (T*)m_head.QBack(); } bool end() { - return (NULL == m_current); + return (m_current == (T*)m_head.Self()); + } + bool add_back(T* item) + { + return m_current->QAddBack(item); } T* operator*() { @@ -70,12 +74,13 @@ public: } _myT& operator++() { - assert(m_current); m_current = (T*)m_current->QPeek(); - if (m_current == (T*)m_head.Self()) - { - m_current = NULL; - } + return *this; + } + _myT& operator--() + { + // no check on NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->QBack(); return *this; } }; @@ -129,19 +134,23 @@ public: item->m_fqlink = item->m_bqlink = item; return item; } - void QDelink() // Remove from the middle + bool QDelink() // Remove from the middle { - if (!QEmpty()) - { - m_bqlink->m_fqlink = m_fqlink; - m_fqlink->m_bqlink = m_bqlink; - m_fqlink = m_bqlink = this; - } + if (QEmpty()) + return false; + m_bqlink->m_fqlink = m_fqlink; + m_fqlink->m_bqlink = m_bqlink; + m_fqlink = m_bqlink = this; + return true; } inline SG_QList *QPeek() // Look at front without removing { return m_fqlink; } + inline SG_QList *QBack() // Look at front without removing + { + return m_bqlink; + } }; #endif //__SG_QLIST From a6721e549d560c12c07a6a0f14ada3c429d4bc79 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 May 2009 21:22:25 +0000 Subject: [PATCH 195/444] changes to get benoits logic updates building on scons with gcc --- source/gameengine/Converter/KX_ConvertActuators.cpp | 3 ++- source/gameengine/Expressions/SConscript | 2 +- source/gameengine/GameLogic/SConscript | 2 +- source/gameengine/Ketsji/KXNetwork/SConscript | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 76b8540118a..5d3db25b9ed 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -1105,7 +1105,8 @@ void BL_ConvertActuators(char* maggiename, buf = txt_to_buf(_2dfilter->text); if (buf) { - tmp->SetShaderText(STR_String(buf)); + STR_String buf_str= buf; + tmp->SetShaderText(buf_str); MEM_freeN(buf); } } diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 9d6823e3879..12d4a163c86 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('*.cpp') -incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Scenegraph' +incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] cxxflags = [] diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index 189c39ee237..aadc4154298 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp') incs = '. #/source/kernel/gen_system #/intern/string' incs += ' #/source/gameengine/Expressions #/intern/moto/include' -incs += ' #/source/gameengine/Rasterizer #/source/gameengine/Scenegraph' +incs += ' #/source/gameengine/Rasterizer #/source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 26f95fab8af..9dc68669b4a 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Ketsji' incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions' -incs += ' #source/gameengine/Network #source/gameengine/Scenegraph' +incs += ' #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] From 89c2d80d32228a140f27b2b2c0e25b30fc1394a8 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 10 May 2009 21:30:30 +0000 Subject: [PATCH 196/444] Linux compilation problem, better fix --- source/gameengine/Converter/KX_ConvertActuators.cpp | 3 +-- source/gameengine/GameLogic/SCA_2DFilterActuator.cpp | 2 +- source/gameengine/GameLogic/SCA_2DFilterActuator.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 5d3db25b9ed..60d64621665 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -1105,8 +1105,7 @@ void BL_ConvertActuators(char* maggiename, buf = txt_to_buf(_2dfilter->text); if (buf) { - STR_String buf_str= buf; - tmp->SetShaderText(buf_str); + tmp->SetShaderText(buf); MEM_freeN(buf); } } diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index 1aaa59ee207..7682f6755ef 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -95,7 +95,7 @@ bool SCA_2DFilterActuator::Update() } -void SCA_2DFilterActuator::SetShaderText(STR_String& text) +void SCA_2DFilterActuator::SetShaderText(const char *text) { m_shaderText = text; } diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index aea3a35d404..13b9997a010 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -60,7 +60,7 @@ public: PyTypeObject* T=&Type ); - void SetShaderText(STR_String& text); + void SetShaderText(const char *text); virtual ~SCA_2DFilterActuator(); virtual bool Update(); From a417334026946c0eaa9e5dfc600eb12447ec0af0 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 10 May 2009 22:06:11 +0000 Subject: [PATCH 197/444] Linux compilation problem --- source/gameengine/Ketsji/KX_PythonSeq.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 42b1850a454..c2ecf3b384f 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -52,7 +52,7 @@ PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type ) PyObject_DEL( self ); } -static Py_ssize_t KX_PythonSeq_len( KX_PythonSeq * self ) +static int KX_PythonSeq_len( KX_PythonSeq * self ) { PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); @@ -63,15 +63,15 @@ static Py_ssize_t KX_PythonSeq_len( KX_PythonSeq * self ) switch(self->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: - return ((SCA_IController *)self_plus)->GetLinkedSensors().size(); + return (int)(((SCA_IController *)self_plus)->GetLinkedSensors().size()); case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: - return ((SCA_IController *)self_plus)->GetLinkedActuators().size(); + return (int)(((SCA_IController *)self_plus)->GetLinkedActuators().size()); case KX_PYGENSEQ_OB_TYPE_SENSORS: - return ((KX_GameObject *)self_plus)->GetSensors().size(); + return (int)(((KX_GameObject *)self_plus)->GetSensors().size()); case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: - return ((KX_GameObject *)self_plus)->GetControllers().size(); + return (int)(((KX_GameObject *)self_plus)->GetControllers().size()); case KX_PYGENSEQ_OB_TYPE_ACTUATORS: - return ((KX_GameObject *)self_plus)->GetActuators().size(); + return (int)(((KX_GameObject *)self_plus)->GetActuators().size()); default: /* Should never happen */ PyErr_SetString(PyExc_SystemError, "invalid type, internal error"); From 9cc61dd9c8233c8878599aec1bd95fe8019094a6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 May 2009 22:33:21 +0000 Subject: [PATCH 198/444] use the same sequence mapping types as CListValue, hopefully this means it will build on different python versions --- source/gameengine/Ketsji/KX_PythonSeq.cpp | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index c2ecf3b384f..cc8021fc2e4 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -20,7 +20,7 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * The Original Code is: none of this file. * * Contributor(s): Campbell Barton * @@ -52,26 +52,26 @@ PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type ) PyObject_DEL( self ); } -static int KX_PythonSeq_len( KX_PythonSeq * self ) +static Py_ssize_t KX_PythonSeq_len( PyObject * self ) { - PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if(self_plus==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return -1; } - switch(self->type) { + switch(((KX_PythonSeq *)self)->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: - return (int)(((SCA_IController *)self_plus)->GetLinkedSensors().size()); + return ((SCA_IController *)self_plus)->GetLinkedSensors().size(); case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: - return (int)(((SCA_IController *)self_plus)->GetLinkedActuators().size()); + return ((SCA_IController *)self_plus)->GetLinkedActuators().size(); case KX_PYGENSEQ_OB_TYPE_SENSORS: - return (int)(((KX_GameObject *)self_plus)->GetSensors().size()); + return ((KX_GameObject *)self_plus)->GetSensors().size(); case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: - return (int)(((KX_GameObject *)self_plus)->GetControllers().size()); + return ((KX_GameObject *)self_plus)->GetControllers().size(); case KX_PYGENSEQ_OB_TYPE_ACTUATORS: - return (int)(((KX_GameObject *)self_plus)->GetActuators().size()); + return ((KX_GameObject *)self_plus)->GetActuators().size(); default: /* Should never happen */ PyErr_SetString(PyExc_SystemError, "invalid type, internal error"); @@ -79,16 +79,16 @@ static int KX_PythonSeq_len( KX_PythonSeq * self ) } } -static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) +static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index) { - PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if(self_plus==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; } - switch(self->type) { + switch(((KX_PythonSeq *)self)->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: { vector& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); @@ -146,9 +146,9 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index) } -static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) +static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) { - PyObjectPlus *self_plus= BGE_PROXY_REF(self->base); + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); char *name = NULL; if(self_plus==NULL) { @@ -165,7 +165,7 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) return NULL; } - switch(self->type) { + switch(((KX_PythonSeq *)self)->type) { case KX_PYGENSEQ_CONT_TYPE_SENSORS: { vector& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); @@ -228,8 +228,8 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key) } static PyMappingMethods KX_PythonSeq_as_mapping = { - ( inquiry ) KX_PythonSeq_len, /* mp_length */ - ( binaryfunc ) KX_PythonSeq_subscript, /* mp_subscript */ + KX_PythonSeq_len, /* mp_length */ + KX_PythonSeq_subscript, /* mp_subscript */ 0, /* mp_ass_subscript */ }; @@ -238,7 +238,7 @@ static PyMappingMethods KX_PythonSeq_as_mapping = { * Initialize the interator index */ -static PyObject *KX_PythonSeq_getIter( KX_PythonSeq * self ) +static PyObject *KX_PythonSeq_getIter(KX_PythonSeq *self) { if(BGE_PROXY_REF(self->base)==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); @@ -260,9 +260,9 @@ static PyObject *KX_PythonSeq_getIter( KX_PythonSeq * self ) * Return next KX_PythonSeq iter. */ -static PyObject *KX_PythonSeq_nextIter( KX_PythonSeq * self ) +static PyObject *KX_PythonSeq_nextIter(KX_PythonSeq *self) { - PyObject *object = KX_PythonSeq_getIndex(self, self->iter); + PyObject *object = KX_PythonSeq_getIndex((PyObject *)self, self->iter); self->iter++; if( object==NULL ) { From da3bdefb7a17479a7a7076929f5fa7296052fe1a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 00:19:55 +0000 Subject: [PATCH 199/444] update script templates for new BGE api attributes --- release/scripts/scripttemplate_gamelogic.py | 42 +++++++++---------- .../scripts/scripttemplate_gamelogic_basic.py | 14 +++---- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/release/scripts/scripttemplate_gamelogic.py b/release/scripts/scripttemplate_gamelogic.py index 01348e86d0a..8711783a5f8 100644 --- a/release/scripts/scripttemplate_gamelogic.py +++ b/release/scripts/scripttemplate_gamelogic.py @@ -29,58 +29,58 @@ def main(): cont = GameLogic.getCurrentController() # The KX_GameObject that owns this controller. - own = cont.getOwner() + own = cont.owner # for scripts that deal with spacial logic - own_pos = own.getPosition() + own_pos = own.worldPosition # Some example functions, remove to write your own script. # check for a positive sensor, will run on any object without errors. - print 'Logic info for KX_GameObject', own.getName() + print 'Logic info for KX_GameObject', own.name input = False - for sens in cont.getSensors(): + for sens in cont.sensors: # The sensor can be on another object, we may want to use it - own_sens = sens.getOwner() - print ' sensor:', sens.getName(), - if sens.isPositive(): + own_sens = sens.owner + print ' sensor:', sens.name, + if sens.positive: print '(true)' input = True else: print '(false)' - for actu in cont.getActuators(): + for actu in cont.actuators: # The actuator can be on another object, we may want to use it - own_actu = actu.getOwner() - print ' actuator:', actu.getName() + own_actu = actu.owner + print ' actuator:', actu.name # This runs the actuator or turns it off # note that actuators will continue to run unless explicitly turned off. if input: - GameLogic.addActiveActuator(actu, True) + cont.activate(actu) else: - GameLogic.addActiveActuator(actu, False) + cont.deactivate(actu) - # Its also good practice to get sensors and actuators by names - # so any changes to their order wont break the script. + # Its also good practice to get sensors and actuators by name + # rather then index so any changes to their order wont break the script. - # sens_key = cont.getSensor('key_sensor') - # actu_motion = cont.getActuator('motion') + # sens_key = cont.sensors['key_sensor'] + # actu_motion = cont.actuators['motion'] # Loop through all other objects in the scene sce = GameLogic.getCurrentScene() - print 'Scene Objects:', sce.getName() - for ob in sce.getObjectList(): - print ' ', ob.getName(), ob.getPosition() + print 'Scene Objects:', sce.name + for ob in sce.objects: + print ' ', ob.name, ob.worldPosition # Example where collision objects are checked for their properties # adding to our objects "life" property """ - actu_collide = cont.getSensor('collision_sens') - for ob in actu_collide.getHitObjectList(): + actu_collide = cont.sensors['collision_sens'] + for ob in actu_collide.objectHitList: # Check to see the object has this property if hasattr(ob, 'life'): own.life += ob.life diff --git a/release/scripts/scripttemplate_gamelogic_basic.py b/release/scripts/scripttemplate_gamelogic_basic.py index 1584659d317..fd404d5c8a4 100644 --- a/release/scripts/scripttemplate_gamelogic_basic.py +++ b/release/scripts/scripttemplate_gamelogic_basic.py @@ -1,7 +1,7 @@ #!BPY """ Name: 'GameLogic Template' -Blender: 245 +Blender: 249 Group: 'ScriptTemplate' Tooltip: 'Basic template for new game logic scripts' """ @@ -14,15 +14,15 @@ script_data = \ def main(): cont = GameLogic.getCurrentController() - own = cont.getOwner() + own = cont.owner - sens = cont.getSensor('mySensor') - actu = cont.getActuator('myActuator') + sens = cont.sensors['mySensor'] + actu = cont.actuators['myActuator'] - if sens.isPositive(): - GameLogic.addActiveActuator(actu, True) + if sens.positive: + cont.activate(actu) else: - GameLogic.addActiveActuator(actu, False) + cont.deactivate(actu) main() ''' From 1a8bbba7bd79d187969143ee4e199b1b08783938 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 00:56:48 +0000 Subject: [PATCH 200/444] new script to copy the active object to all other selected objects transformation. When turning many assets into DupliGroups there was no way to do this other then manually copying the loc/size/rot for each object manually. --- release/scripts/object_active_to_other.py | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 release/scripts/object_active_to_other.py diff --git a/release/scripts/object_active_to_other.py b/release/scripts/object_active_to_other.py new file mode 100644 index 00000000000..131d1f63d74 --- /dev/null +++ b/release/scripts/object_active_to_other.py @@ -0,0 +1,58 @@ +#!BPY +""" +Name: 'Copy Active to Selected' +Blender: 249 +Group: 'Object' +Tooltip: 'For every selected object, copy the active to their loc/size/rot' +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Campbell Barton +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + +from Blender import Window, sys, Draw +import bpy + +def my_object_util(sce): + ob_act = sce.objects.active + + if not ob_act: + Draw.PupMenu('Error%t|No active object selected') + return + + mats = [ob.matrixWorld for ob in sce.objects.context if ob != ob_act] + + for m in mats: + ob_copy = ob_act.copy() + sce.objects.link(ob_copy) + ob_copy.setMatrix(m) + ob_copy.Layers = ob.Layers + + +def main(): + sce = bpy.data.scenes.active + + Window.WaitCursor(1) + my_object_util(sce) + Window.WaitCursor(0) + +if __name__ == '__main__': + main() From dcee43b449737c036dcf19d005df08c8687e5f93 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 05:10:09 +0000 Subject: [PATCH 201/444] bolt wizard from Aaron Keith (Spudmn), edits from Brendon and myself. Minor changes are... - default size is smaller then it was but still too big IMHO, presets are huge. - deselect all objects and make the new bolt active - place the new bolt at the 3D cursor location --- release/scripts/wizard_bolt_factory.py | 3041 ++++++++++++++++++++++++ 1 file changed, 3041 insertions(+) create mode 100644 release/scripts/wizard_bolt_factory.py diff --git a/release/scripts/wizard_bolt_factory.py b/release/scripts/wizard_bolt_factory.py new file mode 100644 index 00000000000..572cd763c18 --- /dev/null +++ b/release/scripts/wizard_bolt_factory.py @@ -0,0 +1,3041 @@ +#!BPY + +""" +Name: 'Bolt Factory' +Blender: 249 +Group: 'Wizards' +Tooltip: 'Create models of various types to screw fasteners.' +""" + +__author__ = " Aaron Keith (Spudmn) " +__version__ = "1.50 " +__url__ = ["blender", "http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Misc/Bolt_Factory"] +__email__= [""] +__bpydoc__ = """\ +Bolt_Factory.py + +Bolt Factory is a Python script for Blender 3D. + +The script allows the user to create models of various types to screw fasteners. + +This version is very much a work in progress. + +This is my first attempt to program in Python. This version is unpolished and +doesn't do much error checking. Therefore if the user sets strange +variable the model created will be as equally strange. + +For best results set the material to smooth and apply a Edge Split modifier +with default settings. + +To Do: +Better error checking. +Nuts to go with the bolts. +Pre-sets for common bolts. +Improved GUI. +More Head and Bit types. +Better documentation. +Fix error with mesh when using crest and root percent other than 10. + + +""" + +# -------------------------------------------------------------------------- +# Bolt_Factory.py +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Copyright (C) 2008: Aaron Keith +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + + + +import Blender +from Blender import Draw, BGL,Mesh +from Blender import * +from math import * +from Blender import Mathutils +from Blender.Mathutils import * + + +Global_NutRad = 0.0 +MAX_INPUT_NUMBER = 50 + +No_Event,On_Preset_Click,On_Apply_Click,On_Create_Click,On_Hex_Click, On_Cap_Click,On_Dome_Click,On_Pan_Click,On_Bit_None_Click,On_Bit_Allen_Click,On_Bit_Philips_Click,On_Exit_Click,On_Model_Bolt_Click,On_Model_Nut_Click,On_Hex_Nut_Click,On_Lock_Nut_Click,On_Test_Click = range(17) # this is like a ENUM + + +Head_Type={'HEX' : [Draw.Create(1),On_Hex_Click], + 'CAP' : [Draw.Create(0),On_Cap_Click], + 'DOME': [Draw.Create(0),On_Dome_Click], + 'PAN' : [Draw.Create(0),On_Pan_Click]} + + +Bit_Type={'NONE' : [Draw.Create(1),On_Bit_None_Click], + 'ALLEN' : [Draw.Create(0),On_Bit_Allen_Click], + 'PHILLIPS': [Draw.Create(0),On_Bit_Philips_Click]} + +Model_Type={'BOLT' : [Draw.Create(1),On_Model_Bolt_Click], + 'NUT' : [Draw.Create(0),On_Model_Nut_Click]} + +Nut_Type={'HEX' : [Draw.Create(1),On_Hex_Nut_Click], + 'LOCK' : [Draw.Create(0),On_Lock_Nut_Click]} + + + +Phillips_Bit_Depth = Draw.Create(1.0) +Philips_Bit_Dia = Draw.Create(1.75) + +Allen_Bit_Depth = Draw.Create(1.0) +Allen_Bit_Flat_Distance = Draw.Create(1.25) + +Hex_Head_Height = Draw.Create(1.0) +Hex_Head_Flat_Distance = Draw.Create(2.25) + +Cap_Head_Dia = Draw.Create(2.25) +Cap_Head_Height = Draw.Create(1.5) +Cap_Head_Inside_Rad = 0.0 + +Dome_Head_Dia = Draw.Create(3.75) + +Pan_Head_Dia = Draw.Create(5.375) + +Shank_Dia = Draw.Create(1.5) +Shank_Length = Draw.Create(0.125) + +Thread_Length = Draw.Create(2.5) +Major_Dia = Draw.Create(1.5) +Minor_Dia = Draw.Create(1.25) +Pitch = Draw.Create(0.125) +Crest_Percent = Draw.Create(1.25) +Root_Percent = Draw.Create(1.25) + +Hex_Nut_Height = Draw.Create(1.0) +Hex_Nut_Flat_Distance = Draw.Create(2.25) + +Preset_Menu = Draw.Create(0.25) +Preset_Length = Draw.Create(1.5) + + +########################################################################################## +########################################################################################## +## Miscellaneous Utilities +########################################################################################## +########################################################################################## + + +def Rot_Mesh(verts,matrix): + ret = [] + for v in verts: + vec = Vector(v) * matrix + ret.append([vec.x,vec.y,vec.z]) + return ret + +def Copy_Faces(faces,offset): + ret = [] + for f in faces: + fsub = [] + for i in range(len(f)): + fsub.append(f[i]+ offset) + ret.append(fsub) + return ret + +def Move_Verts_Up_Z(VERTS,DISTANCE): + ret = [] + for v in VERTS: + ret.append([v[0],v[1],v[2]+DISTANCE]) + return ret + + +def SpinDup(VERTS,FACES,DEGREE,DIVISIONS,AXIS): + verts=[] + faces=[] + + if DIVISIONS == 0: + DIVISIONS = 1 + + step = DEGREE/DIVISIONS # set step so pieces * step = degrees in arc + + for i in range(int(DIVISIONS)): + rotmat = Mathutils.RotationMatrix(step*i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis. + Rot = Rot_Mesh(VERTS,rotmat) + faces.extend(Copy_Faces(FACES,len(verts))) + #print faces + verts.extend(Rot) + return verts,faces + + +def Mirror_Verts(VERTS,AXIS): + ret = [] + for v in VERTS: + ret.append([0-v[0],v[1],v[2]]) + return ret + + +def Mirror_Verts_Faces(VERTS,FACES,AXIS,FLIP_POINT =0): + ret_vert = [] + ret_face = [] + offset = len(VERTS) + if AXIS == 'y': + for v in VERTS: + Delta = v[0] - FLIP_POINT + ret_vert.append([FLIP_POINT-Delta,v[1],v[2]]) + if AXIS == 'x': + for v in VERTS: + Delta = v[1] - FLIP_POINT + ret_vert.append([v[0],FLIP_POINT-Delta,v[2]]) + if AXIS == 'z': + for v in VERTS: + Delta = v[2] - FLIP_POINT + ret_vert.append([v[0],v[1],FLIP_POINT-Delta]) + + for f in FACES: + fsub = [] + for i in range(len(f)): + fsub.append(f[i]+ offset) + fsub.reverse() # filp the order to make norm point out + ret_face.append(fsub) + + return ret_vert,ret_face + +def Lath(tool_V1,tool_V2,verts,faces): + + #verts = [] + #faces = []f + + #verts.append([7.0,6.0,0.0]) + #verts.append([7.0+10,6.0-10,0.0]) + #faces.append([3,4]) + + vec1 = Vector(verts[-1]) + vec2 = Vector(verts[-2]) + + VecOut1,VecR2 = LineIntersect(vec1, vec2,Vector(tool_V1), Vector(tool_V2)) + + vec1 = Vector(verts[-2]) + vec2 = Vector(verts[-3]) + + VecOut2,VecR2 = LineIntersect(vec1, vec2,Vector(tool_V1), Vector(tool_V2)) + + if VecOut1 != None: + if VecOut1 == VecOut2: + #print "got it" + faces.append([len(verts),len(verts)+1]) + verts.append([VecOut1.x,VecOut1.y,VecOut1.z]) + verts.append([VecOut2.x,VecOut2.y,VecOut2.z]) + #print verts[-1] + #print verts[-2] + + return verts,faces + + +def Build_Face_List_Quads(OFFSET,COLUM,ROW,FLIP = 0): + Ret =[] + RowStart = 0; + for j in range(ROW): + for i in range(COLUM): + Res1 = RowStart + i; + Res2 = RowStart + i + (COLUM +1) + Res3 = RowStart + i + (COLUM +1) +1 + Res4 = RowStart+i+1 + if FLIP: + Ret.append([OFFSET+Res1,OFFSET+Res2,OFFSET+Res3,OFFSET+Res4]) + else: + Ret.append([OFFSET+Res4,OFFSET+Res3,OFFSET+Res2,OFFSET+Res1]) + RowStart += COLUM+1 + return Ret + + + +def Fill_Ring_Face(OFFSET,NUM,FACE_DOWN = 0): + Ret =[] + Face = [1,2,0] + TempFace = [0,0,0] + A = 0 + B = 1 + C = 2 + if NUM < 3: + return None + for i in range(NUM-2): + if (i%2): + TempFace[0] = Face[C]; + TempFace[1] = Face[C] + 1; + TempFace[2] = Face[B]; + if FACE_DOWN: + Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]]) + else: + Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]]) + else: + TempFace[0] =Face[C]; + if Face[C] == 0: + TempFace[1] = NUM-1; + else: + TempFace[1] = Face[C] - 1; + TempFace[2] = Face[B]; + if FACE_DOWN: + Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]]) + else: + Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]]) + + Face[0] = TempFace[0] + Face[1] = TempFace[1] + Face[2] = TempFace[2] + return Ret + + +def Flat_To_Radius(FLAT): + h = (float(FLAT)/2)/cos(radians(30)) + #print h + return h + + + +########################################################################################## +########################################################################################## +## Error Checking +########################################################################################## +########################################################################################## + + +def Error_Check(): + + #global Phillips_Bit_Depth + #global Philips_Bit_Dia + + #global Allen_Bit_Depth + #global Allen_Bit_Flat_Distance + + #global Hex_Head_Height + #global Hex_Head_Flat_Distance + + #global Cap_Head_Dia + #global Cap_Head_Height + + + #global Dome_Head_Dia + + #global Pan_Head_Dia + + #global Shank_Dia + #global Shank_Length + + global Thread_Length + global Major_Dia + global Minor_Dia + global Pitch + #global Crest_Percent + #global Root_Percent + + Error_Result = 0 + + if Minor_Dia.val >= Major_Dia.val: + error_txt = "Error%t|Major Dia must be larger than Minor Dia" + Blender.Draw.PupMenu(error_txt) + print error_txt + Error_Result = TRUE + + elif (Pitch.val*7.0) > Thread_Length.val: + error_txt = "Error%t|Thread length must be at least 7 times the pitch" + Blender.Draw.PupMenu(error_txt) + print error_txt + Error_Result = TRUE + return Error_Result + + + + + + + + + + +########################################################################################## +########################################################################################## +## Create Allen Bit +########################################################################################## +########################################################################################## + + + +def Allen_Fill(OFFSET,FLIP= 0): + faces = [] + Lookup = [[19,1,0], + [19,2,1], + [19,3,2], + [19,20,3], + [20,4,3], + [20,5,4], + [20,6,5], + [20,7,6], + [20,8,7], + [20,9,8], + + [20,21,9], + + [21,10,9], + [21,11,10], + [21,12,11], + [21,13,12], + [21,14,13], + [21,15,14], + + [21,22,15], + [22,16,15], + [22,17,16], + [22,18,17] + ] + for i in Lookup: + if FLIP: + faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]]) + else: + faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2]]) + + return faces + + + +def Create_Allen_Bit(FLAT_DISTANCE,HEIGHT): + Div = 36 + verts = [] + faces = [] + + Flat_Radius = (float(FLAT_DISTANCE)/2)/cos(radians(30)) + OUTTER_RADIUS = Flat_Radius * 1.05 + Outter_Radius_Height = Flat_Radius * (0.1/5.77) + FaceStart_Outside = len(verts) + Deg_Step = 360.0 /float(Div) + + for i in range((Div/2)+1): # only do half and mirror later + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,0]) + + FaceStart_Inside = len(verts) + + Deg_Step = 360.0 /float(6) + for i in range((6/2)+1): + x = sin(radians(i*Deg_Step))* Flat_Radius + y = cos(radians(i*Deg_Step))* Flat_Radius + verts.append([x,y,0-Outter_Radius_Height]) + + faces.extend(Allen_Fill(FaceStart_Outside,0)) + + + FaceStart_Bottom = len(verts) + + Deg_Step = 360.0 /float(6) + for i in range((6/2)+1): + x = sin(radians(i*Deg_Step))* Flat_Radius + y = cos(radians(i*Deg_Step))* Flat_Radius + verts.append([x,y,0-HEIGHT]) + + faces.extend(Build_Face_List_Quads(FaceStart_Inside,3,1,TRUE)) + faces.extend(Fill_Ring_Face(FaceStart_Bottom,4)) + + + M_Verts,M_Faces = Mirror_Verts_Faces(verts,faces,'y') + verts.extend(M_Verts) + faces.extend(M_Faces) + + return verts,faces,OUTTER_RADIUS * 2 + + +########################################################################################## +########################################################################################## +## Create Phillips Bit +########################################################################################## +########################################################################################## + + +def Phillips_Fill(OFFSET,FLIP= 0): + faces = [] + Lookup = [[0,1,10], + [1,11,10], + [1,2,11], + [2,12,11], + + [2,3,12], + [3,4,12], + [4,5,12], + [5,6,12], + [6,7,12], + + [7,13,12], + [7,8,13], + [8,14,13], + [8,9,14], + + + [10,11,16,15], + [11,12,16], + [12,13,16], + [13,14,17,16], + [15,16,17,18] + + + ] + for i in Lookup: + if FLIP: + if len(i) == 3: + faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]]) + else: + faces.append([OFFSET+i[3],OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]]) + else: + if len(i) == 3: + faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2]]) + else: + faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2],OFFSET+i[3]]) + return faces + + + +def Create_Phillips_Bit(FLAT_DIA,FLAT_WIDTH,HEIGHT): + Div = 36 + verts = [] + faces = [] + + FLAT_RADIUS = FLAT_DIA * 0.5 + OUTTER_RADIUS = FLAT_RADIUS * 1.05 + + Flat_Half = float(FLAT_WIDTH)/2.0 + + FaceStart_Outside = len(verts) + Deg_Step = 360.0 /float(Div) + for i in range((Div/4)+1): # only do half and mirror later + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,0]) + + + FaceStart_Inside = len(verts) + verts.append([0,FLAT_RADIUS,0]) #10 + verts.append([Flat_Half,FLAT_RADIUS,0]) #11 + verts.append([Flat_Half,Flat_Half,0]) #12 + verts.append([FLAT_RADIUS,Flat_Half,0]) #13 + verts.append([FLAT_RADIUS,0,0]) #14 + + + verts.append([0,Flat_Half,0-HEIGHT]) #15 + verts.append([Flat_Half,Flat_Half,0-HEIGHT]) #16 + verts.append([Flat_Half,0,0-HEIGHT]) #17 + + verts.append([0,0,0-HEIGHT]) #18 + + faces.extend(Phillips_Fill(FaceStart_Outside,TRUE)) + + Spin_Verts,Spin_Face = SpinDup(verts,faces,360,4,'z') + + return Spin_Verts,Spin_Face,OUTTER_RADIUS * 2 + + +########################################################################################## +########################################################################################## +## Create Head Types +########################################################################################## +########################################################################################## + + + +def Create_Pan_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): + + DIV = 36 + HOLE_RADIUS = HOLE_DIA * 0.5 + HEAD_RADIUS = HEAD_DIA * 0.5 + SHANK_RADIUS = SHANK_DIA * 0.5 + + print "hole dia", HOLE_DIA + verts = [] + faces = [] + Row = 0 + BEVEL = HEIGHT * 0.01 + #Dome_Rad = HEAD_RADIUS * (1.0/1.75) + + + Dome_Rad = HEAD_RADIUS * 1.12 + RAD_Offset = HEAD_RADIUS * 0.96 + OtherRad = HEAD_RADIUS * 0.16 + OtherRad_X_Offset = HEAD_RADIUS * 0.84 + OtherRad_Z_Offset = HEAD_RADIUS * 0.504 + XRad = HEAD_RADIUS * 1.976 + ZRad = HEAD_RADIUS * 1.768 + EndRad = HEAD_RADIUS * 0.284 + EndZOffset = HEAD_RADIUS * 0.432 + HEIGHT = HEAD_RADIUS * 0.59 + +# Dome_Rad = 5.6 +# RAD_Offset = 4.9 +# OtherRad = 0.8 +# OtherRad_X_Offset = 4.2 +# OtherRad_Z_Offset = 2.52 +# XRad = 9.88 +# ZRad = 8.84 +# EndRad = 1.42 +# EndZOffset = 2.16 +# HEIGHT = 2.95 + + FaceStart = FACE_OFFSET + + z = cos(radians(10))*ZRad + verts.append([HOLE_RADIUS,0.0,(0.0-ZRad)+z]) + Start_Height = 0 - ((0.0-ZRad)+z) + Row += 1 + + #for i in range(0,30,10): was 0 to 30 more work needed to make this look good. + for i in range(10,30,10): + x = sin(radians(i))*XRad + z = cos(radians(i))*ZRad + print x + verts.append([x,0.0,(0.0-ZRad)+z]) + Row += 1 + + for i in range(20,140,10): + x = sin(radians(i))*EndRad + z = cos(radians(i))*EndRad + if ((0.0 - EndZOffset)+z) < (0.0-HEIGHT): + verts.append([(HEAD_RADIUS -EndRad)+x,0.0,0.0 - HEIGHT]) + else: + verts.append([(HEAD_RADIUS -EndRad)+x,0.0,(0.0 - EndZOffset)+z]) + Row += 1 + + + verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)]) + Row += 1 + + verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)-Start_Height]) + Row += 1 + + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + Global_Head_Height = HEIGHT ; + + + return Move_Verts_Up_Z(sVerts,Start_Height),faces,HEIGHT + + + +def Create_Dome_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): + DIV = 36 + HOLE_RADIUS = HOLE_DIA * 0.5 + HEAD_RADIUS = HEAD_DIA * 0.5 + SHANK_RADIUS = SHANK_DIA * 0.5 + + verts = [] + faces = [] + Row = 0 + BEVEL = HEIGHT * 0.01 + #Dome_Rad = HEAD_RADIUS * (1.0/1.75) + + Dome_Rad = HEAD_RADIUS * 1.12 + #Head_Height = HEAD_RADIUS * 0.78 + RAD_Offset = HEAD_RADIUS * 0.98 + Dome_Height = HEAD_RADIUS * 0.64 + OtherRad = HEAD_RADIUS * 0.16 + OtherRad_X_Offset = HEAD_RADIUS * 0.84 + OtherRad_Z_Offset = HEAD_RADIUS * 0.504 + + +# Dome_Rad = 5.6 +# RAD_Offset = 4.9 +# Dome_Height = 3.2 +# OtherRad = 0.8 +# OtherRad_X_Offset = 4.2 +# OtherRad_Z_Offset = 2.52 +# + + + #averts, afaces = Create_Allen_Bit(8.5,5,5) + #verts.extend(averts) + #faces.extend(afaces) + + #FaceStart = len(verts) + FaceStart = FACE_OFFSET + + verts.append([HOLE_RADIUS,0.0,0.0]) + Row += 1 + + + for i in range(0,60,10): + x = sin(radians(i))*Dome_Rad + z = cos(radians(i))*Dome_Rad + #verts.append([x,0.0,(0.0-RAD_Offset)+z]) + if ((0.0-RAD_Offset)+z) <= 0: + verts.append([x,0.0,(0.0-RAD_Offset)+z]) + Row += 1 + + + for i in range(60,160,10): + x = sin(radians(i))*OtherRad + z = cos(radians(i))*OtherRad + z = (0.0-OtherRad_Z_Offset)+z + if z < (0.0-Dome_Height): + z = (0.0-Dome_Height) + verts.append([OtherRad_X_Offset+x,0.0,z]) + Row += 1 + + verts.append([SHANK_RADIUS,0.0,(0.0-Dome_Height)]) + Row += 1 + + + + #for i in range(0,18,1): + # x = i + # verts.append([x,0.0,(0.0-Dome_Height)]) + # Row += 1 + + + #verts.append([SHANK_RADIUS,0.0,(0.0-Dome_Height)-Dome_Height]) + #Row += 1 + + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + + #Global_Head_Height = Dome_Height + return sVerts,faces,Dome_Height + #return verts,faces + + + +def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2): + DIV = 36 + + HOLE_RADIUS = HOLE_DIA * 0.5 + HEAD_RADIUS = HEAD_DIA * 0.5 + SHANK_RADIUS = SHANK_DIA * 0.5 + + + print "Head dia" , HEAD_DIA + print "Rad1" , RAD1 + print "Rad2" , RAD2 + + verts = [] + faces = [] + Row = 0 + BEVEL = HEIGHT * 0.01 + + + FaceStart = len(verts) + + verts.append([HOLE_RADIUS,0.0,0.0]) + Row += 1 + + #verts.append([HEAD_RADIUS-RAD1,0.0,0.0]) + #Row += 1 Done in for loop below + + #rad + + for i in range(0,100,10): + #print i + x = sin(radians(i))*RAD1 + z = cos(radians(i))*RAD1 + verts.append([(HEAD_RADIUS-RAD1)+x,0.0,(0.0-RAD1)+z]) + Row += 1 + + + #verts.append([HEAD_RADIUS,0.0,0.0-RAD1]) + #Row += 1 Done in for loop above + + verts.append([HEAD_RADIUS,0.0,0.0-HEIGHT+BEVEL]) + Row += 1 + + verts.append([HEAD_RADIUS-BEVEL,0.0,0.0-HEIGHT]) + Row += 1 + + #rad2 + + +# verts.append([SHANK_RADIUS+RAD2,0.0,0.0-HEIGHT]) +# Row += 1 Done by rad2 below + + for i in range(0,100,10): + x = sin(radians(i))*RAD2 + z = cos(radians(i))*RAD2 + verts.append([(SHANK_RADIUS+RAD2)-x,0.0,(0.0-HEIGHT-RAD2)+z]) + Row += 1 + +# verts.append([SHANK_RADIUS,0.0,0.0-HEIGHT-RAD2]) +# Row += 1 done by rad2 above + + +# verts.append([SHANK_RADIUS,0.0,0.0-HEIGHT-RAD2-RAD2]) +# Row += 1 + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + #Global_Head_Height = HEIGHT+RAD2 + + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + return sVerts,faces,HEIGHT+RAD2 + #return verts,faces + + + +def Create_Hex_Head(FLAT,HOLE_DIA,SHANK_DIA,HEIGHT): + + verts = [] + faces = [] + HOLE_RADIUS = HOLE_DIA * 0.5 + Half_Flat = FLAT/2 + TopBevelRadius = Half_Flat - (Half_Flat* (0.05/8)) + Undercut_Height = (Half_Flat* (0.05/8)) + Shank_Bevel = (Half_Flat* (0.05/8)) + Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel + #Undercut_Height = 5 + SHANK_RADIUS = SHANK_DIA/2 + Row = 0; + + verts.append([0.0,0.0,0.0]) + + + FaceStart = len(verts) + #inner hole + + x = sin(radians(0))*HOLE_RADIUS + y = cos(radians(0))*HOLE_RADIUS + verts.append([x,y,0.0]) + + + x = sin(radians(60/6))*HOLE_RADIUS + y = cos(radians(60/6))*HOLE_RADIUS + verts.append([x,y,0.0]) + + + x = sin(radians(60/3))*HOLE_RADIUS + y = cos(radians(60/3))*HOLE_RADIUS + verts.append([x,y,0.0]) + + + x = sin(radians(60/2))*HOLE_RADIUS + y = cos(radians(60/2))*HOLE_RADIUS + verts.append([x,y,0.0]) + Row += 1 + + #bevel + + x = sin(radians(0))*TopBevelRadius + y = cos(radians(0))*TopBevelRadius + vec1 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + + + x = sin(radians(60/6))*TopBevelRadius + y = cos(radians(60/6))*TopBevelRadius + vec2 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + + + x = sin(radians(60/3))*TopBevelRadius + y = cos(radians(60/3))*TopBevelRadius + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + + + x = sin(radians(60/2))*TopBevelRadius + y = cos(radians(60/2))*TopBevelRadius + vec4 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + Row += 1 + + #Flats + + x = tan(radians(0))*Half_Flat + dvec = vec1 - Mathutils.Vector([x,Half_Flat,0.0]) + #print dvec.length + verts.append([x,Half_Flat,-dvec.length]) + + + x = tan(radians(60/6))*Half_Flat + dvec = vec2 - Mathutils.Vector([x,Half_Flat,0.0]) + verts.append([x,Half_Flat,-dvec.length]) + + + x = tan(radians(60/3))*Half_Flat + dvec = vec3 - Mathutils.Vector([x,Half_Flat,0.0]) + Lowest_Point = -dvec.length + verts.append([x,Half_Flat,-dvec.length]) + + + x = tan(radians(60/2))*Half_Flat + dvec = vec4 - Mathutils.Vector([x,Half_Flat,0.0]) + Lowest_Point = -dvec.length + verts.append([x,Half_Flat,-dvec.length]) + Row += 1 + + #down Bits Tri + x = tan(radians(0))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + + x = tan(radians(60/6))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + + x = tan(radians(60/3))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + + x = tan(radians(60/2))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + Row += 1 + + #down Bits + + x = tan(radians(0))*Half_Flat + verts.append([x,Half_Flat,-Flat_Height]) + + x = tan(radians(60/6))*Half_Flat + verts.append([x,Half_Flat,-Flat_Height]) + + x = tan(radians(60/3))*Half_Flat + verts.append([x,Half_Flat,-Flat_Height]) + + x = tan(radians(60/2))*Half_Flat + verts.append([x,Half_Flat,-Flat_Height]) + Row += 1 + + + #under cut + + x = sin(radians(0))*Half_Flat + y = cos(radians(0))*Half_Flat + vec1 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height]) + + x = sin(radians(60/6))*Half_Flat + y = cos(radians(60/6))*Half_Flat + vec2 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height]) + + x = sin(radians(60/3))*Half_Flat + y = cos(radians(60/3))*Half_Flat + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height]) + + x = sin(radians(60/2))*Half_Flat + y = cos(radians(60/2))*Half_Flat + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height]) + Row += 1 + + #under cut down bit + x = sin(radians(0))*Half_Flat + y = cos(radians(0))*Half_Flat + vec1 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + + x = sin(radians(60/6))*Half_Flat + y = cos(radians(60/6))*Half_Flat + vec2 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + + x = sin(radians(60/3))*Half_Flat + y = cos(radians(60/3))*Half_Flat + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + + x = sin(radians(60/2))*Half_Flat + y = cos(radians(60/2))*Half_Flat + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + Row += 1 + + #under cut to Shank BEVEAL + x = sin(radians(0))*(SHANK_RADIUS+Shank_Bevel) + y = cos(radians(0))*(SHANK_RADIUS+Shank_Bevel) + vec1 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + + x = sin(radians(60/6))*(SHANK_RADIUS+Shank_Bevel) + y = cos(radians(60/6))*(SHANK_RADIUS+Shank_Bevel) + vec2 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + + x = sin(radians(60/3))*(SHANK_RADIUS+Shank_Bevel) + y = cos(radians(60/3))*(SHANK_RADIUS+Shank_Bevel) + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + + x = sin(radians(60/2))*(SHANK_RADIUS+Shank_Bevel) + y = cos(radians(60/2))*(SHANK_RADIUS+Shank_Bevel) + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height]) + Row += 1 + + #under cut to Shank BEVEAL + x = sin(radians(0))*SHANK_RADIUS + y = cos(radians(0))*SHANK_RADIUS + vec1 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) + + x = sin(radians(60/6))*SHANK_RADIUS + y = cos(radians(60/6))*SHANK_RADIUS + vec2 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) + + x = sin(radians(60/3))*SHANK_RADIUS + y = cos(radians(60/3))*SHANK_RADIUS + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) + + x = sin(radians(60/2))*SHANK_RADIUS + y = cos(radians(60/2))*SHANK_RADIUS + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel]) + Row += 1 + + + #Shank +# x = sin(radians(0))*SHANK_RADIUS +# y = cos(radians(0))*SHANK_RADIUS +# vec1 = Mathutils.Vector([x,y,0.0]) +# verts.append([x,y,-HEIGHT-0.5]) +# +# x = sin(radians(60/6))*SHANK_RADIUS +# y = cos(radians(60/6))*SHANK_RADIUS +# vec2 = Mathutils.Vector([x,y,0.0]) +# verts.append([x,y,-HEIGHT-0.5]) +# +# x = sin(radians(60/3))*SHANK_RADIUS +# y = cos(radians(60/3))*SHANK_RADIUS +# vec3 = Mathutils.Vector([x,y,0.0]) +# verts.append([x,y,-HEIGHT-0.5]) +# +# x = sin(radians(60/2))*SHANK_RADIUS +# y = cos(radians(60/2))*SHANK_RADIUS +# vec3 = Mathutils.Vector([x,y,0.0]) +# verts.append([x,y,-HEIGHT-0.5]) + + #Global_Head_Height = 0 - (-HEIGHT-0.1) + faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1)) + + + Mirror_Verts,Mirror_Faces = Mirror_Verts_Faces(verts,faces,'y') + verts.extend(Mirror_Verts) + faces.extend(Mirror_Faces) + + Spin_Verts,Spin_Faces = SpinDup(verts,faces,360,6,'z') + + return Spin_Verts,Spin_Faces,0 - (-HEIGHT) + + +########################################################################################## +########################################################################################## +## Create Bolt +########################################################################################## +########################################################################################## + + + +def MakeBolt(): + global Phillips_Bit_Depth + global Philips_Bit_Dia + + global Allen_Bit_Depth + global Allen_Bit_Flat_Distance + + global Hex_Head_Height + global Hex_Head_Flat_Distance + + global Cap_Head_Dia + global Cap_Head_Height + + + global Dome_Head_Dia + + global Pan_Head_Dia + + global Shank_Dia + global Shank_Length + + global Thread_Length + global Major_Dia + global Minor_Dia + global Pitch + global Crest_Percent + global Root_Percent + + verts = [] + faces = [] + Bit_Verts = [] + Bit_Faces = [] + Bit_Dia = 0.001 + Head_Verts = [] + Head_Faces= [] + Head_Height = 0.0 + + + + + Head_Height = Hex_Head_Height.val # will be changed by the Head Functions + + #bit Mesh + if Bit_Type['ALLEN'][0].val: + #Create_Allen_Bit(FLAT_DISTANCE,OUTTER_RADIUS,HEIGHT): + Bit_Verts,Bit_Faces,Bit_Dia = Create_Allen_Bit(Allen_Bit_Flat_Distance.val,Allen_Bit_Depth.val) + + if Bit_Type['PHILLIPS'][0].val: + #Create_Phillips_Bit(FLAT_RADIUS, FLAT_WIDTH, HEIGHT) + #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(Philips_Bit_Dia.val,3,Phillips_Bit_Depth.val) + #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(3.00,0.4856,1.98) + #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(4,1,2) + #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(3.8,0.9,2.0) + #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(3.0,0.9,2.0) + Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(Philips_Bit_Dia.val,Philips_Bit_Dia.val*(0.5/1.82),Phillips_Bit_Depth.val) + + + #Head Mesh + if Head_Type['HEX'][0].val: + #add_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT) + Head_Verts,Head_Faces,Head_Height = Create_Hex_Head(Hex_Head_Flat_Distance.val,Bit_Dia,Shank_Dia.val,Hex_Head_Height.val) + + elif Head_Type['CAP'][0].val: + #add_Cap_Head(HOLE_RADIUS,HEAD_RADIUS,SHANK_RADIUS,HEIGHT,RAD1,RAD2) + #add_Cap_Head(2,5,3,6,1,1) + Head_Verts,Head_Faces,Head_Height = Create_Cap_Head(Bit_Dia,Cap_Head_Dia.val,Shank_Dia.val,Cap_Head_Height.val,Cap_Head_Dia.val*(1.0/19.0),Cap_Head_Dia.val*(1.0/19.0)) + + elif Head_Type['DOME'][0].val: + #add_Dome_Head(HOLE_RADIUS,HEAD_RADIUS,SHANK_RADIUS,HEIGHT,RAD1,RAD2,FACE_OFFSET): + Head_Verts,Head_Faces,Head_Height = Create_Dome_Head(Bit_Dia,Dome_Head_Dia.val,Shank_Dia.val,Hex_Head_Height.val,1,1,0) + + elif Head_Type['PAN'][0].val: + #add_Pan_Head(HOLE_RADIUS,HEAD_RADIUS,SHANK_RADIUS,HEIGHT,RAD1,RAD2,FACE_OFFSET): + #verts, faces = add_Pan_Head(2.6,5,2,6,3.2,1,0) + #Head_Verts,Head_Faces = add_Pan_Head(2.6*2,5*2,2*2,6,3.2,1,0) + Head_Verts,Head_Faces,Head_Height = Create_Pan_Head(Bit_Dia,Pan_Head_Dia.val,Shank_Dia.val,Hex_Head_Height.val,1,1,0) + + print 'got here' + + Face_Start = len(verts) + verts.extend(Move_Verts_Up_Z(Bit_Verts,Head_Height)) + faces.extend(Copy_Faces(Bit_Faces,Face_Start)) + + Face_Start = len(verts) + verts.extend(Move_Verts_Up_Z(Head_Verts,Head_Height)) + faces.extend(Copy_Faces(Head_Faces,Face_Start)) + + Face_Start = len(verts) + Thread_Verts,Thread_Faces,Thread_Height = Create_External_Thread(Shank_Dia.val,Shank_Length.val,Minor_Dia.val,Major_Dia.val,Pitch.val,Thread_Length.val,Crest_Percent.val,Root_Percent.val) + + verts.extend(Move_Verts_Up_Z(Thread_Verts,00)) + faces.extend(Copy_Faces(Thread_Faces,Face_Start)) + + return Move_Verts_Up_Z(verts,Thread_Height),faces + #return Move_Verts_Up_Z(verts,0),faces + + + + + +def Create_Bolt(): + verts = [] + faces = [] + + + if Error_Check() : + return + + + me = Mesh.New('Bolt') # create a new mesh + + verts, faces = MakeBolt() + + me.verts.extend(verts) # add vertices to mesh + me.faces.extend(faces) # add faces to the mesh (also adds edges) + + + + is_editmode = Window.EditMode() # Store edit mode state + if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. + + + scn = Scene.GetCurrent() # link object to current scene + scn.objects.selected = [] + + ob = scn.objects.active = scn.objects.new(me, 'Bolt') + ob.loc = Window.GetCursorPos() + me.remDoubles(0.010) + + if is_editmode: Window.EditMode(1) + + Blender.Redraw() + + + + +########################################################################################## +########################################################################################## +## Create Internal Thread +########################################################################################## +########################################################################################## + + +def Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): + + + Ret_Row = 0; + + Height_Offset = Height_Offset + PITCH #Move the offset up so that the verts start at + #at the corect place (Height_Start) + + + Half_Pitch = float(PITCH)/2 + Height_Start = Height_Offset - PITCH + Height_Step = float(PITCH)/float(DIV) + Deg_Step = 360.0 /float(DIV) + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + + +#theard start + #print Height_Start + #print "Height_Offset" , Height_Offset + + Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) + for j in range(1): + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z]) + Height_Offset -= Crest_Height + Ret_Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z ]) + Height_Offset -= Crest_to_Root_Height + Ret_Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + if j == 0: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + verts.append([x,y,z ]) + Height_Offset -= Root_Height + Ret_Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + + if j == 0: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + verts.append([x,y,z ]) + Height_Offset -= Root_to_Crest_Height + Ret_Row += 1 + + return Ret_Row,Height_Offset + + +def Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): + + + Ret_Row = 0; + + Half_Pitch = float(PITCH)/2 + #Height_End = Height_Offset - PITCH - PITCH - PITCH- PITCH - PITCH- PITCH + Height_End = Height_Offset - PITCH + #Height_End = -2.1 + Height_Step = float(PITCH)/float(DIV) + Deg_Step = 360.0 /float(DIV) + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + + +#theard start + + Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) + + Num = 0 + + for j in range(2): + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z < Height_End: + z = Height_End + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z]) + Height_Offset -= Crest_Height + Ret_Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z < Height_End: + z = Height_End + + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z ]) + Height_Offset -= Crest_to_Root_Height + Ret_Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z < Height_End: + z = Height_End + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + if j == Num: + x = sin(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank)) + y = cos(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank)) + if j > Num: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS ) + + verts.append([x,y,z ]) + Height_Offset -= Root_Height + Ret_Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z < Height_End: + z = Height_End + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + + if j == Num: + x = sin(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank)) + y = cos(radians(i*Deg_Step))*(INNER_RADIUS + (i*Rank)) + if j > Num: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS ) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS ) + + verts.append([x,y,z ]) + Height_Offset -= Root_to_Crest_Height + Ret_Row += 1 + + + + + return Ret_Row,Height_End # send back Height End as this is the lowest point + + +def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,INTERNAL = 1): + verts = [] + faces = [] + + DIV = 36 + + INNER_RADIUS = INNER_DIA/2 + OUTTER_RADIUS = OUTTER_DIA/2 + + Half_Pitch = float(PITCH)/2 + Deg_Step = 360.0 /float(DIV) + Height_Step = float(PITCH)/float(DIV) + + #print "HEIGHT" , HEIGHT + + Num = int(round((HEIGHT- PITCH)/PITCH)) # less one pitch for the start and end that is 1/2 pitch high + + #print "Num" ,Num + + Col = 0 + Row = 0 + + #CREST_PERCENT = 10 + #ROOT_PERCENT = 10 + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + + Height_Offset = 0 + FaceStart = len(verts) + + Row_Inc,Height_Offset = Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) + #Row_Inc,Height_Offset = Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) + Row += Row_Inc + + print "start Height_Offset ", Height_Offset + #Global_Thread_Height = 0 - Height_Offset + #faces.extend(Build_Face_List_Quads(FaceStart,DIV,Row -1)) + #return verts,faces + + + for j in range(Num): + + print j + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,Height_Offset - (Height_Step*i) ]) + Height_Offset -= Crest_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,Height_Offset - (Height_Step*i) ]) + Height_Offset -= Crest_to_Root_Height + Row += 1 + + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + verts.append([x,y,Height_Offset - (Height_Step*i) ]) + Height_Offset -= Root_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + verts.append([x,y,Height_Offset - (Height_Step*i) ]) + Height_Offset -= Root_to_Crest_Height + Row += 1 + + print "thread Height_Offset ", Height_Offset + # Row_Inc,Height_Offset = Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) + + # Row += Row_Inc + Row_Inc,Height_Offset = Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) + Row += Row_Inc + + + print "End Height_Offset ", Height_Offset + + + faces.extend(Build_Face_List_Quads(FaceStart,DIV,Row -1,INTERNAL)) + + #faces.extend(Fill_Ring_Face(len(verts)-DIV,DIV,1)) + + #Global_Thread_Height = 0 - Height_Offset + #print "Global_Thread_Height" ,Global_Thread_Height + return verts,faces,0 - Height_Offset + + + +########################################################################################## +########################################################################################## +## Create External Thread +########################################################################################## +########################################################################################## + + + + + +def Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): + + + Ret_Row = 0; + + Half_Pitch = float(PITCH)/2 + Height_Start = Height_Offset - PITCH + Height_Step = float(PITCH)/float(DIV) + Deg_Step = 360.0 /float(DIV) + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + +#theard start + + Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) + for j in range(4): + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z]) + Height_Offset -= Crest_Height + Ret_Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z ]) + Height_Offset -= Crest_to_Root_Height + Ret_Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + if j == 0: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + verts.append([x,y,z ]) + Height_Offset -= Root_Height + Ret_Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + + if j == 0: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + verts.append([x,y,z ]) + Height_Offset -= Root_to_Crest_Height + Ret_Row += 1 + + return Ret_Row,Height_Offset + + + + + + + + + + + + + + + +def Create_Shank_Verts(START_DIA,OUTTER_DIA,LENGTH,Z_LOCATION = 0): + + verts = [] + DIV = 36 + + START_RADIUS = START_DIA/2 + OUTTER_RADIUS = OUTTER_DIA/2 + + Opp = abs(START_RADIUS - OUTTER_RADIUS) + Taper_Lentgh = Opp/tan(radians(31)); + + if Taper_Lentgh > LENGTH: + Taper_Lentgh = 0 + + Stright_Length = LENGTH - Taper_Lentgh + + print "opp " , Opp + print "Taper_Lentgh " , Taper_Lentgh + print "Stright_Length " , Stright_Length + + + Deg_Step = 360.0 /float(DIV) + + Row = 0 + + Lowest_Z_Vert = 0; + + Height_Offset = Z_LOCATION + + + #ring + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*START_RADIUS + y = cos(radians(i*Deg_Step))*START_RADIUS + z = Height_Offset - 0 + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Stright_Length + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*START_RADIUS + y = cos(radians(i*Deg_Step))*START_RADIUS + z = Height_Offset - 0 + verts.append([x,y,z]) + if i == DIV: + print "ring", x,y,z + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Taper_Lentgh + Row += 1 + + +# for i in range(DIV+1): +# x = sin(radians(i*Deg_Step))*OUTTER_RADIUS +# y = cos(radians(i*Deg_Step))*OUTTER_RADIUS +# z = Height_Offset - 0 +# verts.append([x,y,z]) +# Lowest_Z_Vert = min(Lowest_Z_Vert,z) +# Height_Offset -= 1 +# Row += 1 + + + + return verts,Row,Height_Offset + + +def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): + + verts = [] + DIV = 36 + + INNER_RADIUS = INNER_DIA/2 + OUTTER_RADIUS = OUTTER_DIA/2 + + Half_Pitch = float(PITCH)/2 + Deg_Step = 360.0 /float(DIV) + Height_Step = float(PITCH)/float(DIV) + + Row = 0 + + Lowest_Z_Vert = 0; + + Height_Offset = Z_LOCATION + + #Height_Start = Height_Offset - PITCH + Height_Start = Height_Offset + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + + Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) + + Height_Offset = Z_LOCATION + PITCH + Cut_off = Z_LOCATION + + + for j in range(1): + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + z = Height_Offset - (Height_Step*i) + print "z", z + if z > Cut_off : z = Cut_off + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + z = Height_Offset - (Height_Step*i) + if z > Cut_off : z = Cut_off + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_to_Root_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + z = Height_Offset - (Height_Step*i) + if z > Cut_off : z = Cut_off + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + z = Height_Offset - (Height_Step*i) + if z > Cut_off : z = Cut_off + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_to_Crest_Height + Row += 1 + +## return verts,Row,Height_Offset + + + for j in range(2): + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_Height + Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + verts.append([x,y,z ]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_to_Root_Height + Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + if j == 0: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + verts.append([x,y,z ]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_Height + Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + if z > Height_Start: + z = Height_Start + + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + + if j == 0: + x = sin(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + y = cos(radians(i*Deg_Step))*(OUTTER_RADIUS - (i*Rank)) + verts.append([x,y,z ]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_to_Crest_Height + Row += 1 + + + return verts,Row,Height_Offset + + + + + + + + + +def Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): + verts = [] + + DIV = 36 + + INNER_RADIUS = INNER_DIA/2 + OUTTER_RADIUS = OUTTER_DIA/2 + + Half_Pitch = float(PITCH)/2 + Deg_Step = 360.0 /float(DIV) + Height_Step = float(PITCH)/float(DIV) + + NUM_OF_START_THREADS = 4.0 + NUM_OF_END_THREADS = 3.0 + Num = int((HEIGHT- ((NUM_OF_START_THREADS*PITCH) + (NUM_OF_END_THREADS*PITCH) ))/PITCH) + Row = 0 + + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + + + + #print "Crest_Height" ,Crest_Height + #print "Crest_to_Root_Height" ,Crest_to_Root_Height + #print "Root_Height" ,Root_Height + #print "Root_to_Crest_Height" ,Root_to_Crest_Height + + + + #Height_Offset = Half_Pitch + Height_Offset = Z_LOCATION + + Lowest_Z_Vert = 0; + FaceStart = len(verts) + + + + + + for j in range(Num): + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + z = Height_Offset - (Height_Step*i) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*OUTTER_RADIUS + y = cos(radians(i*Deg_Step))*OUTTER_RADIUS + z = Height_Offset - (Height_Step*i) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_to_Root_Height + Row += 1 + + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + z = Height_Offset - (Height_Step*i) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_Height + Row += 1 + + for i in range(DIV+1): + x = sin(radians(i*Deg_Step))*INNER_RADIUS + y = cos(radians(i*Deg_Step))*INNER_RADIUS + z = Height_Offset - (Height_Step*i) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_to_Crest_Height + Row += 1 + + return verts,Row,Height_Offset + + + +def Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): + verts = [] + + DIV = 36 + + INNER_RADIUS = INNER_DIA/2 + OUTTER_RADIUS = OUTTER_DIA/2 + + Half_Pitch = float(PITCH)/2 + Deg_Step = 360.0 /float(DIV) + Height_Step = float(PITCH)/float(DIV) + + Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) + Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) + Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 + + Col = 0 + Row = 0 + + Height_Offset = Z_LOCATION + + + Tapper_Height_Start = Height_Offset - PITCH - PITCH + #Tapper_Height_Start = Height_Offset + + Max_Height = Tapper_Height_Start - PITCH + #Max_Height = Tapper_Height_Start - PITCH - PITCH - PITCH - PITCH - PITCH + + Lowest_Z_Vert = 0; + + FaceStart = len(verts) + for j in range(4): + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + z = max(z,Max_Height) + Tapper_Radius = OUTTER_RADIUS + if z < Tapper_Height_Start: + Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z) + + x = sin(radians(i*Deg_Step))*(Tapper_Radius) + y = cos(radians(i*Deg_Step))*(Tapper_Radius) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_Height + Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + z = max(z,Max_Height) + Tapper_Radius = OUTTER_RADIUS + if z < Tapper_Height_Start: + Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z) + + x = sin(radians(i*Deg_Step))*(Tapper_Radius) + y = cos(radians(i*Deg_Step))*(Tapper_Radius) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Crest_to_Root_Height + Row += 1 + + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + z = max(z,Max_Height) + Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z) + if Tapper_Radius > INNER_RADIUS: + Tapper_Radius = INNER_RADIUS + + x = sin(radians(i*Deg_Step))*(Tapper_Radius) + y = cos(radians(i*Deg_Step))*(Tapper_Radius) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_Height + Row += 1 + + for i in range(DIV+1): + z = Height_Offset - (Height_Step*i) + z = max(z,Max_Height) + Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z) + if Tapper_Radius > INNER_RADIUS: + Tapper_Radius = INNER_RADIUS + + x = sin(radians(i*Deg_Step))*(Tapper_Radius) + y = cos(radians(i*Deg_Step))*(Tapper_Radius) + verts.append([x,y,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Height_Offset -= Root_to_Crest_Height + Row += 1 + + return verts,Row,Height_Offset,Lowest_Z_Vert + + + + +def Create_External_Thread(SHANK_DIA,SHANK_LENGTH,INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT): + + verts = [] + faces = [] + + DIV = 36 + + Total_Row = 0 + Thread_Len = 0; + + Face_Start = len(verts) + Offset = 0.0; + + + Shank_Verts,Shank_Row,Offset = Create_Shank_Verts(SHANK_DIA,OUTTER_DIA,SHANK_LENGTH,Offset) + Total_Row += Shank_Row + print "Shank offset " , Offset + + + Thread_Start_Verts,Thread_Start_Row,Offset = Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset) + Total_Row += Thread_Start_Row + print "Start offset " , Offset + + + Thread_Verts,Thread_Row,Offset = Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT,Offset) + Total_Row += Thread_Row + print "Thread offset " , Offset + + + Thread_End_Verts,Thread_End_Row,Offset,Lowest_Z_Vert = Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset ) + Total_Row += Thread_End_Row + print "End offset " , Offset + print "Lowest_Z_Vert " , Lowest_Z_Vert + + + + verts.extend(Shank_Verts) + verts.extend(Thread_Start_Verts) + verts.extend(Thread_Verts) + verts.extend(Thread_End_Verts) + + faces.extend(Build_Face_List_Quads(Face_Start,DIV,Total_Row -1,0)) + faces.extend(Fill_Ring_Face(len(verts)-DIV,DIV,1)) + + return verts,faces,0.0 - Lowest_Z_Vert + + +########################################################################################## +########################################################################################## +## Create Nut +########################################################################################## +########################################################################################## + + +def add_Hex_Nut(FLAT,HOLE_DIA,HEIGHT): + global Global_Head_Height + global Global_NutRad + + verts = [] + faces = [] + HOLE_RADIUS = HOLE_DIA * 0.5 + Half_Flat = FLAT/2 + Half_Height = HEIGHT/2 + TopBevelRadius = Half_Flat - 0.05 + + Global_NutRad = TopBevelRadius + + Row = 0; + Lowest_Z_Vert = 0.0; + + verts.append([0.0,0.0,0.0]) + + + FaceStart = len(verts) + #inner hole + + x = sin(radians(0))*HOLE_RADIUS + y = cos(radians(0))*HOLE_RADIUS + verts.append([x,y,0.0]) + + + x = sin(radians(60/6))*HOLE_RADIUS + y = cos(radians(60/6))*HOLE_RADIUS + verts.append([x,y,0.0]) + + + x = sin(radians(60/3))*HOLE_RADIUS + y = cos(radians(60/3))*HOLE_RADIUS + verts.append([x,y,0.0]) + + + x = sin(radians(60/2))*HOLE_RADIUS + y = cos(radians(60/2))*HOLE_RADIUS + verts.append([x,y,0.0]) + Row += 1 + + #bevel + + x = sin(radians(0))*TopBevelRadius + y = cos(radians(0))*TopBevelRadius + vec1 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + + + x = sin(radians(60/6))*TopBevelRadius + y = cos(radians(60/6))*TopBevelRadius + vec2 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + + + x = sin(radians(60/3))*TopBevelRadius + y = cos(radians(60/3))*TopBevelRadius + vec3 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + + + x = sin(radians(60/2))*TopBevelRadius + y = cos(radians(60/2))*TopBevelRadius + vec4 = Mathutils.Vector([x,y,0.0]) + verts.append([x,y,0.0]) + Row += 1 + + #Flats + + x = tan(radians(0))*Half_Flat + dvec = vec1 - Mathutils.Vector([x,Half_Flat,0.0]) + #print dvec.length + verts.append([x,Half_Flat,-dvec.length]) + Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) + + + x = tan(radians(60/6))*Half_Flat + dvec = vec2 - Mathutils.Vector([x,Half_Flat,0.0]) + verts.append([x,Half_Flat,-dvec.length]) + Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) + + + x = tan(radians(60/3))*Half_Flat + dvec = vec3 - Mathutils.Vector([x,Half_Flat,0.0]) + Lowest_Point = -dvec.length + verts.append([x,Half_Flat,-dvec.length]) + Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) + + x = tan(radians(60/2))*Half_Flat + dvec = vec4 - Mathutils.Vector([x,Half_Flat,0.0]) + Lowest_Point = -dvec.length + verts.append([x,Half_Flat,-dvec.length]) + Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) + Row += 1 + + #down Bits Tri + x = tan(radians(0))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + + + x = tan(radians(60/6))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + + x = tan(radians(60/3))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + + x = tan(radians(60/2))*Half_Flat + verts.append([x,Half_Flat,Lowest_Point]) + Lowest_Z_Vert = min(Lowest_Z_Vert,Lowest_Point) + Row += 1 + + #down Bits + + x = tan(radians(0))*Half_Flat + verts.append([x,Half_Flat,-Half_Height]) + + x = tan(radians(60/6))*Half_Flat + verts.append([x,Half_Flat,-Half_Height]) + + x = tan(radians(60/3))*Half_Flat + verts.append([x,Half_Flat,-Half_Height]) + + x = tan(radians(60/2))*Half_Flat + verts.append([x,Half_Flat,-Half_Height]) + Lowest_Z_Vert = min(Lowest_Z_Vert,-Half_Height) + Row += 1 + + + + + faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1)) + + + Global_Head_Height = HEIGHT + + Tvert,tface = Mirror_Verts_Faces(verts,faces,'z',Lowest_Z_Vert) + verts.extend(Tvert) + faces.extend(tface) + + + Tvert,tface = Mirror_Verts_Faces(verts,faces,'y') + verts.extend(Tvert) + faces.extend(tface) + + S_verts,S_faces = SpinDup(verts,faces,360,6,'z') + return S_verts,S_faces,TopBevelRadius + + + + + +def add_Nylon_Head_Top(OUTSIDE_RADIUS): + DIV = 36 + verts = [] + faces = [] + Row = 0 + + print "outside" , OUTSIDE_RADIUS + + INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) + EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) + RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) + OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) + + FaceStart = len(verts) + + Start_Height = 0 - 3 + Height_Offset = 0 + Lowest_Z_Vert = 0 + + + x = INNER_HOLE + z = Height_Offset - EDGE_THICKNESS + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = INNER_HOLE + z = Height_Offset - 0 + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + + for i in range(0,100,10): + #print i + x = sin(radians(i))*RAD1 + z = cos(radians(i))*RAD1 + verts.append([(OUTSIDE_RADIUS-RAD1)+x,0.0,(Height_Offset-RAD1)+z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + + x = OUTSIDE_RADIUS - 0 + z = Height_Offset - OVER_ALL_HEIGTH + print "ada" , z , OVER_ALL_HEIGTH + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + #return Move_Verts_Up_Z(verts,Start_Height),faces + return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert + + + +def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0): + DIV = 36 + verts = [] + faces = [] + Row = 0 + + print "outside" , OUTSIDE_RADIUS + + INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) + EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) + RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) + OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) + + FaceStart = len(verts) + + Start_Height = 0 - 3 + Height_Offset = Z_LOCATION + Lowest_Z_Vert = 0 + + + x = INNER_HOLE + z = (Height_Offset - OVER_ALL_HEIGTH) + EDGE_THICKNESS + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = INNER_HOLE + z = (Height_Offset - OVER_ALL_HEIGTH) + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + + for i in range(180,80,-10): + print i + x = sin(radians(i))*RAD1 + z = cos(radians(i))*RAD1 + verts.append([(OUTSIDE_RADIUS-RAD1)+x,0.0,((Height_Offset - OVER_ALL_HEIGTH)+RAD1)+z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + + x = OUTSIDE_RADIUS - 0 + z = Height_Offset + print "ada" , z , OVER_ALL_HEIGTH + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + return Move_Verts_Up_Z(sVerts,0),faces,Lowest_Z_Vert + #return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert + + + +def add_Nylon_Part_top(OUTSIDE_RADIUS,Z_LOCATION = 0): + DIV = 36 + verts = [] + faces = [] + Row = 0 + + print "outside" , OUTSIDE_RADIUS + + + INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) + EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) + RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) + OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) + PART_THICKNESS = OVER_ALL_HEIGTH - EDGE_THICKNESS + PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5/4.75)) + + FaceStart = len(verts) + + Start_Height = 0 - 3 + Height_Offset = 0 + Lowest_Z_Vert = 0 + + + x = INNER_HOLE + EDGE_THICKNESS + z = Height_Offset - OVER_ALL_HEIGTH + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = PART_INNER_HOLE + z = Height_Offset - OVER_ALL_HEIGTH + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = PART_INNER_HOLE + z = Height_Offset - EDGE_THICKNESS + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = INNER_HOLE + EDGE_THICKNESS + z = Height_Offset - EDGE_THICKNESS + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + return sVerts,faces,0 - Lowest_Z_Vert + #return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert + + + +def add_Nylon_Part(OUTSIDE_RADIUS,Z_LOCATION = 0): + DIV = 36 + verts = [] + faces = [] + Row = 0 + + print "outside" , OUTSIDE_RADIUS + + + INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) + EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) + RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) + OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) + PART_THICKNESS = OVER_ALL_HEIGTH - EDGE_THICKNESS + PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5/4.75)) + + FaceStart = len(verts) + + Start_Height = 0 - 3 + Height_Offset = Z_LOCATION + Lowest_Z_Vert = 0 + + + x = INNER_HOLE + EDGE_THICKNESS + z = Height_Offset + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = PART_INNER_HOLE + z = Height_Offset + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = PART_INNER_HOLE + z = Height_Offset - PART_THICKNESS + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + x = INNER_HOLE + EDGE_THICKNESS + z = Height_Offset - PART_THICKNESS + verts.append([x,0.0,z]) + Lowest_Z_Vert = min(Lowest_Z_Vert,z) + Row += 1 + + + sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') + sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop + + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + + return sVerts,faces,0 - Lowest_Z_Vert + #return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert + + + +def Nut_Mesh(): + + verts = [] + faces = [] + Head_Verts = [] + Head_Faces= [] + + Face_Start = len(verts) + Thread_Verts,Thread_Faces,New_Nut_Height = Create_Internal_Thread(Minor_Dia.val,Major_Dia.val,Pitch.val,Hex_Nut_Height.val,Crest_Percent.val,Root_Percent.val,1) + verts.extend(Thread_Verts) + faces.extend(Copy_Faces(Thread_Faces,Face_Start)) + + Face_Start = len(verts) + Head_Verts,Head_Faces,Lock_Nut_Rad = add_Hex_Nut(Hex_Nut_Flat_Distance.val,Major_Dia.val,New_Nut_Height) + verts.extend((Head_Verts)) + faces.extend(Copy_Faces(Head_Faces,Face_Start)) + + LowZ = 0 - New_Nut_Height + + if Nut_Type['LOCK'][0].val: + Face_Start = len(verts) + Nylon_Head_Verts,Nylon_Head_faces,LowZ = add_Nylon_Head(Lock_Nut_Rad,0-New_Nut_Height) + verts.extend((Nylon_Head_Verts)) + faces.extend(Copy_Faces(Nylon_Head_faces,Face_Start)) + + Face_Start = len(verts) + Nylon_Verts,Nylon_faces,Temp_LowZ = add_Nylon_Part(Lock_Nut_Rad,0-New_Nut_Height) + verts.extend((Nylon_Verts)) + faces.extend(Copy_Faces(Nylon_faces,Face_Start)) + + + #verts.extend(Move_Verts_Up_Z(Thread_Verts,Global_Thread_Height)) + #verts.extend(Thread_Verts) + #faces.extend(Copy_Faces(Thread_Faces,Face_Start)) + print "low z" , LowZ + #return Move_Verts_Up_Z(verts,0),faces + return Move_Verts_Up_Z(verts,0 - LowZ),faces + + + +def Create_Nut(): + verts = [] + faces = [] + + + if Error_Check() : + return + + me = Mesh.New('Nut') # create a new mesh + + verts, faces = Nut_Mesh() + + me.verts.extend(verts) # add vertices to mesh + me.faces.extend(faces) # add faces to the mesh (also adds edges) + + is_editmode = Window.EditMode() # Store edit mode state + if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. + + + scn = Scene.GetCurrent() # link object to current scene + scn.objects.selected = [] + ob = scn.objects.active = scn.objects.new(me, 'Nut') + ob.loc = Window.GetCursorPos() + + me.remDoubles(0.010) + + if is_editmode: Window.EditMode(1) + + Blender.Redraw() + + +################################################################################################## + +def Get_Phillips_Bit_Height(Bit_Dia): + Flat_Width_half = (Bit_Dia*(0.5/1.82))/2.0 + Bit_Rad = Bit_Dia / 2.0 + x = Bit_Rad - Flat_Width_half + y = tan(radians(60))*x + return y + + + +def Load_Preset(): + + global Preset_Menu + global Preset_Length + global Shank_Dia + global Shank_Length + global Thread_Length + global Major_Dia + global Minor_Dia + global Pitch + global Crest_Percent + global Root_Percent + global Allen_Bit_Flat_Distance + global Allen_Bit_Depth + global Head_Height + global Hex_Head_Flat_Distance + global Head_Dia + global Dome_Head_Dia + global Pan_Head_Dia + global Philips_Bit_Dia + global Phillips_Bit_Depth + global Cap_Head_Inside_Rad + global Cap_Head_Height + + global Hex_Nut_Height + global Hex_Nut_Flat_Distance + + + +# Crest_Percent.val = 13 +# Root_Percent.val = 24 +# Thread_Length.val = 8 +# +# +# if Preset_Menu.val == 4 : #M4 +# Major_Dia.val = 4.0 +# Pitch.val = 0.7 +# +# Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) +# Hex_Head_Flat_Distance.val = 1.75 * Major_Dia.val +# +# Shank_Dia.val = Major_Dia.val +# Shank_Length.val = 0.0 +# Hex_Head_Height.val = 2.8 +# +# Cap_Head_Dia.val = 7.0 +# Allen_Bit_Flat_Distance.val = 3.0 +# Phillips_Bit_Depth.val = 1.5 + + + if Preset_Menu.val == 1 : #M3 + Shank_Dia.val = 3.0 + #Pitch.val = 0.5 #Coarse + Pitch.val = 0.35 #Fine + Major_Dia.val = 3.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 5.5 + Hex_Head_Height.val = 2.0 + Cap_Head_Dia.val = 5.5 + Cap_Head_Height.val = 3.0 + Allen_Bit_Flat_Distance.val = 2.5 + Allen_Bit_Depth.val = 1.5 + Pan_Head_Dia.val = 5.6 + Dome_Head_Dia.val = 5.6 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 2.4 + Hex_Nut_Flat_Distance.val = 5.5 + Thread_Length.val = 6 + Shank_Length.val = 0.0 + + + if Preset_Menu.val == 2 : #M4 + Shank_Dia.val = 4.0 + #Pitch.val = 0.7 #Coarse + Pitch.val = 0.5 #Fine + Major_Dia.val = 4.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 7.0 + Hex_Head_Height.val = 2.8 + Cap_Head_Dia.val = 7.0 + Cap_Head_Height.val = 4.0 + Allen_Bit_Flat_Distance.val = 3.0 + Allen_Bit_Depth.val = 2.0 + Pan_Head_Dia.val = 8.0 + Dome_Head_Dia.val = 8.0 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 3.2 + Hex_Nut_Flat_Distance.val = 7.0 + Thread_Length.val = 8 + Shank_Length.val = 0.0 + + + if Preset_Menu.val == 3 : #M5 + Shank_Dia.val = 5.0 + #Pitch.val = 0.8 #Coarse + Pitch.val = 0.5 #Fine + Major_Dia.val = 5.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 8.0 + Hex_Head_Height.val = 3.5 + Cap_Head_Dia.val = 8.5 + Cap_Head_Height.val = 5.0 + Allen_Bit_Flat_Distance.val = 4.0 + Allen_Bit_Depth.val = 2.5 + Pan_Head_Dia.val = 9.5 + Dome_Head_Dia.val = 9.5 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 4.0 + Hex_Nut_Flat_Distance.val = 8.0 + Thread_Length.val = 10 + Shank_Length.val = 0.0 + + + if Preset_Menu.val == 4 : #M6 + Shank_Dia.val = 6.0 + #Pitch.val = 1.0 #Coarse + Pitch.val = 0.75 #Fine + Major_Dia.val = 6.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 10.0 + Hex_Head_Height.val = 4.0 + Cap_Head_Dia.val = 10.0 + Cap_Head_Height.val = 6.0 + Allen_Bit_Flat_Distance.val = 5.0 + Allen_Bit_Depth.val = 3.0 + Pan_Head_Dia.val = 12.0 + Dome_Head_Dia.val = 12.0 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 5.0 + Hex_Nut_Flat_Distance.val = 10.0 + Thread_Length.val = 12 + Shank_Length.val = 0.0 + + + if Preset_Menu.val == 5 : #M8 + Shank_Dia.val = 8.0 + #Pitch.val = 1.25 #Coarse + Pitch.val = 1.00 #Fine + Major_Dia.val = 8.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 13.0 + Hex_Head_Height.val = 5.3 + Cap_Head_Dia.val = 13.5 + Cap_Head_Height.val = 8.0 + Allen_Bit_Flat_Distance.val = 6.0 + Allen_Bit_Depth.val = 4.0 + Pan_Head_Dia.val = 16.0 + Dome_Head_Dia.val = 16.0 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 6.5 + Hex_Nut_Flat_Distance.val = 13.0 + Thread_Length.val = 16 + Shank_Length.val = 0.0 + + if Preset_Menu.val == 6 : #M10 + Shank_Dia.val = 10.0 + #Pitch.val = 1.5 #Coarse + Pitch.val = 1.25 #Fine + Major_Dia.val = 10.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 17.0 + Hex_Head_Height.val = 6.4 + Cap_Head_Dia.val = 16.0 + Cap_Head_Height.val = 10.0 + Allen_Bit_Flat_Distance.val = 8.0 + Allen_Bit_Depth.val = 5.0 + Pan_Head_Dia.val = 20.0 + Dome_Head_Dia.val = 20.0 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 8.0 + Hex_Nut_Flat_Distance.val = 17.0 + Thread_Length.val = 20 + Shank_Length.val = 0.0 + + + if Preset_Menu.val == 7 : #M12 + #Pitch.val = 1.75 #Coarse + Pitch.val = 1.50 #Fine + Major_Dia.val = 12.0 + Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) + Hex_Head_Flat_Distance.val = 19.0 + Hex_Head_Height.val = 7.5 + Cap_Head_Dia.val = 18.5 + Cap_Head_Height.val = 12.0 + Allen_Bit_Flat_Distance.val = 10.0 + Allen_Bit_Depth.val = 6.0 + Pan_Head_Dia.val = 24.0 + Dome_Head_Dia.val = 24.0 + Philips_Bit_Dia.val = Pan_Head_Dia.val*(1.82/5.6) + Phillips_Bit_Depth.val = Get_Phillips_Bit_Height(Philips_Bit_Dia.val) + Hex_Nut_Height.val = 10.0 + Hex_Nut_Flat_Distance.val = 19.0 + Shank_Dia.val = 12.0 + Shank_Length.val = 33.0 + Thread_Length.val = 32.0 + + + +def get_selected_edges(edge_lst): + ret = [] + for i in range(0, len(edge_lst)): + if edge_lst[i].sel == 1: + ret.append(edge_lst[i]) + return ret + +def Test(): + + + print "Test" + scn = Scene.GetCurrent() + ob = scn.getActiveObject() # Gets the current active object (If Any) + + if ob == None or ob.getType() != 'Mesh': # Checks the active objects a mesh + Draw.PupMenu('ERROR%t|Select a mesh object.') + return + + is_editmode = Window.EditMode() # Store edit mode state + if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. + + me = ob.getData(False, True) + Sel_Edges = get_selected_edges(me.faces) + print Sel_Edges + print Sel_Edges[0].index + mystr = 'Face Number ' + str(Sel_Edges) + #mystr = 'Face Number ' + str(Sel_Edges[0].index) + Draw.PupMenu(mystr) + + + if is_editmode: Window.EditMode(1) + + + + + + +############################################################################################## + +def event(evt, val): # the function to handle input events + + if evt == Draw.ESCKEY: + Draw.Exit() # exit when user presses ESC + return + + +def button_event(evt): # the function to handle Draw Button events + + if evt == On_Exit_Click: + Draw.Exit() # exit when user presses ESC + return + + if evt == On_Test_Click: + Test() + Draw.Redraw(1) + + if evt == On_Preset_Click: + Load_Preset() + Draw.Redraw(1) + + if evt == On_Create_Click: + if Model_Type['BOLT'][0].val: + Create_Bolt() + if Model_Type['NUT'][0].val: + Create_Nut() + Draw.Redraw(1) + + elif (evt in [On_Hex_Click, On_Cap_Click,On_Dome_Click,On_Pan_Click]): + for k in Head_Type.iterkeys(): + if Head_Type[k][1]!=evt: + Head_Type[k][0].val=0 + else: + Head_Type[k][0].val=1 + Draw.Redraw(1) + + elif (evt in [On_Bit_None_Click,On_Bit_Allen_Click,On_Bit_Philips_Click]): + for k in Bit_Type.iterkeys(): + if Bit_Type[k][1]!=evt: + Bit_Type[k][0].val=0 + else: + Bit_Type[k][0].val=1 + Draw.Redraw(1) + + elif (evt in [On_Model_Bolt_Click,On_Model_Nut_Click]): + for k in Model_Type.iterkeys(): + if Model_Type[k][1]!=evt: + Model_Type[k][0].val=0 + else: + Model_Type[k][0].val=1 + Draw.Redraw(1) + + elif (evt in [On_Hex_Nut_Click,On_Lock_Nut_Click]): + for k in Nut_Type.iterkeys(): + if Nut_Type[k][1]!=evt: + Nut_Type[k][0].val=0 + else: + Nut_Type[k][0].val=1 + Draw.Redraw(1) + +##################################################################################### + + +def Draw_Border(X1,Y1,X2,Y2): # X1,Y1 = Top Left X2,Y2 = Bottom Right + INDENT = 3 + + BGL.glColor3f(1.0,1.0,1.0) + BGL.glBegin(BGL.GL_LINES) + BGL.glVertex2i(X1+INDENT,Y1-INDENT) #top line + BGL.glVertex2i(X2-INDENT,Y1-INDENT) + + BGL.glVertex2i(X1+INDENT,Y1-INDENT) #left line + BGL.glVertex2i(X1+INDENT,Y2+INDENT) + BGL.glEnd() + + BGL.glColor3f(0.5,0.5,0.5) + BGL.glBegin(BGL.GL_LINES) + BGL.glVertex2i(X2-INDENT,Y1-INDENT) #Right line + BGL.glVertex2i(X2-INDENT,Y2+INDENT) + + BGL.glVertex2i(X1+INDENT,Y2+INDENT) #bottom line + BGL.glVertex2i(X2-INDENT,Y2+INDENT) + BGL.glEnd() + + + + +def Create_Tab(X1,Y1,X2,Y2,Title,Buttons): # X1,Y1 = Top Left X2,Y2 = Bottom Right + + BIT_BUTTON_WIDTH = 55 + BIT_BUTTON_HEIGHT = 18 + TITLE_HEIGHT = 15 + INDENT = 6 + BUTTON_GAP = 4 + + BGL.glColor3f(0.75, 0.75, 0.75) + BGL.glRecti(X1,Y1,X2,Y2) + + Draw_Border(X1,Y1,X2,Y2); + + BGL.glColor3f(0.0,0.0,0.0) + BGL.glRasterPos2d(X1+INDENT,Y1 - TITLE_HEIGHT) + Draw.Text(Title) + + Button_X = X1 + INDENT + Button_Y = Y1 - TITLE_HEIGHT - BIT_BUTTON_HEIGHT - 8 + + #Nut_Number_X = Nut_Button_X + #Nut_Number_Y = Nut_Button_Y - 25 + if (Buttons != 0): + key= Buttons.keys() + for k in key: + Buttons[k][0]= Draw.Toggle(k,Buttons[k][1],Button_X,Button_Y, BIT_BUTTON_WIDTH,BIT_BUTTON_HEIGHT,Buttons[k][0].val) + Button_X += BIT_BUTTON_WIDTH + BUTTON_GAP + + + +def Dispaly_Title_Bar(Y_POS,CONTROL_HEIGHT): + CONTROL_WIDTH = 250 + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS -CONTROL_HEIGHT,"Bolt Factory V1.50_249",Model_Type) + + + +def Dispaly_Preset_Tab(Y_POS,CONTROL_HEIGHT): + CONTROL_WIDTH = 250 + BUTTON_Y_OFFSET = 40 + + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Preset",0) + + name = "M3%x1|M4%x2|M5%x3|M6%x4|M8%x5|M10%x6|M12%x7" + + global Preset_Menu + Preset_Menu = Draw.Menu(name,No_Event,9,Y_POS-BUTTON_Y_OFFSET,50,18, Preset_Menu.val, "Just a test menu.") + Draw.Button("Apply",On_Preset_Click,150,Y_POS-BUTTON_Y_OFFSET,55,18) + + +def Dispaly_Bit_Tab(Y_POS,CONTROL_HEIGHT): + + CONTROL_WIDTH = 250 + NUMBER_HEIGHT = 18 + NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3 + + Bit_Number_X = 3+3+3 + Bit_Number_Y = Y_POS - 64 + + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Bit Type",Bit_Type) + + if Bit_Type['NONE'][0].val: + DoNothing = 1; + + elif Bit_Type['ALLEN'][0].val: + global Allen_Bit_Depth + Allen_Bit_Depth = Draw.Number('Bit Depth: ',No_Event,Bit_Number_X,Bit_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Allen_Bit_Depth.val, 0,100, '') + Bit_Number_Y -= NUMBER_HEIGHT + global Allen_Bit_Flat_Distance + Allen_Bit_Flat_Distance = Draw.Number('Flat Dist: ',No_Event,Bit_Number_X,Bit_Number_Y,NUMBER_WIDTH,NUMBER_HEIGHT,Allen_Bit_Flat_Distance.val, 0,100, '') + Bit_Number_Y -= NUMBER_HEIGHT + + elif Bit_Type['PHILLIPS'][0].val: + global Phillips_Bit_Depth + Phillips_Bit_Depth = Draw.Number('Bit Depth: ',No_Event,Bit_Number_X,Bit_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Phillips_Bit_Depth.val, 0,100, '') + Bit_Number_Y -= NUMBER_HEIGHT + global Philips_Bit_Dia + Philips_Bit_Dia = Draw.Number('Bit Dia: ',No_Event,Bit_Number_X,Bit_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Philips_Bit_Dia.val, 0,100, '') + Bit_Number_Y -= NUMBER_HEIGHT + + + +def Dispaly_Shank_Tab(Y_POS,CONTROL_HEIGHT): + + CONTROL_WIDTH = 250 + NUMBER_HEIGHT = 18 + NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3 + + Number_X = 3+3+3 + Number_Y_Pos = Y_POS - 40 + + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Shank",0) + + global Shank_Length + Shank_Length = Draw.Number('Shank Length: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Shank_Length.val, 0,MAX_INPUT_NUMBER, 'some text tip') + Number_Y_Pos -= NUMBER_HEIGHT + + global Shank_Dia + Shank_Dia = Draw.Number('Shank Dia: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Shank_Dia.val, 0,MAX_INPUT_NUMBER, 'some text tip') + Number_Y_Pos -= NUMBER_HEIGHT + + + +def Dispaly_Thread_Tab(Y_POS,CONTROL_HEIGHT): + + CONTROL_WIDTH = 250 + NUMBER_HEIGHT = 18 + NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3 + + + Number_X = 3+3+3 + Number_Y_Pos = Y_POS - 40 + + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Thread",0) + + global Thread_Length + if Model_Type['BOLT'][0].val: + Thread_Length = Draw.Number('Thread Length: ',No_Event, Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Thread_Length.val, 0,MAX_INPUT_NUMBER, '') + Number_Y_Pos -= NUMBER_HEIGHT + + global Major_Dia + Major_Dia = Draw.Number('Major Dia: ',No_Event,Number_X,Number_Y_Pos, NUMBER_WIDTH,NUMBER_HEIGHT, Major_Dia.val, 0,MAX_INPUT_NUMBER, '') + Number_Y_Pos -= NUMBER_HEIGHT + + global Minor_Dia + Minor_Dia = Draw.Number('Minor Dia: ',No_Event,Number_X,Number_Y_Pos, NUMBER_WIDTH,NUMBER_HEIGHT, Minor_Dia.val, 0,MAX_INPUT_NUMBER, '') + Number_Y_Pos -= NUMBER_HEIGHT + + global Pitch + Pitch = Draw.Number('Pitch: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Pitch.val, 0.01,50.0, '') + Number_Y_Pos -= NUMBER_HEIGHT + + global Crest_Percent + Crest_Percent = Draw.Number('Crest %: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT,Crest_Percent.val, 1,90, '') + Number_Y_Pos -= NUMBER_HEIGHT + + global Root_Percent + Root_Percent = Draw.Number('Root %: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT,Root_Percent.val, 1,90, '') + Number_Y_Pos -= NUMBER_HEIGHT + + + + +def Dispaly_Head_Tab(Y_POS,CONTROL_HEIGHT): + + CONTROL_WIDTH = 250 + NUMBER_HEIGHT = 18 + NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3 + + Head_Number_X = 3+3+3 + Head_Number_Y = Y_POS - 64 + + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Head Type",Head_Type) + + if Head_Type['HEX'][0].val: + global Hex_Head_Height + Hex_Head_Height = Draw.Number('Head Height: ',No_Event,Head_Number_X ,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Head_Height.val, 0,100, '') + Head_Number_Y -= NUMBER_HEIGHT + global Hex_Head_Flat_Distance + Hex_Head_Flat_Distance = Draw.Number('Head Hex Flat Distance ',No_Event,Head_Number_X,Head_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Head_Flat_Distance.val, 0,MAX_INPUT_NUMBER, '') + Head_Number_Y -= NUMBER_HEIGHT + + elif Head_Type['CAP'][0].val: + global Cap_Head_Height + Cap_Head_Height = Draw.Number('Head Height: ',No_Event, Head_Number_X,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Cap_Head_Height.val, 0,100, '') + Head_Number_Y -= NUMBER_HEIGHT + global Cap_Head_Dia + Cap_Head_Dia = Draw.Number('Head Dia ',No_Event,Head_Number_X,Head_Number_Y,NUMBER_WIDTH, NUMBER_HEIGHT,Cap_Head_Dia.val, 0,MAX_INPUT_NUMBER, '') + Head_Number_Y -= NUMBER_HEIGHT + + elif Head_Type['DOME'][0].val: + global Dome_Head_Dia + Dome_Head_Dia = Draw.Number(' Dome Head Dia ',No_Event,Head_Number_X,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Dome_Head_Dia.val, 0,MAX_INPUT_NUMBER, '') + Head_Number_Y -= NUMBER_HEIGHT + + elif Head_Type['PAN'][0].val: + global Pan_Head_Dia + Pan_Head_Dia = Draw.Number('Pan Head Dia ',No_Event,Head_Number_X,Head_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Pan_Head_Dia.val, 0,MAX_INPUT_NUMBER, '') + Head_Number_Y -= NUMBER_HEIGHT + + + + +def Dispaly_Nut_Tab(Y_POS,CONTROL_HEIGHT): + + CONTROL_WIDTH = 250 + NUMBER_HEIGHT = 18 + NUMBER_WIDTH = CONTROL_WIDTH -3-3-3-3-3 + + Nut_Number_X = 3+3+3 + Nut_Number_Y = Y_POS - 64 + + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS-CONTROL_HEIGHT,"Nut Type",Nut_Type) + + #if Nut_Type['HEX'][0].val: + global Hex_Nut_Height + Hex_Nut_Height = Draw.Number('Nut Height: ',No_Event,Nut_Number_X ,Nut_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Nut_Height.val, 0,MAX_INPUT_NUMBER, '') + Nut_Number_Y -= NUMBER_HEIGHT + global Hex_Nut_Flat_Distance + Hex_Nut_Flat_Distance = Draw.Number('Nut Flat Distance ',No_Event,Nut_Number_X,Nut_Number_Y, NUMBER_WIDTH, NUMBER_HEIGHT,Hex_Nut_Flat_Distance.val, 0,MAX_INPUT_NUMBER, '') + Nut_Number_Y -= NUMBER_HEIGHT + + +def Dispaly_Bolt_Tab(): + + Dispaly_Shank_Tab(284,66) + Dispaly_Head_Tab(374,90) + Dispaly_Bit_Tab(464,90) + + +########################################################################################## + +def gui(): # the function to draw the screen + + CONTROL_WIDTH = 250 + + BGL.glClearColor(0.6, 0.6, 0.6, 1.0) + BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) + + BGL.glColor3f(0.75, 0.75, 0.75) + BGL.glRecti(3,30,CONTROL_WIDTH,3) + + Dispaly_Title_Bar(514,50); + + if Model_Type['BOLT'][0].val: + Dispaly_Bolt_Tab(); + + if Model_Type['NUT'][0].val: + Dispaly_Nut_Tab(464,246); + + Dispaly_Thread_Tab(218,138) + + Dispaly_Preset_Tab(80,50) + + Draw.PushButton("Create",On_Create_Click,6,8,55,18,"Create Bolt") + Draw.Button("Exit",On_Exit_Click,6+55+4,8,55,18) + + #Draw.Button("Test",On_Test_Click,150,10,55,20) + #Draw.Button("Nut2",On_Nut2_Click,150,32,55,20) + + #key.sort() + + +Draw.Register(gui, event, button_event) # registering the 3 callbacks From a220ae2f6007dee191c77997d22fff5311cdc3ce Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 05:35:32 +0000 Subject: [PATCH 202/444] 2D Cutout Image Importer from Kevin Morgan (forTe) imports images as quads in the 3D view made some changes - images that fail to import give an error popup rather then a script error - extension input is only shown for batch directory importing - extension comparison is now case insensitive - importing images from "/" failed, (bug in Blender.sys.dirname), use os.path.dirname since os is needed for batch import in other places. - disable Esc for quitting because escaping from the file selector would quit the script too. --- release/scripts/image_2d_cutout.py | 559 +++++++++++++++++++++++++++++ 1 file changed, 559 insertions(+) create mode 100644 release/scripts/image_2d_cutout.py diff --git a/release/scripts/image_2d_cutout.py b/release/scripts/image_2d_cutout.py new file mode 100644 index 00000000000..16d0805256b --- /dev/null +++ b/release/scripts/image_2d_cutout.py @@ -0,0 +1,559 @@ +#!BPY + +""" +Name: '2D Cutout Image Importer' +Blender: 249 +Group: 'Image' +Tooltip: 'Batch UV Map images to Planes' +""" + +__author__ = "Kevin Morgan (forTe)" +__url__ = ("Home page, http://gamulabs.freepgs.com") +__version__ = "1.2.1" +__bpydoc__ = """\ +This Script will take an image and +UV map it to a plane sharing the same width to height ratio as the image. +Import options allow for the image to be a still or sequence type image +

+Imports can be single images or whole directories of images depending on the chosen +option. +""" + +#################################################### +#Copyright (C) 2008: Kevin Morgan +#################################################### +#-------------GPL LICENSE BLOCK------------- +#This program is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#This program is distributed in the hopes that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with this program. If not, see . +#################################################### +#################################################### +#V1.0 +#Basic Functionality +#Published June 28, 2007 +#################################################### +#V1.1 +#Added Support for enabling viewport transparency +#Added more options to the UI for materials +#Added Proportionality code (Pixels per unit) +#Added GPL License Block +#Published June 29, 2007 +#################################################### +#V1.2 +#Added Support for Copying Existing Materials +#Import Images as Sequences +#Refreshed GUI - now with more clutter :( +#Miscellaneous and Housekeeping +#Published June 16, 2008 +#################################################### +#V1.2.1 +#Added Extend Texture Mode option at request of a user +#Published September 24, 2008 +#################################################### + +import Blender +from Blender import BGL, Draw, Image, Mesh, Material, Texture, Window +from Blender.Mathutils import * +import bpy + +# Global Constants +DIR = 0 +SINGLE = 1 +CUROFFS = 0 + +# GUI CONSTANTS +NO_EVT = 0 +SINGLE_IMG = 1 +DIRECTORY_IMG = 2 +CLR_PATH = 3 +CHG_EXT = 4 +EXIT = 5 +DO_SCRIPT = 6 + +VERSIONSTRING = '1.2.1' + +# Note the two parameter dicts could be combined, I just, liked them seperate... +# GUI Buttons Dict +GUIPARAMS = { + 'Path': Draw.Create(''), + 'ImageExt': Draw.Create(''), + 'Seq': Draw.Create(0), + 'PackImage': Draw.Create(0), + 'PPU': Draw.Create(50), + 'VPTransp': Draw.Create(1), + 'XOff': Draw.Create(0.0), + 'YOff': Draw.Create(0.0), + 'ZOff': Draw.Create(0.0), + 'CopyMat': Draw.Create(0), + 'MatId': Draw.Create(0), + 'MatCol': Draw.Create(1.0, 0.0, 0.0), + 'Ref': Draw.Create(0.8), + 'Spec': Draw.Create(0.5), + 'Hard': Draw.Create(50), + 'Alpha': Draw.Create(1.0), + 'ZTransp': Draw.Create(1), + 'Shadeless': Draw.Create(0), + 'TexChan': Draw.Create(1), + 'MPTCol': Draw.Create(1), + 'MPTAlpha': Draw.Create(1), + 'UseAlpha': Draw.Create(1), + 'CalcAlpha': Draw.Create(0), + 'ExtendMode': Draw.Create(0), + 'AutoRefresh': Draw.Create(0), + 'Cyclic': Draw.Create(0), + 'Frames': Draw.Create(100), + 'Offs': Draw.Create(0), + 'StartFr': Draw.Create(1), + 'RedrawImp': Draw.Create(0) +} + +# Script Execution Paramaters +PARAMS = { + 'ImagePaths': [], # Path to images to import + 'ImportType': SINGLE, # Import a Directory or a Single Image? + 'ImageProp': Image.Sources.STILL, # What sources for the image, still or sequence + 'PackImage': 0, # Pack the Image(s)? + 'PPU': 20, # Pixels Per Blender Unit + 'MakeTransp': 1, # Make face transparent in viewport + + 'NewMat': 1, # If true make a new material, otherwise duplicate an existing one, replacing appropriate attributes + 'MaterialId': 0, # ID to take from the Materials list upon copy + 'Materials': None, # Materials in Scene + 'MatProps': {'Col': [1.0, 0.0, 0.0], 'Shadeless': 1, 'Ref': 0.5, 'Spec': 0.5, 'Hard': 200, 'Alpha': 1.0, 'ZTransp': 1}, + + 'TexProps': {'UseAlpha': 1, 'CalcAlpha': 0, 'ExtendMode': 0}, # Texture Properties + 'TexChannel': 0, # Texture Channel + 'TexMapTo': {'Col': 1, 'Alpha': 1}, # Map to Col and/or Alpha + 'SeqProps': {'AutoRefresh': 0, 'Cyclic': 0, 'Frames': 100, 'Offs': 0, 'StartFr': 1}, + 'ObOffset': Vector(1, 0, 0) # Offset by this vector upon creation for multifile import +} + +# Get the Active Scene, of course +scn = bpy.data.scenes.active + +########################################## +# MAIN SCRIPT FUNCTIONS +########################################## + +def imgImport(imgPath): + global CUROFFS, PARAMS + ###################################### + # Load the image + ###################################### + try: + img = Image.Load(imgPath) + imgDimensions = img.getSize() # do this to ensure the data is available + except: + Blender.Draw.PupMenu('Error%t|Unsupported image format for "'+ imgPath.split('\\')[-1].split('/')[-1] +'"') + return + + if PARAMS['PackImage']: + img.pack() + name = Blender.sys.makename(imgPath, strip = 1) + + ###################################### + # Construct the mesh + ###################################### + + me = Mesh.New(name) + + # Calculate Dimensions from Image Size + dim = [float(i)/PARAMS['PPU'] for i in imgDimensions] + v = [[dim[0], dim[1], 0], [-dim[0], dim[1], 0], [-dim[0], -dim[1], 0], [dim[0], -dim[1], 0]] + me.verts.extend(v) + me.faces.extend([0, 1, 2, 3]) + + me.faces[0].image = img + me.faces[0].uv = [Vector(1.0, 1.0), Vector(0.0, 1.0), Vector(0.0, 0.0), Vector(1.0, 0.0)] + + if PARAMS['MakeTransp']: + me.faces[0].transp = Mesh.FaceTranspModes.ALPHA + + ###################################### + # Modify the Material + ###################################### + + mat = None + if not PARAMS['NewMat']: + mat = PARAMS['Materials'][PARAMS['MaterialId']].__copy__() + mat.setName(name) + else: + mat = Material.New(name) + properties = PARAMS['MatProps'] + mat.setRGBCol(properties['Col']) + mat.setRef(properties['Ref']) + mat.setSpec(properties['Spec']) + mat.setHardness(properties['Hard']) + mat.setAlpha(properties['Alpha']) + + if properties['Shadeless']: + mat.mode |= Material.Modes.SHADELESS + if properties['ZTransp']: + mat.mode |= Material.Modes.ZTRANSP + + properties = PARAMS['TexProps'] + + tex = Texture.New(name) + tex.setType('Image') + tex.setImage(img) + if properties['UseAlpha']: + tex.useAlpha = Texture.ImageFlags.USEALPHA + + if properties['CalcAlpha']: + tex.calcAlpha = Texture.ImageFlags.CALCALPHA + + if properties['ExtendMode']: + tex.setExtend('Extend') + + if PARAMS['ImageProp'] == Image.Sources.SEQUENCE: + properties = PARAMS['SeqProps'] + + img.source = PARAMS['ImageProp'] # Needs to be done here, otherwise an error with earlier getSize() + + tex.animStart = properties['StartFr'] + tex.animOffset = properties['Offs'] + tex.animFrames = properties['Frames'] + tex.autoRefresh = properties['AutoRefresh'] + tex.cyclic = properties['Cyclic'] + + texMapSetters = Texture.TexCo.UV + + # PARAMS['TexMapTo']['Col'] (and alpha) will either be 0 or 1 because its from a toggle, otherwise this line doesn't work + texChanSetters = Texture.MapTo.COL * PARAMS['TexMapTo']['Col'] | Texture.MapTo.ALPHA * PARAMS['TexMapTo']['Alpha'] + + mat.setTexture(PARAMS['TexChannel'], tex, texMapSetters, texChanSetters) + me.materials += [mat] + + ###################################### + # Object Construction + ###################################### + + ob = scn.objects.new(me, name) + p = Vector(ob.getLocation()) # Should be the origin, but just to be safe, get it + ob.setLocation((CUROFFS * PARAMS['ObOffset']) + p) + + return + +def translateParams(): + # Translates (or assigns for the most part) GUI values to those that can be read by the + # Import Function + + global GUIPARAMS, PARAMS + + if GUIPARAMS['Seq'].val and PARAMS['ImportType'] != DIR: + PARAMS['ImageProp'] = Image.Sources.SEQUENCE + + PARAMS['PackImage'] = GUIPARAMS['PackImage'].val + PARAMS['PPU'] = GUIPARAMS['PPU'].val + PARAMS['MakeTransp'] = GUIPARAMS['VPTransp'].val + PARAMS['ObOffset'] = Vector(GUIPARAMS['XOff'].val, GUIPARAMS['YOff'].val, GUIPARAMS['ZOff'].val) + + PARAMS['NewMat'] = not GUIPARAMS['CopyMat'].val + PARAMS['MaterialId'] = GUIPARAMS['MatId'].val + PARAMS['MatProps']['Col'] = list(GUIPARAMS['MatCol'].val) + PARAMS['MatProps']['Ref'] = GUIPARAMS['Ref'].val + PARAMS['MatProps']['Spec'] = GUIPARAMS['Spec'].val + PARAMS['MatProps']['Hard'] = GUIPARAMS['Hard'].val + PARAMS['MatProps']['Alpha'] = GUIPARAMS['Alpha'].val + PARAMS['MatProps']['ZTransp'] = GUIPARAMS['ZTransp'].val + PARAMS['MatProps']['Shadeless'] = GUIPARAMS['Shadeless'].val + + PARAMS['TexChannel'] = GUIPARAMS['TexChan'].val - 1 #Channels are 0-9, but GUI shows 1-10 + PARAMS['TexProps']['UseAlpha'] = GUIPARAMS['UseAlpha'].val + PARAMS['TexProps']['CalcAlpha'] = GUIPARAMS['CalcAlpha'].val + PARAMS['TexProps']['ExtendMode'] = GUIPARAMS['ExtendMode'].val + PARAMS['TexMapTo']['Col'] = GUIPARAMS['MPTCol'].val + PARAMS['TexMapTo']['Alpha'] = GUIPARAMS['MPTAlpha'].val + + PARAMS['SeqProps']['AutoRefresh'] = GUIPARAMS['AutoRefresh'].val + PARAMS['SeqProps']['Cyclic'] = GUIPARAMS['Cyclic'].val + PARAMS['SeqProps']['Frames'] = GUIPARAMS['Frames'].val + PARAMS['SeqProps']['Offs'] = GUIPARAMS['Offs'].val + PARAMS['SeqProps']['StartFr'] = GUIPARAMS['StartFr'].val + return + +def doScript(): + # Main script Function + # Consists of choosing between 2 loops, one with a redraw, one without, see comments for why + + global CUROFFS + + translateParams() + + total = len(PARAMS['ImagePaths']) + broken = 0 + + if GUIPARAMS['RedrawImp'].val: # Reduces the need to compare on every go through the loop + for i, path in enumerate(PARAMS['ImagePaths']): + CUROFFS = i # Could be passed to the import Function, but I chose a global instead + Window.DrawProgressBar(float(i)/total, "Importing %i of %i Images..." %(i+1, total)) + imgImport(path) + Blender.Redraw() + if Blender.Get('version') >= 246: + if Window.TestBreak(): + broken = 1 + break + else: + for i, path in enumerate(PARAMS['ImagePaths']): + CUROFFS = i + Window.DrawProgressBar(float(i)/total, "Importing %i of %i Images..." %(i+1, total)) + imgImport(path) + if Blender.Get('version') >= 246: + if Window.TestBreak(): + broken = 1 + break + + if broken: + Window.DrawProgressBar(1.0, "Script Execution Aborted") + else: + Window.DrawProgressBar(1.0, "Finished Importing") + + Blender.Redraw() # Force a refresh, since the user may have chosen to not refresh as they go along + + return + +########################################## +# PATH SETTERS AND CHANGERS +########################################## + +def setSinglePath(filename): + global GUIPARAMS, PARAMS + GUIPARAMS['Path'].val = filename + PARAMS['ImagePaths'] = [filename] + return + +def setDirPath(filename): + global GUIPARAMS, PARAMS + + try: + import os + except: + Draw.PupMenu('Full install of python required to be able to set Directory Paths') + Draw.Exit() + return + + path = os.path.dirname(filename) # Blender.sys.dirname fails on '/' + GUIPARAMS['Path'].val = path + + ext_lower = GUIPARAMS['ImageExt'].val.lower() + for f in os.listdir(path): + if f.lower().endswith(ext_lower): + PARAMS['ImagePaths'].append(os.path.join(path, f)) + + return + +def changeExtension(): + global GUIPARAMS, PARAMS + + if PARAMS['ImportType'] == SINGLE: + return + + try: + import os + except: + Draw.PupMenu('Full install of python required to be able to set Directory Paths') + Draw.Exit() + return + + PARAMS['ImagePaths'] = [] + + ext_lower = GUIPARAMS['ImageExt'].val.lower() + for f in os.listdir(GUIPARAMS['Path'].val): + if f.lower().endswith(ext_lower): + PARAMS['ImagePaths'].append(os.path.join(GUIPARAMS['Path'].val, f)) + + return + +########################################## +# INTERFACE FUNCTIONS +########################################## +def compileMaterialList(): + # Pretty straight forward, just grabs the materials in the blend file and constructs + # an appropriate string for use as a menu + + mats = [mat for mat in bpy.data.materials] + PARAMS['Materials'] = mats + title = 'Materials%t|' + menStrs = [mat.name + '%x' + str(i) + '|' for i, mat in enumerate(mats)] + return title + ''.join(menStrs) + +def event(evt, val): + # Disabled, since Esc is often used from the file browser + #if evt == Draw.ESCKEY: + # Draw.Exit() + + return + +def bevent(evt): + global GUIPARAMS, PARAMS + + if evt == NO_EVT: + Draw.Redraw() + + elif evt == SINGLE_IMG: + Window.FileSelector(setSinglePath, 'Image', Blender.sys.expandpath('//')) + Draw.Redraw() + PARAMS['ImportType'] = SINGLE + + elif evt == DIRECTORY_IMG: + Window.FileSelector(setDirPath, 'Directory', Blender.sys.expandpath('//')) + Draw.Redraw() + PARAMS['ImportType'] = DIR + + elif evt == CLR_PATH: + GUIPARAMS['Path'].val = '' + PARAMS['ImagePaths'] = [] + GUIPARAMS['ImageExt'].val = '' + Draw.Redraw() + + elif evt == CHG_EXT: + changeExtension() + Draw.Redraw() + + elif evt == EXIT: + Draw.Exit() + + elif evt == DO_SCRIPT: + doScript() + + else: + print "ERROR: UNEXPECTED BUTTON EVENT" + + return + +# GUI Colors ###### +ScreenColor = [0.7, 0.7, 0.7] +BackgroundColor = [0.8, 0.8, 0.8] +TitleBG = [0.6, 0.6, 0.6] +TitleCol = [1.0, 1.0, 1.0] +ErrCol = [1.0, 0.0, 0.0] +TextCol = [0.4, 0.4, 0.5] +################### + +def GUI(): + global GUIPARAMS, PARAMS + + BGL.glClearColor(*(ScreenColor + [1.0])) + BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) + + minx = 5 + maxx = 500 + miny = 5 + maxy = 450 + + lineheight = 24 + buPad = 5 # Generic Button Padding, most buttons should have 24-19 (or 5) px space around them + + lP = 5 # Left Padding + rP = 5 # Right Padding + + # Draw Background Box + BGL.glColor3f(*BackgroundColor) + BGL.glRecti(minx, miny, maxx, maxy) + + # Draw Title + BGL.glColor3f(*TitleBG) + BGL.glRecti(minx, maxy - (lineheight), maxx, maxy) + BGL.glColor3f(*TitleCol) + + title = "2D Cutout Image Importer v" + VERSIONSTRING + BGL.glRasterPos2i(minx + lP, maxy - 15) + Draw.Text(title, 'large') + + Draw.PushButton('Exit', EXIT, maxx-50-rP, maxy - lineheight + 2, 50, 19, "Exit Script") + + # Path Buttons + if GUIPARAMS['Path'].val == '': + Draw.PushButton('Single Image', SINGLE_IMG, minx + lP, maxy - (2*lineheight), 150, 19, "Select a Single Image to Import") + Draw.PushButton('Directory', DIRECTORY_IMG, minx + lP + 150, maxy - (2*lineheight), 150, 19, "Select a Directory of Images to Import") + + else: + Draw.PushButton('Clear', CLR_PATH, minx+lP, maxy - (2*lineheight), 50, 19, "Clear Path and Change Import Options") + + GUIPARAMS['Path'] = Draw.String('Path: ', NO_EVT, minx + lP, maxy - (3*lineheight), (maxx-minx-lP-rP), 19, GUIPARAMS['Path'].val, 399, 'Path to Import From') + if PARAMS['ImportType'] == DIR: + GUIPARAMS['ImageExt'] = Draw.String('Image Ext: ', CHG_EXT, minx + lP, maxy - (4*lineheight), 110, 19, GUIPARAMS['ImageExt'].val, 6, 'Image extension for batch directory importing (case insensitive)') + GUIPARAMS['PackImage'] = Draw.Toggle('Pack', NO_EVT, maxx - rP - 50, maxy - (4*lineheight), 50, 19, GUIPARAMS['PackImage'].val, 'Pack Image(s) into .Blend File') + + # Geometry and Viewport Options + BGL.glColor3f(*TextCol) + BGL.glRecti(minx+lP, maxy - (5*lineheight), maxx-rP, maxy - (5*lineheight) + 1) + BGL.glRasterPos2i(minx + lP, maxy-(5*lineheight) + 3) + Draw.Text('Geometry and Display Options', 'small') + + GUIPARAMS['PPU'] = Draw.Slider('Pixels Per Unit: ', NO_EVT, minx + lP, maxy - (6*lineheight), (maxx-minx)/2 - lP, 19, GUIPARAMS['PPU'].val, 1, 5000, 0, 'Set the Number of Pixels Per Blender Unit to preserve Image Size Relations') + GUIPARAMS['VPTransp'] = Draw.Toggle('Viewport Transparency', NO_EVT, minx + lP, maxy - (8*lineheight), (maxx-minx)/2 - lP, 2*lineheight - buPad, GUIPARAMS['VPTransp'].val, 'Display Alpha Transparency in the Viewport') + + GUIPARAMS['XOff'] = Draw.Slider('Offs X: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (6*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['XOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the X-Direction if Importing Multiple Images') + GUIPARAMS['YOff'] = Draw.Slider('Offs Y: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (7*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['YOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the Y-Direction if Importing Multiple Images') + GUIPARAMS['ZOff'] = Draw.Slider('Offs Z: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (8*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['ZOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the Z-Direction if Importing Multiple Images') + + # Material and Texture Options + BGL.glColor3f(*TextCol) + BGL.glRecti(minx+lP, maxy - (9*lineheight), maxx-rP, maxy - (9*lineheight) + 1) + BGL.glRasterPos2i(minx + lP, maxy-(9*lineheight) + 3) + Draw.Text('Material and Texture Options', 'small') + + half = (maxx-minx-lP-rP)/2 + GUIPARAMS['CopyMat'] = Draw.Toggle('Copy Existing Material', NO_EVT, minx + lP, maxy-(10*lineheight), half, 19, GUIPARAMS['CopyMat'].val, 'Copy an Existing Material') + if GUIPARAMS['CopyMat'].val: + menStr = compileMaterialList() + GUIPARAMS['MatId'] = Draw.Menu(menStr, NO_EVT, minx + lP, maxy - (11*lineheight), half, 19, GUIPARAMS['MatId'].val, 'Material to Copy Settings From') + else: + GUIPARAMS['MatCol'] = Draw.ColorPicker(NO_EVT, minx+lP, maxy - (13*lineheight), 40, (3*lineheight) - buPad, GUIPARAMS['MatCol'].val, 'Color of Newly Created Material') + GUIPARAMS['Ref'] = Draw.Slider('Ref: ', NO_EVT, minx +lP+45, maxy - (11*lineheight), half-45, 19, GUIPARAMS['Ref'].val, 0.0, 1.0, 0, 'Set the Ref Value for Created Materials') + GUIPARAMS['Spec'] = Draw.Slider('Spec: ', NO_EVT, minx +lP+45, maxy - (12*lineheight), half-45, 19, GUIPARAMS['Spec'].val, 0.0, 2.0, 0, 'Set the Spec Value for Created Materials') + GUIPARAMS['Hard'] = Draw.Slider('Hard: ', NO_EVT, minx +lP+45, maxy - (13*lineheight), half-45, 19, GUIPARAMS['Hard'].val, 1, 500, 0, 'Set the Hardness Value for Created Materials') + GUIPARAMS['Alpha'] = Draw.Slider('A: ', NO_EVT, minx +lP, maxy - (14*lineheight), half, 19, GUIPARAMS['Alpha'].val, 0.0, 1.0, 0, 'Set the Alpha Value for Created Materials') + + GUIPARAMS['ZTransp'] = Draw.Toggle('ZTransparency', NO_EVT, minx + lP, maxy - (15*lineheight), half, 19, GUIPARAMS['ZTransp'].val, 'Enable ZTransparency') + GUIPARAMS['Shadeless'] = Draw.Toggle('Shadeless', NO_EVT, minx + lP, maxy - (16*lineheight), half, 19, GUIPARAMS['Shadeless'].val, 'Enable Shadeless') + + GUIPARAMS['TexChan'] = Draw.Number('Texture Channel: ', NO_EVT, minx + lP+ half + buPad, maxy - (10*lineheight), half-rP, 19, GUIPARAMS['TexChan'].val, 1, 10, 'Texture Channel for Image Texture') + + GUIPARAMS['MPTCol'] = Draw.Toggle('Color', NO_EVT, minx + lP + half + buPad, maxy - (11*lineheight), half/2, 19, GUIPARAMS['MPTCol'].val, 'Map To Color Channel') + GUIPARAMS['MPTAlpha'] = Draw.Toggle('Alpha', NO_EVT, minx + lP + int((1.5)*half) + buPad, maxy - (11*lineheight), half/2 - rP, 19, GUIPARAMS['MPTAlpha'].val, 'Map To Alpha Channel') + + third = int((maxx-minx-lP-rP)/6) + GUIPARAMS['UseAlpha'] = Draw.Toggle('Use Alpha', NO_EVT, minx + lP + half + buPad, maxy - (12*lineheight), third, 19, GUIPARAMS['UseAlpha'].val, "Use the Images' Alpha Values") + GUIPARAMS['CalcAlpha'] = Draw.Toggle('Calc Alpha', NO_EVT, minx + lP + half + third + buPad, maxy - (12*lineheight), third, 19, GUIPARAMS['CalcAlpha'].val, "Calculate Images' Alpha Values") + GUIPARAMS['ExtendMode'] = Draw.Toggle('Extend', NO_EVT, minx+lP+half+third+third+buPad, maxy - (12*lineheight), third-3, 19, GUIPARAMS['ExtendMode'].val, "Use Extend texture mode. If deselected, Repeat is used") + GUIPARAMS['Seq'] = Draw.Toggle('Sequence', NO_EVT, minx + lP + half + buPad, maxy - (13*lineheight), half-rP, 19, GUIPARAMS['Seq'].val, 'Set the Image(s) to use a Sequence instead of a Still') + + if GUIPARAMS['Seq'].val and not PARAMS['ImportType'] == DIR: + GUIPARAMS['AutoRefresh'] = Draw.Toggle('Auto Refresh', NO_EVT, minx + lP + half + buPad, maxy - (14*lineheight), half/2, 19, GUIPARAMS['AutoRefresh'].val, 'Use Auto Refresh') + GUIPARAMS['Cyclic'] = Draw.Toggle('Cyclic', NO_EVT, minx + lP + half + buPad + half/2, maxy - (14*lineheight), half/2 - rP, 19, GUIPARAMS['Cyclic'].val, 'Repeat Frames Cyclically`') + + GUIPARAMS['Frames'] = Draw.Number('Frames: ', NO_EVT, minx +lP + half + buPad, maxy - (15*lineheight), half - rP, 19, GUIPARAMS['Frames'].val, 1, 30000, 'Sets the Number of Images of a Movie to Use') + GUIPARAMS['Offs'] = Draw.Number('Offs: ', NO_EVT, minx +lP + half + buPad, maxy - (16*lineheight), half/2, 19, GUIPARAMS['Offs'].val, -30000, 30000, 'Offsets the Number of the Frame to use in the Animation') + GUIPARAMS['StartFr'] = Draw.Number('StartFr: ', NO_EVT, minx +lP + half + buPad + half/2, maxy - (16*lineheight), half/2 - rP, 19, GUIPARAMS['StartFr'].val, 1, 30000, 'Sets the Global Starting Frame of the Movie') + elif GUIPARAMS['Seq'].val and PARAMS['ImportType'] == DIR: + BGL.glColor3f(*ErrCol) + BGL.glRasterPos2i(minx + lP + half + buPad + 7, maxy-(14 * lineheight) + 5) + Draw.Text('Sequence only available for Single Image Import', 'small') + + # Import Options + BGL.glColor3f(*TextCol) + BGL.glRecti(minx+lP, maxy - (17*lineheight), maxx-rP, maxy - (17*lineheight) + 1) + BGL.glRasterPos2i(minx + lP, maxy-(17*lineheight) + 3) + Draw.Text('Import', 'small') + + if GUIPARAMS['Path'].val and GUIPARAMS['ImageExt'].val or GUIPARAMS['Path'].val and PARAMS['ImportType'] == SINGLE: + Draw.PushButton('Import', DO_SCRIPT, minx + lP, maxy - (18*lineheight), 75, 19, "Import Image(s)") + else: + BGL.glColor3f(*ErrCol) + BGL.glRasterPos2i(minx+lP, maxy - (18*lineheight) + 5) + Draw.Text('A path and image type must be specified to import images') + + GUIPARAMS['RedrawImp'] = Draw.Toggle('Redraw During Import', NO_EVT, maxx - rP - 150, maxy - (18*lineheight), 150, 19, GUIPARAMS['RedrawImp'].val, 'Redraw the View as Images Import') + +Draw.Register(GUI, event, bevent) \ No newline at end of file From 0a17250dca09f04ae850b0fc355620fc7d26c205 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 05:47:14 +0000 Subject: [PATCH 203/444] going out on a limb and removing this without asking anyone. nobody seriously uses this format for graphics these days, and if they did, the export from blender is unlikely be to be useful, its just different views of the mesh edges projected into a 2D xfig file (quantized to int's too). --- release/scripts/xfig_export.py | 234 --------------------------------- 1 file changed, 234 deletions(-) delete mode 100644 release/scripts/xfig_export.py diff --git a/release/scripts/xfig_export.py b/release/scripts/xfig_export.py deleted file mode 100644 index ddc0dd4dcea..00000000000 --- a/release/scripts/xfig_export.py +++ /dev/null @@ -1,234 +0,0 @@ -#!BPY -""" -Name: 'xfig export (.fig)' -Blender: 244 -Group: 'Export' -Tooltip: 'Export selected mesh to xfig Format (.fig)' -""" - -__author__ = 'Dino Ghilardi', 'Campbell Barton AKA Ideasman42' -__url__ = ("blender", "blenderartists.org") -__version__ = "1.1" - -__bpydoc__ = """\ - This script exports the selected mesh to xfig (www.xfig.org) file format (i.e.: .fig) - - The starting point of this script was Anthony D'Agostino's raw triangle format export. - (some code is still here and there, cut'n pasted from his script) - - Usage:
- Select the mesh to be exported and run this script from "File->Export" menu. - The toggle button 'export 3 files' enables the generation of 4 files: one global - and three with the three different views of the object. - This script is licensed under the GPL license. (c) Dino Ghilardi, 2005 - -""" - -# .fig export, mostly brutally cut-n pasted from the -# 'Raw triangle export' (Anthony D'Agostino, http://www.redrival.com/scorpius)| - -import Blender -from Blender import Draw -import BPyObject -#, meshtools -import sys -import bpy -#import time - -# ================================= -# === Write xfig Format.=== -# ================================= - -def collect_edges(edges): - """Gets the max-min coordinates of the mesh""" - - """Getting the extremes of the mesh to be exported""" - - maxX=maxY=maxZ = -1000000000 - minX=minY=minZ = 1000000000 - - FGON= Blender.Mesh.EdgeFlags.FGON - - me = bpy.data.meshes.new() - for ob_base in bpy.data.scenes.active.objects.context: - for ob in BPyObject.getDerivedObjects(ob_base): - me.verts = None - try: me.getFromObject(ob[0]) - except: pass - - if me.edges: - me.transform(ob[1]) - - for ed in me.edges: - if not ed.flag & FGON: - x,y,z = v1 = tuple(ed.v1.co) - maxX = max(maxX, x) - maxY = max(maxY, y) - maxZ = max(maxZ, z) - minX = min(minX, x) - minY = min(minY, y) - minZ = min(minZ, z) - - x,y,z = v2 = tuple(ed.v2.co) - maxX = max(maxX, x) - maxY = max(maxY, y) - maxZ = max(maxZ, z) - minX = min(minX, x) - minY = min(minY, y) - minZ = min(minZ, z) - - edges.append( (v1, v2) ) - - me.verts = None # free memory - return maxX,maxY,maxZ,minX,minY,minZ - -def xfigheader(file): - file.write('#FIG 3.2 Produced by xfig version 3.2.5-alpha5\n') - file.write('Landscape\n') - file.write('Center\n') - file.write('Metric\n') - file.write('A4\n') - file.write('100.00\n') - file.write('Single\n') - file.write('-2\n') - file.write('1200 2\n') - -def figdata(file, edges, expview, bounds, scale, space): - maxX,maxY,maxZ,minX,minY,minZ = bounds - - def xytransform(ed): - """gives the face vertexes coordinates in the xfig format/translation (view xy)""" - x1,y1,z1 = ed[0] - x2,y2,z2 = ed[1] - y1=-y1; y2=-y2 - return x1,y1,z1,x2,y2,z2 - - def xztransform(ed): - """gives the face vertexes coordinates in the xfig format/translation (view xz)""" - x1,y1,z1 = ed[0] - x2,y2,z2 = ed[1] - y1=-y1 - y2=-y2 - - z1=-z1+maxZ-minY +space - z2=-z2+maxZ-minY +space - return x1,y1,z1,x2,y2,z2 - - def yztransform(ed): - """gives the face vertexes coordinates in the xfig format/translation (view xz)""" - x1,y1,z1 = ed[0] - x2,y2,z2 = ed[1] - y1=-y1; y2=-y2 - z1=-(z1-maxZ-maxX-space) - z2=-(z2-maxZ-maxX-space) - return x1,y1,z1,x2,y2,z2 - - def transform(ed, expview, scale): - if expview=='xy': - x1,y1,z1,x2,y2,z2 = xytransform(ed) - return int(x1*scale),int(y1*scale),int(x2*scale),int(y2*scale) - elif expview=='xz': - x1,y1,z1,x2,y2,z2 = xztransform(ed) - return int(x1*scale),int(z1*scale),int(x2*scale),int(z2*scale) - elif expview=='yz': - x1,y1,z1,x2,y2,z2 = yztransform(ed) - return int(z1*scale),int(y1*scale),int(z2*scale),int(y2*scale) - - - """Prints all the xfig data (no header)""" - for ed in edges: - file.write('2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n') - file.write('\t %i %i %i %i\n' % transform(ed, expview, scale)) - -def writexy(edges, bounds, filename, scale, space): - """writes the x-y view file exported""" - - file = open(filename, 'wb') - xfigheader(file) - figdata(file, edges, 'xy', bounds, scale, space) - file.close() - print 'Successfully exported ', Blender.sys.basename(filename)# + seconds - -def writexz(edges, bounds, filename, scale, space): - """writes the x-z view file exported""" - #start = time.clock() - file = open(filename, 'wb') - xfigheader(file) - figdata(file, edges, 'xz', bounds, scale, space) - file.close() - print 'Successfully exported ', Blender.sys.basename(filename)# + seconds - -def writeyz(edges, bounds, filename, scale, space): - """writes the y-z view file exported""" - - #start = time.clock() - file = open(filename, 'wb') - xfigheader(file) - figdata(file, edges, 'yz', bounds, scale, space) - file.close() - #end = time.clock() - #seconds = " in %.2f %s" % (end-start, "seconds") - print 'Successfully exported ', Blender.sys.basename(filename)# + seconds - -def writeall(edges, bounds, filename, scale=450, space=2.0): - """writes all 3 views - - Every view is a combined object in the resulting xfig. file.""" - - maxX,maxY,maxZ,minX,minY,minZ = bounds - - file = open(filename, 'wb') - - xfigheader(file) - file.write('#upper view (7)\n') - file.write('6 % i % i % i % i ') - file.write('%.6f %.6f %.6f %.6f\n' % (minX, minY, maxX, maxY)) - - figdata(file, edges, 'xy', bounds, scale, space) - file.write('-6\n') - file.write('#bottom view (1)\n') - file.write('6 %i %i %i %i ') - file.write('%.6f %.6f %.6f %.6f\n' % (minX, -minZ+maxZ-minY +space, maxX,-maxZ+maxZ-minY +space)) - - figdata(file, edges, 'xz', bounds, scale, space) - file.write('-6\n') - - file.write('#right view (3)\n') - file.write('6 %i %i %i %i ') - file.write('%.6f %.6f %.6f %.6f\n' % (minX, -minZ+maxZ-minY +space, maxX,-maxZ+maxZ-minY +space)) - figdata(file, edges, 'yz', bounds, scale, space) - file.write('-6\n') - - file.close() - print 'Successfully exported ', Blender.sys.basename(filename)# + seconds - -import BPyMessages - -def write_ui(filename): - if filename.lower().endswith('.fig'): filename = filename[:-4] - - PREF_SEP= Draw.Create(0) - PREF_SCALE= Draw.Create(1200) - PREF_SPACE= Draw.Create(2.0) - - block = [\ - ("Separate Files", PREF_SEP, "Export each view axis as a seperate file"),\ - ("Space: ", PREF_SPACE, 0.0, 10.0, "Space between views in blender units"),\ - ("Scale: ", PREF_SCALE, 10, 100000, "Scale, 1200 is a good default")] - - if not Draw.PupBlock("Export FIG", block): - return - - edges = [] - bounds = collect_edges(edges) - - if PREF_SEP.val: - writexy(edges, bounds, filename + '_XY.fig', PREF_SCALE.val, PREF_SPACE.val) - writexz(edges, bounds, filename + '_XZ.fig', PREF_SCALE.val, PREF_SPACE.val) - writeyz(edges, bounds, filename + '_YZ.fig', PREF_SCALE.val, PREF_SPACE.val) - - writeall(edges, bounds, filename + '.fig', PREF_SCALE.val, PREF_SPACE.val) - -if __name__ == '__main__': - Blender.Window.FileSelector(write_ui, 'Export XFIG', Blender.sys.makename(ext='.fig')) - \ No newline at end of file From 99849b659da72f11d2926150a3d0fdde72897aa4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 11 May 2009 12:06:53 +0000 Subject: [PATCH 204/444] Fix for bug #18683: GLSL refresh issue when adding lamp. There's still cases where this goes wrong, as noted in the release logs, this is just a temporary fix, in 2.5 can solve it properly with notifiers. --- source/blender/src/editobject.c | 1 + source/blender/src/previewrender.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 2f127f9a3ec..b6b6c3c8df9 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -216,6 +216,7 @@ void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff else if(type==OB_LAMP) { BIF_undo_push("Add Lamp"); reshadeall_displist(); /* only frees */ + BIF_preview_changed(ID_LA); } else if(type==OB_LATTICE) BIF_undo_push("Add Lattice"); else if(type==OB_CAMERA) BIF_undo_push("Add Camera"); diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 8dfa32d48c8..21be4b2cf49 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -243,6 +243,13 @@ void BIF_preview_changed(short id_code) allqueue(REDRAWVIEW3D, 0); } } + + for(ma=G.main->mat.first; ma; ma=ma->id.next) { + if(ma->gpumaterial.first) { + GPU_material_free(ma); + allqueue(REDRAWVIEW3D, 0); + } + } } else if(OBACT) { Object *ob = OBACT; From 7002faac31d1afb845f8d930962ccd426153b79d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 12:38:24 +0000 Subject: [PATCH 205/444] Another Noise Tool svn commit is complaining about mixed line endings so after 16 attempts I wont include the full message --- release/scripts/wizard_landscape_ant.py | 2148 +++++++++++++++++++++++ 1 file changed, 2148 insertions(+) create mode 100644 release/scripts/wizard_landscape_ant.py diff --git a/release/scripts/wizard_landscape_ant.py b/release/scripts/wizard_landscape_ant.py new file mode 100644 index 00000000000..405c06432ca --- /dev/null +++ b/release/scripts/wizard_landscape_ant.py @@ -0,0 +1,2148 @@ +#!BPY +""" +Name: 'Landscape Generator (A.N.T)' +Blender: 248 +Group: 'Wizards' +Tip: 'Create landscape mesh.' +""" + +__author__ = "Jimmy Hazevoet" +__url__ = ('http://wiki.blender.org/index.php/Scripts/Manual/Wizards/ANTLandscape','elysiun') +__version__ = "v.1.05 03-2007" +__bpydoc__ = """\ + +Another Noise Tool 'Landscape' v.1.05 + +This script uses noise functions to create a terrain from a grid mesh. + +Usage: + +Make new terrain: press the "Add New Grid" button, change some noise settings and press the "Update" button. + +Work on previous made grid: select the grid/terrain in the 3D view, and press the "Assign" button. + +Tip: use a low resolution grid mesh and add some Multires levels for detail + +Note: when using Multires materials can get weird, +only apply materials when your terrain is ready, or not use Multires. + +This Script creates a landscape mesh. +Press the Auto button when you start the script. +Then the Generate Button & read it's tooltip. +The mesh created is average 16000 verts. +To me the mesh appears quite small in the 3d view. +Just Press S in the 3d view to scale it up. +This saves overhead drawing the Mesh. + +Known Issues: +If the mesh is not drawn in the 3d view first time, +Move your mouse to the 3d view, or press the button again. + +Not really an issue, more to be aware. +Due to the complex nature & design of the script, it only creates one mesh at a time. +When you press Generate or Reset, +Even if you have Closed then Opened the script or .blend file, +The mesh Will be Overwritten. +To create Multiple Landscapes you Must Re-Name or save the Mesh +in Blender's F7 menu Links & Materials Panel. + +Readme: +v.1.04: +_ New G.U.I. +_ New noise types like: +Double_Terrain, +StatsByAlt_Terrain, +slickRock, +ditorted_heteroTerrain, +vlNoise_turbulence, +and many more. + +New fractalized Effect functions. +Effect types such as: gradient, +waves and bumps, dome, piramide, +squares, grid, shattered rocks, +lunar, and many more. + +Bias types: Sin, Cos, Tri, Saw, +and Default(no bias). + +For example the 'Rings' effect +with 'Sin Bias' makes 'Rings' +and 'Default Bias' makes 'Dome'. +The Effect 'Mix factor' Slider gives control over how much of the Effect is vissible, +-1.0=noise, 0.0=average, 1.0=effect +this slider controls also the 'Warp amount' if mix type 'Warp' is selected. + +Image effect: mix image with noise +_ IPOCurve Filter: use Ipo curve to filter terrain height. +I know it's a bit strange to use animation curves for landscape modelling, (actualy i want a curves panel in my G.U.I. but i dont know how to do that) +the downside of this method is that you have this 'Empty' moving around in your scene, so put it on another layer and 'Pin' the Ipo block so that it stays visible. +Usage: +Add one 'Empty' Object to your scene, now add one Loc Key at Frame 1, go to Frame 101 (UpArrow ten times), +move the 'Empty' +100 units in X+ direction and add another Loc Key, open the Ipo Curve Editor Window, rename this IpoBlock if you want, +Copie the first curve to buffer and Paste it in the empty slots (from top to bottom), now you can edit the curves freely. +(use the 'Pin' option to keep the curves visible while other objects are selected) +Set the CurveLength and CurveHeight Button value's according to the length and height of the selected curve. +A curve filter is very versatile when it comes to 'height' filtering. + +_ PreView in UV/Image Editor Window: +The preview image is now rendered as Blender.Image and will be saved to file directory as 'ANTview_size.tga' +you have to select 'ANTview_size.tga' in the UV/Image Editor Window +now it's posible to render and save a large HeightMap image (you can also create nice texture images when the VertCol gradient is enabled), +! If you Change the preview image Size a New Blender.Image object is created. (one for size 256, one for size 512 one for.....) ! + +_ VertexColours: use any image as colour gradient. +This function actualy uses one 'row' of pixels from a image to produce the color gradient, +Make one or more custom gradient images with the Gimp or any other graphics software, the gradients must go from left to right (left is bottom and right is top. +you only need one row of pixels so you can put 10 gradients in a 256*10 image.(higher resolutions like 512*n or 1024*n gives smoother result) +Set Window DrawMode 'Textured' , and set the 'VCol Paint' option in the Materials panel ! + +_ Mesh Tiles: Create large scale terrains. + +_ Vertices Selection: select flat areas. + +_ Keyboard HotKeys: +SPACE = Update mesh. +R = Randomise. +V = Redraw preview. + +_ and more... + +""" + + + + +### +# +# Alt+P to start script. +# +### +# scroll down to see info about updates +## +################################################################################################################ +# Another Noise Tool 'Landscape' +# Jimmy Hazevoet +# license: Do whatever you want with it. +################################################################################################################ + +################################################################################################################ +# v.1.04: +# +# _ New G.U.I. +# _ New noise types like: Double_Terrain, StatsByAlt_Terrain, slickRock, ditorted_heteroTerrain, vlNoise_turbulence, and many more. +# _ New fractalized Effect functions. +# Effect types such as: gradient, waves and bumps, dome, piramide, squares, grid, shattered rocks, lunar, and many more. +# Bias types: Sin, Cos, Tri, Saw, and Default(no bias). +# For example the 'Rings' effect with 'Sin Bias' makes 'Rings' and 'Default Bias' makes 'Dome'. +# _ The Effect 'Mix factor' Slider gives control over how much of the Effect is vissible, -1.0=noise, 0.0=average, 1.0=effect +# this slider controls also the 'Warp amount' if mix type 'Warp' is selected. +# _ Image effect: mix image with noise +# _ IPOCurve Filter: use Ipo curve to filter terrain height. +# I know it's a bit strange to use animation curves for landscape modelling, (actualy i want a curves panel in my G.U.I. but i dont know how to do that) +# the downside of this method is that you have this 'Empty' moving around in your scene, so put it on another layer and 'Pin' the Ipo block so that it stays visible. +# Usage: +# Add one 'Empty' Object to your scene, now add one Loc Key at Frame 1, go to Frame 101 (UpArrow ten times), +# move the 'Empty' +100 units in X+ direction and add another Loc Key, open the Ipo Curve Editor Window, rename this IpoBlock if you want, +# Copie the first curve to buffer and Paste it in the empty slots (from top to bottom), now you can edit the curves freely. +# (use the 'Pin' option to keep the curves visible while other objects are selected) +# Set the CurveLength and CurveHeight Button value's according to the length and height of the selected curve. +# A curve filter is very versatile when it comes to 'height' filtering. +# _ PreView in UV/Image Editor Window: +# The preview image is now rendered as Blender.Image and will be saved to file directory as 'ANTview_size.tga' +# you have to select 'ANTview_size.tga' in the UV/Image Editor Window +# now it's posible to render and save a large HeightMap image (you can also create nice texture images when the VertCol gradient is enabled), +# ! If you Change the preview image Size a New Blender.Image object is created. (one for size 256, one for size 512 one for.....) ! +# _ VertexColours: use any image as colour gradient. +# This function actualy uses one 'row' of pixels from a image to produce the color gradient, +# Make one or more custom gradient images with the Gimp or any other graphics software, the gradients must go from left to right (left is bottom and right is top. +# you only need one row of pixels so you can put 10 gradients in a 256*10 image.(higher resolutions like 512*n or 1024*n gives smoother result) +# Set Window DrawMode 'Textured' , and set the 'VCol Paint' option in the Materials panel ! +# _ Mesh Tiles: Create large scale terrains. +# _ Vertices Selection: select flat areas. +# _ Keyboard HotKeys: +# SPACE = Update mesh. +# R = Randomise. +# V = Redraw preview. +# _ and more... +################################################################################################################ + +################################################################################################################ +# BugFix: Sept./2006 v.1.04a +#----------------------------- +# _Image Effect did not worked well with tiled mesh. Fixed (now use Freq. and Loc. buttons to scale and position image). +# +################################################################################################################ + + +################################################################################################################ +# UPDATE: v.1.05 03-2007 +#--------------------------------------------------------------------------------------------------------------- +# +# _ New: Save and Load function, save your settings to a .ant file. +# __NOTE: when saving/loading settings to/from a file, +# make sure the filename/path is not too long! +# __HOTKEY__ Load from file: L +# __HOTKEY__ Save to file : S +# +# _ New mesh code, uses Mesh instead of NMesh, +# this gives a small speed improvement and alows you to use Multires. +# +# Usage: Select a Grid/Terrain mesh and hit the Assign button, now you can work on it, when ready you assign another. +# +# _ New: 'Musgrave' noise types, 'Random noise' and 'Constant' in 'Effects' section. +# _ New: 'Custom Effect', write custom formulae ( x,y, a,b, from math import *, from Blender.Noise import * ) +# _ New: 'Custom Height Filter', write custom formulae ( x,y, h, a,b, from math import *, from Blender.Noise import * ) +# _ New: 'Change Filter Order', Toggle: OFF = Noise+Effect+Falloff+FILTER / ON = Noise+FILTER+Effect+Falloff +# +# _ If you want to make a tiled terrain, you need to set the coordinates to "WorldSpace" or "Center at Cursor" (in G.U.I.Noise panel), +# create and place the grid meshes. now one by one select, assign and update, you may need to adjust the "EdgeFalloff" size. +# +# WARNING!: when using Multires, materials can get weird (?), so apply materials when your terrain is finnished. +# +############################################################################################################### + + +############################################################################################################### +# +## Execute Script: Alt P +# + + +import Blender +from Blender import * +from math import * +from Blender.Noise import * +from Blender.Draw import * +from Blender.BGL import * +from Blender import Image +import string +from string import strip +import BPyMathutils +from BPyMathutils import genrand +from random import choice +scene = Scene.GetCurrent() + +###--------------------------------------------------------------------------- + +CurVersion = 'A.N.T.Landscape v.1.05' + +##--------------------------------------------------------------------------- +# Customise default settings: ---------------------------------------------- + +# Names: +antfilename = 'Terrain' # Default filename +previewname = Create('') # Default preview Image name +DefaultIpoName = '' # Default Ipo DataBlock name (for height filter) +# G.U.I.: +FullScreen = Create( 0 ) # FullScreen on/off +# gui colors: +ledcolors = [ [1.0,0.498,0.498], [1.0,0.698,0.498], [1.0,0.898,0.498], [0.898,1.0,0.498], [0.698,1.0,0.498], [0.498,1.0,0.498], [0.498,1.0,0.698], [0.498,1.0,0.898], [0.600,0.918,1.0], [0.6,0.757,1.0], [0.6,0.6,1.0], [0.757,0.6,1.0], [0.898,0.498,1.0], [1.0,0.498,0.898] ] +#ledcolor = [ 1.0, 0.5, 0.0 ] +lightgrey = [ 0.76, 0.76, 0.76 ] # gui col. +grey = [ 0.6, 0.6, 0.6 ] # panel col. +background = [ 0.7, 0.7, 0.7, 1.0 ] # background col. +black = [ 0.0, 0.0, 0.0 ] # text col. +white = [ 1.0, 1.0, 1.0 ] +# gui size +size_x = 320 # gui x size +size_y = 280 # gui y size +# tabs +guitabs = [ Create( 1 ), Create( 0 ), Create( 0 ), Create( 0 ), Create( 0 ) ] # gui Tabs +# How long does it take to generate a mesh or image ? +print_time = 0 # 1 = Print time in console. + +# end customise. ---------------------------------------------------------- +##-------------------------------------------------------------------------- +###-------------------------------------------------------------------------- +####-------------------------------------------------------------------------- +##--------------------------------------------------------------------------- + +dirpath=Blender.sys.dirname(Blender.Get('filename')) +fname=dirpath.replace('\\','/')+'/' + antfilename + '.ant' +txtFile = Create( fname ) + +###--------------------------------------------------------------------------- +columns = 10 # gui columns +rows = 13 # gui rows +actob = [] # active object +actme = [] # active mesh +ipoblockname='' +thiscurve=[] +selectedcurve=0 +phi=3.14159265359 +# events +App_Evt = 144 +New_Evt = 166 +SelFile_Evt = 71 +LoadFile_Evt = 72 +SaveFile_Evt = 73 +UseMe_Evt = 74 +No_Evt = 1 +Btn_Evt = 2 +Msh_Evt = 12 +Upd_Evt = 3 +Rndm_Evt = 4 +Load_Evt = 5 +Sel_Evt = 6 +Save_Evt = 7 +Rend_Evt = 8 +End_Evt = 9 +Scrn_Evt = 15 +Im_Evt = 16 +gt0_Evt = 20 +gt1_Evt = 21 +gt2_Evt = 22 +gt3_Evt = 23 +gt4_Evt = 24 +Ipo_Evt = 17 +New_Ipo_Evt=700 + +###--------------------------------------------------------------------------- +# menus +noisetypemenu = "Noise type: %t|multiFractal %x0|ridgedMFractal %x1|hybridMFractal %x2|heteroTerrain %x3|fBm %x4|turbulence %x5|Voronoi turb. %x6|vlNoise turb. %x7|noise %x8|cellNoise %x9|Marble %x10|lava_multiFractal %x11|slopey_noise %x12|duo_multiFractal %x13|distorted_heteroTerrain %x14|slickRock %x15|terra_turbulence %x16|rocky_fBm %x17|StatsByAlt_Terrain %x18|Double_Terrain %x19|Shattered_hTerrain %x20|vlhTerrain %x21" +noisebasismenu = "Basis %t|Blender Original%x0|Original Perlin%x1|Improved Perlin%x2|Voronoi_F1%x3|Voronoi_F2%x4|Voronoi_F3%x5|Voronoi_F4%x6|Voronoi_F2-F1%x7|Voronoi Crackle%x8|CellNoise%x9" +voronitypemenu = "Voronoi type %t|Distance %x0|Distance Squared %x1|Manhattan %x2|Chebychev %x3|Minkovsky 1/2 %x4|Minkovsky 4 %x5|Minkovsky %x6" +tBasismodemenu = "Terrain basis mode: %t|noise %x0|ridged noise %x1|vlNoise %x2|ridged vlNoise %x3" +effecttypemenu = ['Effect Type %t','No Effect %x0','Image %x1','Turbulence %x2','vlNoise %x3','Marble %x4', 'multiFractal %x5','ridgedMFractal %x6','hybridMFractal %x7','heteroTerrain %x8','fBm %x9', 'Gradient %x10','Waves and Bumps %x11','ZigZag %x12','Wavy %x13','Sine Bump %x14','Dots %x15','Rings / Dome %x16','Spiral %x17','Square / Piramide %x18','Blocks %x19','Grid %x20','Tech %x21','Crackle %x22','Sparse Cracks %x23','Shattered Rocks %x24','Lunar %x25','Cosine noise %x26','Spike noise %x27','Stone noise %x28','Flat Turb %x29','Flat Voroni %x30','Random noise %x31','Constant %x32','Custom Effect %x33' ] +mixtypemenu = ['Mix Type %t','Effect only %x0','%l','Mix %x1','Add %x2','Subtract %x3','Multiply %x4','Difference %x5','Screen %x6','addmodulo %x7','Minimum %x8','Maximum %x9','%l','Warp Effect %x10','Warp Noise %x11'] +biastypemenu = "Bias %t|Sin bias %x0|Cos bias %x1|Tri bias %x2|Saw bias %x3|Default (no bias)%x4" +sharptypemenu = "Sharpen %t|Soft %x0|Sharp %x1|Sharper %x2" +filtermodemenu = "Filter Mode %t|No Filter %x0| %l|Default Filters %x1|IPOCurve Filter %x2|Custom Filter %x3" +filtertypemenu = "Filter Type %t|Default Terrace %x0|Sharper Terrace %x1|Rounded Terrace %x2|Posterise Mixed %x3|Posterise %x4|Layered Peaks %x5|Peaked %x6|Smooth-thing %x7|Sin bias %x8|Cos bias %x9|Tri bias %x10|Saw bias %x11|Clamp Max. %x12" +falloftypemenu = "Edge Falloff %t|No Edge Falloff %x0| %l|Soft Falloff %x1|Default Falloff %x2|Hard Falloff %x3|Linear Falloff Y %x4|Linear Falloff X %x5|Diagonal Falloff + %x6|Diagonal Falloff - %x7|Square %x8|Round %x9" +randomtypemenu = "Random type: %t|setRandomSeed() : Blender.Noise %x0|Rand() : Blender.Mathutils %x1|genrand() : BPyMathutils MersenneTwister %x2" + +##-------------------------------------------------- +def Set_ReSet_Values(): + global fileinfo, filemessage + global iScale, Offset, Invert, NSize, Sx, Sy, Lx, Ly, WorldSpaceCo + global NType, Basis, musgr, vlnoi, vlnoiTwo, voron, turbOne, turbTwo, marbleOne, marbleTwo, tBasismod, musgrTwo + global CustomFX, effect_image, Effect_Ctrl, Min, Max, Falloff, CustomFilt, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order + global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I, AutoUpd, PreView, DefaultIpoName + + filemessage = '' + fileinfo = '' + effect_image = 'Load and Select image.' + AutoUpd = Create( 0 ) + PreView = [ Create( 0 ), Create( 1.0 ), Create( 0.0 ) ] + ## Coords controls: + WorldSpaceCo = Create(0) + iScale = [ Create( 1.0 ), Create( 1.0 ), Create( 0.25) ] + Offset = [ Create( 0.0 ), Create( 0.0), Create( 0.0) ] + Invert = [ Create( 0 ), Create( 0 ), Create( 0 ) ] + NSize = [ Create( 1.0 ), Create( 2.0 ) ] + Sx = [ Create( 1.0 ), Create( 1.0 ) ] + Sy = [ Create( 1.0 ), Create( 1.0 ) ] + Lx = [ Create( 0.0 ), Create( 0.0 ) ] + Ly = [ Create( 0.0 ), Create( 0.0 ) ] + ## Noise controls: + NType = Create( 3 ) + Basis = [ Create( 0 ), Create( 0 ) ] + musgr = [ Create( 1.0 ), Create( 2.0 ), Create( 8 ), Create( 1.0 ), Create( 1.0 ), Create( 0.5 ) ] + vlnoi = [ Create( 1.0 ), Create( 0 ) ] + vlnoiTwo = [ Create( 1.0 ), Create( 0 ) ] + voron = [ Create( 0 ), Create( 2.5 ) ] + turbOne = [ Create( 6 ), Create( 0 ), Create( 0.5 ), Create( 2.0 ) ] + marbleOne = [ Create( 6 ), Create( 0 ), Create( 2.0 ), Create( 0 ), Create( 0 ), Create( 1.0 ) ] + tBasismod = Create(0) + ## Effect controls: + musgrTwo = [ Create( 1.0 ), Create( 2.0 ), Create( 8 ), Create( 1.0 ), Create( 1.0 ) ] + turbTwo = [ Create( 6 ), Create( 0 ), Create( 0.5 ), Create( 2.0 ) ] + marbleTwo = [ Create( 6 ), Create( 0 ), Create( 2.0 ), Create( 0 ), Create( 0 ), Create( 1.0 ) ] + Effect_Ctrl = [ Create( 0 ),Create( 2 ),Create( 0.0 ),Create( 0 ),Create( 0.0 ) ,Create( 0 ),Create( 2.0 ),Create( 0.5 ),Create( 0.5 ) ] + CustomFX = [ Create('sin(x*pi)'), Create('cos(y*pi)'), Create('abs(a*b)*0.5') ] + ## Filter controls: + Min = Create( 0.0 ) + Max = Create( 1.0 ) + Falloff = [ Create( 2 ), Create( 1.0 ), Create( 1.0 ), Create( 0 ) , Create( 0 ) ] + Filter_Mode = Create( 0 ) + Def_Filter_Ctrl = [ Create( 0 ), Create( 3.0 ) ] + Ipo_Filter_Ctrl = [ Create( DefaultIpoName ), Create( 0 ), Create( 100.0 ), Create( 100.0 ) ] + Filter_Order = Create( 0 ) + CustomFilt = [ Create('sqrt(h*h)**2'), Create('0'), Create('a') ] + ## Randomise noise buttons: + RandMod = Create( 1 ) + RSeed = Create( 0 ) + rand_I = Create( 0 ) + rand_H = Create( 0 ) + rand_S = Create( 0 ) + rand_L = Create( 1 ) + +##------------------------- +Set_ReSet_Values() + + +####---------------------------------------------------------------------------------------------------- +###---------------------------------------------------------------------------------------------------- +## G.U.I.: text,backpanel,panel +#-------------------------------------------------- +def draw_Text( ( x, y ), text, color, size ): + glColor3f( color[0],color[1],color[2] ) + glRasterPos2d(x,y) + txtsize = 'small', 'normal', 'large' + Text( text, txtsize[ size ] ) +def draw_BackPanel( text, x, y, w, h, colors ): + glColor3f( colors[0]*0.76, colors[1]*0.76, colors[2]*0.76 ) + glRecti( x, h, w, h+20 ) + glColor3f( colors[0], colors[1], colors[2] ) + glRecti( x, y, w, h ) + glColor3f( colors[0], colors[1], colors[2] ) + glRasterPos2d( x+10, h+5 ) + Text( text, 'small' ) +def draw_Panel( x, y, w, h, colors ): + glColor3f( colors[0], colors[1], colors[2] ) + glRecti( x,y, w,h ) +def draw_Frame( text, x, y, w, h, color ): + glColor3f( color[0], color[1], color[2] ) + glRasterPos2i(x+3,h-3) + Text(text ,'small') + stringwidth = GetStringWidth( text,'small' ) + glColor3f( color[0], color[1], color[2] ) + glBegin(Blender.BGL.GL_LINE_STRIP) + glVertex2i(x,h) + glVertex2i(x,y) + glVertex2i(w,y) + glVertex2i(w,h) + glVertex2i(x+stringwidth+10,h) + glEnd() +def draw_Led( x, y, colors ): + glColor3f( colors[0], colors[1], colors[2] ) + glRecti( x,y, x+4,y+4 ) + + +###---------------------------------------------------------------------------------------------------- +## G.U.I. Buttons: +#---------------------------------------------------------------------------------------------------- + +###------------------------- +## Main / Mesh Buttons: +# +def MeshButtons( col, row, width, height ): + global actme, actob, AutoUpd, txtFile, filemessage, fileinfo + + PushButton("I", UseMe_Evt, col[8], row[3], width[0], height[1], "Info: Here you can write some text to save with the file." ) + draw_Text( ( col[0], row[1]+5 ), 'Info: ' + fileinfo, black, 0 ) + txtFile = String("", No_Evt, col[0], row[2], width[9], height[1], txtFile.val, 256, "File: Full path and filename" ) + PushButton( "Select", SelFile_Evt, col[1], row[3], width[0], height[1], "File: Open FileBrowser and select *.ant file" ) + PushButton( "Load", LoadFile_Evt,col[2], row[3], width[2], height[1], "File: Load settings from file ( HotKey: L )" ) + PushButton( "Save", SaveFile_Evt,col[5], row[3], width[2], height[1], "File: Save settings to file ( HotKey: S )" ) + + activeobname = '' + if actme !=[]: + activeobname = actob[0].name + draw_Text( ( col[5]+5, row[7]-5 ), 'OB: ' + activeobname, [0.0,0.0,1.0], 1 ) + PushButton( "Add New Grid", New_Evt, col[0], row[6], width[4], height[2] ) + PushButton( "Assign Selected", App_Evt, col[5], row[6], width[4], height[2], 'Assign selected terrain') + +###------------------------- +## Noise Buttons: +# +def NoiseButtons( col, row, width, height ): + global NSize, iScale, Offset, Invert, Lx, Ly, Sx, Sy, WorldSpaceCo + global Ha, La, Oc, Of, Ga, Basis, NType, musgr, vlnoi, voron, turbOne, tBasismod + global Depth, Hard, Amp, Freq, vlBasis, Distort, VFunc, VExp, VDep, marbleOne + global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I + + bth = height[1]/2+5 + iScale[0] = Number("iScale:", Btn_Evt, col[5], row[2]+bth, width[3], height[1], iScale[0].val, -10.0, 10.0 , "Noise: Intensity Scale." ) + Invert[0] = Toggle("Inv.", Btn_Evt, col[9], row[2]+bth, width[0], height[1], Invert[0].val, "Noise: Invert") + Offset[0] = Number("Offset:", Btn_Evt, col[5], row[3]+bth, width[4], height[1], Offset[0].val, -10.0, 10.0 , "Noise: Offset " ) + NSize[0] = Number("Noise Size:",Btn_Evt, col[5], row[5], width[4], height[2], NSize[0].val, 0.001, 10.0 , "Noise Size" ) + Sx[0] = Number("Size X:", Btn_Evt, col[5], row[6], width[4], height[1], Sx[0].val, 0.001, 10.0 , "Size X" ) + Sy[0] = Number("Size Y:", Btn_Evt, col[5], row[7], width[4], height[1], Sy[0].val, 0.001, 10.0 , "Size Y" ) + Lx[0] = Number("Loc X:", Btn_Evt, col[5], row[8], width[4], height[1], Lx[0].val, -10000.0, 10000.0 , "Loc X" ) + Ly[0] = Number("Loc Y:", Btn_Evt, col[5], row[9],width[4], height[1], Ly[0].val, -10000.0, 10000.0 , "Loc Y" ) + WorldSpaceCo = Menu( "Coordinates %t|Local Space %x0|World Space %x1|Center at CursorPos %x2", Btn_Evt, col[5], row[10], width[4], height[1], WorldSpaceCo.val, "x,y,z coordinates for noise, effect and height falloff " ) + + NType = Menu( noisetypemenu, Btn_Evt, col[0], row[2], width[4], height[2], NType.val, "Noise type" ) + if NType.val == 6: + voron[0] = Menu( voronitypemenu, Btn_Evt, col[0], row[3], width[4], height[1], voron[0].val, "Voronoi type" ) + else: + if NType.val != 9: + Basis[0] = Menu( noisebasismenu, Btn_Evt, col[0], row[3], width[4], height[1], Basis[0].val, "Noise Basis" ) + + if NType.val in [0,1,2,3,4,11,12,13,14,15,17,18,19,20,21]: + musgr[0] = Slider( "H: ", Btn_Evt, col[0], row[5], width[4], height[1], musgr[0].val, 0.0, 3.0, 0 , "H" ) + musgr[1] = Slider( "Lacu: ", Btn_Evt, col[0], row[6], width[4], height[1], musgr[1].val, 0.0, 6.0, 0 , "Lacunarity" ) + musgr[2] = Slider( "Octs: ", Btn_Evt, col[0], row[4], width[4], height[1], musgr[2].val, 0, 12, 0 , "Octaves" ) + if NType.val in [1,2,3,13,14,15,18,19,20,21]: + musgr[3] = Slider( "Offst: ", Btn_Evt, col[0], row[7], width[4], height[1], musgr[3].val, 0.0, 6.0, 0 , "Offset" ) + if NType.val in [1,2,13,15,18]: + musgr[4] = Slider( "Gain: ", Btn_Evt, col[0], row[8], width[4], height[1], musgr[4].val, 0.0, 6.0, 0 , "Gain" ) + if NType.val == 19: + musgr[5] = Slider( "Thresh: ", Btn_Evt, col[0], row[8], width[4], height[1], musgr[5].val, 0.001, 2.0, 0 , "Threshold" ) + if NType.val in [5,6,7,16]: + turbOne[0] = Number( "Depth:", Btn_Evt, col[0], row[4], width[4], height[1], turbOne[0].val, 0, 12, "Octaves") + turbOne[1] = Toggle( "Hard noise", Btn_Evt, col[0], row[5], width[4], height[1], turbOne[1].val, "Soft noise / Hard noise") + turbOne[2] = Slider( "Amp:", Btn_Evt, col[0], row[6], width[4], height[1], turbOne[2].val, 0.0, 3.0, 0, "Ampscale ") + turbOne[3] = Slider( "Freq:", Btn_Evt, col[0], row[7], width[4], height[1], turbOne[3].val, 0.0, 6.0, 0, "Freqscale") + if NType.val in [18,19]: + tBasismod = Menu( tBasismodemenu, Btn_Evt, col[0], row[9], width[4], height[1], tBasismod.val, "Terrain basis mode.") + if NType.val == 6: + if voron[0].val == 6: + voron[1] = Slider( "Exp: ", Btn_Evt, col[0], row[8], width[4], height[1], voron[1].val, 0.0,10.0, 0, "Minkovsky exponent") + if NType.val in [7,11,12,14,20,21]: + vlnoi[0] = Slider( "Dist: ", Btn_Evt, col[0], row[8], width[4], height[1], vlnoi[0].val, 0.0, 10.0, 0 , "Distort" ) + if NType.val in [7,13,14,15,21]: + vlnoi[1] = Menu(noisebasismenu, Btn_Evt, col[0], row[9], width[4], height[1], vlnoi[1].val, "Distortion Noise") + if NType.val == 10: + marbleOne[0] = Number( "Depth: ", Btn_Evt, col[0], row[6], width[4], height[1], marbleOne[0].val, 0, 12, "Octaves") + marbleOne[2] = Slider( "Turb: ", Btn_Evt, col[0], row[7], width[4], height[1], marbleOne[2].val, 0.0,20.0, 0, "Turbulence ") + marbleOne[3] = Menu( biastypemenu, Btn_Evt ,col[0], row[4], width[4], height[1], marbleOne[3].val, "Bias") + marbleOne[5] = Slider("ReScale: ", Btn_Evt, col[0], row[8], width[4], height[1], marbleOne[5].val, 0.0,20.0, 0, "ReScale") + if marbleOne[3].val != 4: + marbleOne[4] = Menu(sharptypemenu, Btn_Evt ,col[0], row[5], width[4], height[1], marbleOne[4].val, "Sharpen") + + RandMod = Menu( randomtypemenu, No_Evt, col[0], row[10], width[0], height[1], RandMod.val, "Random Type" ) + rand_H = Toggle("TH",No_Evt ,col[1], row[10], width[0], height[1], rand_H.val, "Randomise Terrain Height ( in Height panel )") + rand_I = Toggle("NH",No_Evt ,col[2], row[10], width[0], height[1], rand_I.val, "Randomise Noise Height") + rand_S = Toggle("NS",No_Evt ,col[3], row[10], width[0], height[1], rand_S.val, "Randomise Noise Size") + rand_L = Toggle("NL",No_Evt ,col[4], row[10], width[0], height[1], rand_L.val, "Randomise Noise Location") + +###------------------------- +## Effect Buttons: +# +def EffectButtons( col, row, width, height ): + global Effect_Type, Effect_Ctrl, Blend_Effect, CustomFX + global NSize, iScale, Offset, Invert, Lx, Ly, Sx, Sy + global BasisTwo, turbTwo, marbleTwo, vlnoiTwo, musgrTwo + + Effect_Ctrl[0] = Menu( '|'.join( effecttypemenu ), Btn_Evt, col[0], row[2], width[4], height[2], Effect_Ctrl[0].val, "Effect: Type" ) + if Effect_Ctrl[0].val != 0: + Effect_Ctrl[1] = Menu( '|'.join( mixtypemenu ), Btn_Evt, col[5], row[2], width[4], height[2], Effect_Ctrl[1].val, "Mix: Type" ) + if Effect_Ctrl[1].val in [10,11]: + Effect_Ctrl[2] = Slider("Warp: ", Btn_Evt, col[5], row[3], width[4], height[1], Effect_Ctrl[2].val, -1.0, 1.0, 0, "Mix factor / Warp amount" ) + else: Effect_Ctrl[2] = Slider("Mix: ",Btn_Evt, col[5], row[3], width[4], height[1], Effect_Ctrl[2].val, -1.0, 1.0, 0, "Mix factor / Warp amount" ) + + iScale[1] = Number("iScale:", Btn_Evt, col[5], row[4], width[3], height[1], iScale[1].val, -20.0, 20.0 , "Effect: Intensity Scale " ) + Invert[1] = Toggle("Inv.", Btn_Evt, col[9], row[4], width[0], height[1], Invert[1].val, "Effect: Invert") + Offset[1] = Number("Offset:", Btn_Evt, col[5], row[5], width[4], height[1], Offset[1].val, -20.0, 20.0 , "Effect: Offset " ) + NSize[1] = Number("Frequency:",Btn_Evt, col[5], row[6], width[4], height[1], NSize[1].val, 0.001, 100.0, "Effect Frequency ( Scale )" ) + Sx[1] = Number("Freq X:", Btn_Evt, col[5], row[7], width[4], height[1], Sx[1].val, -50.0, 50.0 , "Effect Frequency X ( ScaleX )" ) + Sy[1] = Number("Freq Y:", Btn_Evt, col[5], row[8], width[4], height[1], Sy[1].val, -50.0, 50.0 , "Effect Frequency Y ( ScaleY )" ) + Lx[1] = Number("Loc X:", Btn_Evt, col[5], row[9], width[4], height[1], Lx[1].val, -1000.0, 1000.0 , "Effect Loc X" ) + Ly[1] = Number("Loc Y:", Btn_Evt, col[5], row[10], width[4], height[1], Ly[1].val, -1000.0, 1000.0 , "Effect Loc Y" ) + + if Effect_Ctrl[0].val == 1: + PushButton("Load Image", Load_Evt, col[0], row[4], width[4], height[2] , "Load Image") + PushButton("Select Image", Sel_Evt, col[0], row[6], width[4], height[3] , "Select Image") + draw_Text( ( col[0]+5, row[7] ), effect_image, black, 1 ) + + if Effect_Ctrl[0].val in [2,3,4,5,6,7,8,9]: + Basis[1] = Menu( noisebasismenu, Btn_Evt, col[0], row[3], width[4], height[1], Basis[1].val, "Basis" ) + + if Effect_Ctrl[0].val == 2: + turbTwo[0] = Number( "Depth:", Btn_Evt, col[0], row[4], width[4], height[1], turbTwo[0].val, 1, 12, "Octaves") + turbTwo[1] = Toggle("Hard noise", Btn_Evt, col[0], row[5], width[4], height[1], turbTwo[1].val, "Hard noise") + turbTwo[2] = Slider( "Amp:", Btn_Evt, col[0], row[6], width[4], height[1], turbTwo[2].val, 0.0, 3.0, 0, "Ampscale ") + turbTwo[3] = Slider( "Freq:", Btn_Evt, col[0], row[7], width[4], height[1], turbTwo[3].val, 0.0, 6.0, 0, "Freqscale") + if Effect_Ctrl[0].val == 3: + vlnoiTwo[1] = Menu(noisebasismenu, Btn_Evt, col[0], row[4], width[4], height[1], vlnoiTwo[1].val, "Distortion Noise") + vlnoiTwo[0] = Slider( "Dist: ", Btn_Evt, col[0], row[5], width[4], height[1], vlnoiTwo[0].val, 0.0, 10.0, 0 , "Distort" ) + if Effect_Ctrl[0].val == 4: + marbleTwo[0] = Number( "Depth: ", Btn_Evt, col[0], row[6], width[4], height[1], marbleTwo[0].val, 1, 12, "Octaves") + marbleTwo[2] = Slider( "Turb: ", Btn_Evt, col[0], row[7], width[4], height[1], marbleTwo[2].val, 0.0,20.0, 0, "Turbulence") + marbleTwo[3] = Menu( biastypemenu, Btn_Evt ,col[0], row[4], width[4], height[1], marbleTwo[3].val, "Bias") + marbleTwo[5] = Slider("ReScale: ", Btn_Evt, col[0], row[8], width[4], height[1], marbleTwo[5].val, 0.0,20.0, 0, "ReScale") + if marbleTwo[3].val != 4: + marbleTwo[4] = Menu(sharptypemenu,Btn_Evt ,col[0], row[5], width[4], height[1], marbleTwo[4].val, "Sharpen") + + if Effect_Ctrl[0].val in [5,6,7,8,9]: + musgrTwo[0] = Slider( "H: ", Btn_Evt, col[0], row[5], width[4], height[1], musgrTwo[0].val, 0.0, 3.0, 0 , "H" ) + musgrTwo[1] = Slider( "Lacu: ", Btn_Evt, col[0], row[6], width[4], height[1], musgrTwo[1].val, 0.0, 6.0, 0 , "Lacunarity" ) + musgrTwo[2] = Slider( "Octs: ", Btn_Evt, col[0], row[4], width[4], height[1], musgrTwo[2].val, 0, 12, 0 , "Octaves" ) + if Effect_Ctrl[0].val in [6,7,8]: + musgrTwo[3] = Slider( "Offst: ", Btn_Evt, col[0], row[7], width[4], height[1], musgrTwo[3].val, 0.0, 6.0, 0 , "Offset" ) + if Effect_Ctrl[0].val in [6,7]: + musgrTwo[4] = Slider( "Gain: ", Btn_Evt, col[0], row[8], width[4], height[1], musgrTwo[4].val, 0.0, 6.0, 0 , "Gain" ) + + if Effect_Ctrl[0].val > 9 and Effect_Ctrl[0].val < 31: + Effect_Ctrl[5] = Number("Depth:", Btn_Evt, col[0], row[4], width[4], height[1], Effect_Ctrl[5].val, 0, 12 , "Fractalize Effect: Octaves" ) + Effect_Ctrl[4] = Number("Distort:",Btn_Evt, col[0], row[7], width[4], height[1], Effect_Ctrl[4].val, 0.0, 50.0 , "Distort Effect: Amount" ) + Effect_Ctrl[6] = Slider("Freq:", Btn_Evt, col[0], row[5], width[4], height[1], Effect_Ctrl[6].val, 0.0, 6.0, 0, "Fractalize Effect: Frequency" ) + Effect_Ctrl[7] = Slider("Amp:", Btn_Evt, col[0], row[6], width[4], height[1], Effect_Ctrl[7].val, 0.0, 3.0, 0, "Fractalize Effect: Amplitude" ) + if Effect_Ctrl[0].val < 22: + Effect_Ctrl[3] = Menu(biastypemenu, Btn_Evt ,col[0], row[3], width[4], height[1], Effect_Ctrl[3].val, "Effect bias") + if Effect_Ctrl[0].val in [31,32]: + Effect_Ctrl[8] = Number("Amount:", Btn_Evt, col[0], row[4], width[4], height[1], Effect_Ctrl[8].val, -20.0, 20.0, "Effect: Amount" ) + if Effect_Ctrl[0].val == 33: + draw_Text( ( col[0]+5, row[4] ), 'Custom math ( h, x,y, a,b )' , black, 0 ) + CustomFX[0] = String( "a = ", Btn_Evt, col[0], row[5], width[4], height[1] ,CustomFX[0].val,96, "a" ) + CustomFX[1] = String( "b = ", Btn_Evt, col[0], row[6], width[4], height[1] ,CustomFX[1].val,96, "b" ) + CustomFX[2] = String( "result = ", Btn_Evt, col[0], row[7], width[4], height[1] ,CustomFX[2].val,96, "result" ) + +###------------------------- +## Filter / Height Buttons: +# +def FilterButtons( col, row, width, height ): + global iScale, Offset, Invert, Min, Max, Falloff, CustomFilt + global Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, DefaultIpoName, Filter_Order + + iScale[2] = Number("Height:", Btn_Evt, col[5], row[2], width[3], height[2], iScale[2].val, -10.0, 10.0 , "Terrain Height: Scale" ) + Invert[2] = Toggle("Inv.", Btn_Evt, col[9], row[2], width[0], height[2], Invert[2].val, "Terrain Height: Invert") + Offset[2] = Number("Offset:", Btn_Evt, col[5], row[3], width[4], height[1], Offset[2].val, -10.0, 10.0 , "Terrain Height: Offset" ) + Max = Number( "Plateau:", Btn_Evt, col[5], row[5], width[4], height[1], Max.val, Min.val, 1.0 , "Terrain Height: Clamp Max. ( Plateau )" ) + Min = Number( "Sealevel:", Btn_Evt, col[5], row[6], width[4], height[1], Min.val, -1.0, Max.val , "Terrain Height: Clamp Min. ( Sealevel )" ) + Falloff[0] = Menu( falloftypemenu, Btn_Evt ,col[5], row[9], width[4], height[2], Falloff[0].val, "Terrain Height: Edge falloff") + if Falloff[0].val !=0: + Falloff[1] = Number("X:", Btn_Evt, col[5], row[10], width[1], height[1], Falloff[1].val , 0.01, 100.0 , "Edge falloff: X Size" ) + Falloff[2] = Number("Y:", Btn_Evt, col[8], row[10], width[1], height[1], Falloff[2].val , 0.01, 100.0 , "Edge falloff: Y Size" ) + Falloff[4] = Toggle("Inv.", Btn_Evt, col[7], row[10], width[0], height[1], Falloff[4].val, "Edge falloff: Invert") + Falloff[3] = Toggle("Edge At Sealevel", Btn_Evt, col[5], row[7], width[4], height[1], Falloff[3].val, "Edge falloff: Edge at Sealevel") + + Filter_Mode = Menu( filtermodemenu, No_Evt, col[0], row[2], width[4], height[2], Filter_Mode.val, "Filter: Mode") + if Filter_Mode.val ==1: + Def_Filter_Ctrl[0] = Menu( filtertypemenu, Btn_Evt, col[0], row[5], width[4], height[2], Def_Filter_Ctrl[0].val, "Filter: Type") + Def_Filter_Ctrl[1] = Number("Amount: ", Btn_Evt, col[0], row[6], width[4], height[1], Def_Filter_Ctrl[1].val, 0.1, 100.0 , "Filter: Amount" ) + + if Filter_Mode.val ==2: + Ipo_Filter_Ctrl[0] = String("IP:", Ipo_Evt, col[0], row[5], width[4], height[2], Ipo_Filter_Ctrl[0].val,20, "Ipo datablock name" ) + if Ipo_Filter_Ctrl[0].val !='': + Ipo_Filter_Ctrl[1] = Number("Use This Curve:",Ipo_Evt, col[0], row[7], width[4], height[3], Ipo_Filter_Ctrl[1].val, 0, 29, "Select curve to use" ) + Ipo_Filter_Ctrl[2] = Number("Curve Length:", Ipo_Evt, col[0], row[8], width[4], height[1], Ipo_Filter_Ctrl[2].val, 0.0, 1000.0, "X: Length (number of frames) of the selected curve." ) + Ipo_Filter_Ctrl[3] = Number("Curve Height:", Ipo_Evt, col[0], row[9], width[4], height[1], Ipo_Filter_Ctrl[3].val, 0.0, 1000.0, "Y: Height (offset) of the selected curve." ) + else: + draw_Text( ( col[0]+5, row[6] ), 'Enter Ipo DataBlock name,' , black, 0 ) + draw_Text( ( col[0]+5, row[9] ), 'or else:' , black, 0 ) + PushButton( "New IpoDataBlock/Object", New_Ipo_Evt, col[0], row[10], width[4], height[1], "Creates new Ipo Object(Empty), and Ipo DataBlock(curves)' to use as height filter") + + if Filter_Mode.val ==3: + draw_Text( ( col[0]+5, row[4] ), 'Custom math ( h, x,y, a,b )' , black, 0 ) + CustomFilt[0] = String( "a = ", Btn_Evt, col[0], row[5], width[4], height[1] ,CustomFilt[0].val,96, "a" ) + CustomFilt[1] = String( "b = ", Btn_Evt, col[0], row[6], width[4], height[1] ,CustomFilt[1].val,96, "b" ) + CustomFilt[2] = String( "result = ", Btn_Evt, col[0], row[7], width[4], height[1] ,CustomFilt[2].val,96, "result" ) + if Filter_Mode.val !=0: + Filter_Order = Toggle("Change Filter Order", Btn_Evt, col[0], row[3], width[4], height[1], Filter_Order.val, "Filter Order: OFF = Noise+Effect+Falloff+FILTER / ON = Noise+FILTER+Effect+Falloff.") + +###------------------------- +## Option / Generate Image Buttons: +# +def OptionButtons( col, row, width, height ): + global PreView, previewname + + PreView[0] = Toggle("Make Image", No_Evt, col[0], row[2], width[4], height[2], PreView[0].val, "Image: On/Off (Make a new Image in UV/ImageEditor Window, and give a name to it)") + if PreView[0].val !=0: + previewname = String( "IM:", No_Evt, col[0], row[3], width[4], height[1] ,previewname.val, 16, "IM:Name, Render terrain height to this image" ) + PreView[1] = Number("", Im_Evt, col[0], row[4], width[1], height[1], PreView[1].val, 0.0, 10.0, "Image: Intensity Scale") + PreView[2] = Number("", Im_Evt, col[3], row[4], width[1], height[1], PreView[2].val,-10.0, 10.0, "Image: Offset") + PushButton( "Draw Image", Im_Evt, col[0], row[5], width[4], height[1] , "Image: Update image ( KEY: V )") + draw_Text( ( col[5], row[1] ), 'Create yourself a new image', black, 0 ) + draw_Text( ( col[5], row[2] ), 'in UV/Image Editor Window,', black, 0 ) + draw_Text( ( col[5], row[3] ), 'give it a name,', black, 0 ) + draw_Text( ( col[5], row[4] ), 'and save it manualy.', black, 0 ) + +####-------------------------------------------------------------------------- +###-------------------------------------------------------------------------- +## Draw G.U.I. ------------------------------------------------------------- +#-------------------------------------------------------------------------- +def drawgui(): + global guitabs, ledcolor, FullScreen, AutoUpd, RandMod, RSeed, filemessage + global Effect_Ctrl, Filter_Mode, Falloff, PreView, rand_H, rand_S, rand_L, rand_I + + glClearColor(background[0],background[1],background[2],background[3]) + glClear(GL_COLOR_BUFFER_BIT) + scissorbox=Buffer(GL_FLOAT,4) + glGetFloatv(GL_SCISSOR_BOX,scissorbox) + scissbleft=int(scissorbox[0]) + scissbbase=int(scissorbox[1]) + scissbwidth=int(scissorbox[2]) + scissbheight=int(scissorbox[3]) + xstart = 5 + ystart = 5 + xgap = 5 + ygap = 5 + if FullScreen.val==1: + guiwidth = scissbwidth-10 + guiheight = scissbheight-25 + if guiwidth < size_x/2: + guiwidth = size_x/2 + if guiheight < size_y/2: + guiheight = size_y/2 + else: + guiwidth = size_x + guiheight = size_y + col,row = [],[] + xpart = ( ( guiwidth-xstart ) / columns ) + ypart = ( ( guiheight-ystart ) / rows ) + width = [] + for c in xrange( columns ): + col.append( xgap + xpart * c + xstart ) + width.append( xpart*(c+1)-xgap ) + height = [ (ypart-ygap)/2 , ypart-ygap, (ypart*3-ygap)/2, ypart*2-ygap, (ypart*5-ygap)/2 ] + for r in xrange( rows ): + row.append( ygap + ypart * r + ystart ) + row.reverse() + + ###------------------------- + ## Draw G.U.I.: + draw_BackPanel( 'Another Noise Tool 1.05', xstart, ystart, guiwidth, guiheight + ygap, lightgrey ) + + FullScreen = Toggle("", Scrn_Evt, guiwidth-32, guiheight+ygap+3, 15, 15, FullScreen.val ,"FullScreen" ) + PushButton( "X", End_Evt, guiwidth-16, guiheight+ygap+3, 15, 15, "Exit" ) + draw_Text(( guiwidth-(guiwidth/2)-width[0], guiheight+ygap+5 ), filemessage, white, 0 ) + + # gui tabs + guitabs[0] = Toggle("Main", gt0_Evt, col[0], row[0], width[1], height[1], guitabs[0].val ,"Main / Mesh settings" ) + guitabs[1] = Toggle("Noise", gt1_Evt, col[2], row[0], width[1], height[1], guitabs[1].val ,"Noise settings" ) + guitabs[2] = Toggle("Effect", gt2_Evt, col[4], row[0], width[1], height[1], guitabs[2].val ,"Add Effect" ) + guitabs[3] = Toggle("Height", gt3_Evt, col[6], row[0], width[1], height[1], guitabs[3].val ,"Height Filter" ) + guitabs[4] = Toggle("Options", gt4_Evt, col[8], row[0], width[1], height[1], guitabs[4].val ,"Options" ) + + if guitabs[0].val !=0: MeshButtons( col, row, width, height ) + elif guitabs[1].val !=0: NoiseButtons( col, row, width, height ) + elif guitabs[2].val !=0: EffectButtons( col, row, width, height ) + elif guitabs[3].val !=0: FilterButtons( col, row, width, height ) + elif guitabs[4].val !=0: OptionButtons( col, row, width, height ) + else: # some info + draw_Panel( col[0], row[0]-5, col[9]+width[0], row[10]-10, black ) + draw_Text( ( col[0]+5, row[1] ), 'Another Noise Tool v.1.05', ledcolors[0], 2 ) + draw_Text( ( col[0]+5, row[2] ), 'by: Jimmy Hazevoet, 01/2005-03/2007', ledcolors[1], 2 ) + draw_Text( ( col[0]+5, row[3] ), 'v.1.05: build/tested in: Blender 2.43 (Wndws)', ledcolors[2], 1 ) + draw_Text( ( col[0]+5, row[4] ), 'HotKeys: ----------------------------', ledcolors[3], 2 ) + draw_Text( ( col[0]+5, row[5] ), 'Space = Update mesh', ledcolors[4], 2 ) + draw_Text( ( col[0]+5, row[6] ), 'V = Update Image', ledcolors[5], 2 ) + draw_Text( ( col[0]+5, row[7] ), 'R = Randomise', ledcolors[6], 2 ) + draw_Text( ( col[0]+5, row[8] ), 'L = Load from file', ledcolors[7], 2 ) + draw_Text( ( col[0]+5, row[9] ), 'S = Save to file', ledcolors[8], 2 ) + draw_Text( ( col[0]+5, row[10] ),'Q = Quit', ledcolors[9], 2 ) + + # auto/generate/randomise buttons + rand_on_off = 0 + if rand_H.val !=0: rand_on_off = 1 + elif rand_I.val !=0: rand_on_off = 1 + elif rand_S.val !=0: rand_on_off = 1 + elif rand_L.val !=0: rand_on_off = 1 + else: rand_on_off = 0 + if rand_on_off != 0: + if RandMod.val in [1,2]: + PushButton( "Randomise", Rndm_Evt, col[2], row[12], width[2], height[2] , "Randomise Noise ( KEY: R )") + else: RSeed = Number("Seed: ", Rndm_Evt, col[2], row[12], width[2], height[2], RSeed.val, 0, 255 , "Random Seed: If seed = 0, the current time will be used as seed." ) + AutoUpd = Toggle("Auto", No_Evt, col[0], row[12], width[1], height[2], AutoUpd.val ,"Automatic update" ) + PushButton("Update", Upd_Evt, col[5], row[12], width[4], height[2] , "Generate / Update. ( KEY: SPACE )") + else: + AutoUpd = Toggle("Auto", No_Evt, col[0], row[12], width[1], height[2], AutoUpd.val ,"Automatic update" ) + PushButton("Update", Upd_Evt, col[2], row[12], width[7], height[2] , "Generate / Update. ( KEY: SPACE )") + ####--------------------------------------------------------------------------- + +###--------------------------------------------------------------------------- +##--------------------------------------------------------------------------- +# Key Events: + +def events(evt, val): + global PreView, txtFile, AutoUpd, PreView + + ## hotkey: Q = Quit + if (evt == QKEY and not val): + name = "Quit ?%t|No %x0|Yes %x1" + result = Blender.Draw.PupMenu(name) + if result==1: + Exit() + + ## hotkey: Space = Generate/Update terrain + if (evt == SPACEKEY and not val): + do_it() + + ## hotkey: R = Randomise noise + if (evt in [ RKEY ] and not val): + if AutoUpd.val != 0: + do_it_random() + else: + randomiseNoise() + Draw() + + ## hotkey: V = Update image + if PreView[0].val != 0: + if (evt in [ VKEY, RKEY ] and not val): + do_it_preview() + + ## hotkey: L = Load from file + if (evt == LKEY and not val): + loadmenu = "Load file ?%t|" + txtFile.val + loadresult = Blender.Draw.PupMenu(loadmenu) + if loadresult==1: + LoadPreset(txtFile.val) + if AutoUpd.val != 0: + do_it() + else: Draw() + + ## hotkey: S = Save to file + if (evt == SKEY and not val): + savemenu = "Save file ?%t|" + txtFile.val + saveresult = Blender.Draw.PupMenu(savemenu) + if saveresult==1: + SavePreset(txtFile.val) + Draw() + +###--------------------------------------------------------------------------- +##--------------------------------------------------------------------------- +# Button events: + +def bevents(evt): + global txtFile, effect_image, PreView, fileinfo, filemessage + global Filter_Mode, Ipo_Filter_Ctrl, iponame, thiscurve, selectedcurve + global antfilename, terrainname + global actob, actme + + # quit/reset event + if (evt == End_Evt ): + name = "OK ?%t|Reset %x1|Quit %x2" + result = Blender.Draw.PupMenu(name) + if result==1: + Set_ReSet_Values() + Draw() + elif result==2: + Exit() + + ## file info string event + if (evt == UseMe_Evt ): + result = Blender.Draw.PupStrInput("Info: ", fileinfo, 96) + if result: + fileinfo = result + Draw() + else: return + + ## none event + if (evt in [No_Evt, Scrn_Evt] ): + Draw() + + ## image event + if (evt == Im_Evt ): + do_it_preview() + + ## generate/update event + if (evt == Upd_Evt ): + if PreView[0].val != 0: + do_it_preview() + do_it() + + ## mesh button event + if (evt == Msh_Evt): + if AutoUpd.val != 0: + do_it() + else: Draw() + + ## button event + if (evt == Btn_Evt ): + if AutoUpd.val != 0: + if PreView[0].val != 0: + do_it_preview() + do_it() + else: Draw() + + ## randomise event + if (evt == Rndm_Evt ): + if AutoUpd.val != 0: + do_it_random() + else: + randomiseNoise() + if PreView[0].val != 0: + do_it_preview() + Draw() + + ###--------------------------------------------------------- + ## Effect Image Load/Select: + if (evt == Load_Evt ): + Blender.Window.FileSelector ( load_image, 'LOAD IMAGE') + if (evt == Sel_Evt ): + try: effect_image = Image_Menu() + except: pass + if AutoUpd.val != 0: + do_it() + else: Draw() + + ###--------------------------------------------------------- + ## Make New IPOCurve to use as Filter: + if (evt == New_Ipo_Evt ): + objname = Create("ANT_Ipo_Empty") + iponame = Create("ANT_IPO") + block = [] + block.append("Enter new names") + block.append("and hit OK button") + block.append(("OB: ", objname, 0, 30, "New Ipo Object Name. (Object type = 'Empty')")) + block.append(("IP: ", iponame, 0, 30, "New Ipo DataBlock Name")) + block.append("Open IpoCurveEditor") + block.append("select Ipo DataBlock" ) + block.append("'Pin' the view" ) + block.append("and edit the curves." ) + retval = PupBlock("Make A.N.T. IpoCurve Object", block) + if retval !=0: + ANTAutoIpo( objname.val, iponame.val ) + Ipo_Filter_Ctrl[0].val = iponame.val + + ###--------------------------------------------------------- + ## get IPOCurve to use as Filter: + if (evt in [Ipo_Evt, New_Ipo_Evt] ): + if Filter_Mode.val == 2: + if AutoUpd.val != 0: + try: + ipoblockname = Ipo.Get( Ipo_Filter_Ctrl[0].val ) + thiscurve = ipoblockname.getCurves() + selectedcurve = thiscurve[ Ipo_Filter_Ctrl[1].val ] + if PreView[0].val != 0: + do_it_preview() + #if AutoUpd.val != 0: + do_it() + except: pass + else: + try: + ipoblockname = Ipo.Get( Ipo_Filter_Ctrl[0].val ) + thiscurve = ipoblockname.getCurves() + selectedcurve = thiscurve[ Ipo_Filter_Ctrl[1].val ] + if PreView[0].val != 0: + do_it_preview() + else: + Draw() + except: pass + + ###--------------------------------------------------------- + ## gui tabs + if (evt == gt0_Evt ): + if guitabs[0].val == 1: + guitabs[1].val = ( 0 ) + guitabs[2].val = ( 0 ) + guitabs[3].val = ( 0 ) + guitabs[4].val = ( 0 ) + Draw() + if (evt == gt1_Evt ): + if guitabs[1].val == 1: + guitabs[0].val = ( 0 ) + guitabs[2].val = ( 0 ) + guitabs[3].val = ( 0 ) + guitabs[4].val = ( 0 ) + Draw() + if (evt == gt2_Evt ): + if guitabs[2].val == 1: + guitabs[0].val = ( 0 ) + guitabs[1].val = ( 0 ) + guitabs[3].val = ( 0 ) + guitabs[4].val = ( 0 ) + Draw() + if (evt == gt3_Evt ): + if guitabs[3].val == 1: + guitabs[0].val = ( 0 ) + guitabs[1].val = ( 0 ) + guitabs[2].val = ( 0 ) + guitabs[4].val = ( 0 ) + Draw() + if (evt == gt4_Evt ): + if guitabs[4].val == 1: + guitabs[0].val = ( 0 ) + guitabs[1].val = ( 0 ) + guitabs[2].val = ( 0 ) + guitabs[3].val = ( 0 ) + Draw() + + ###--------------------------------------------------------- + ## load and save all settings: + if (evt == SelFile_Evt ): + Blender.Window.FileSelector ( callback, "Select .ant File") + if (evt == LoadFile_Evt ): + loadmenu = "Load file ?%t|" + txtFile.val + loadresult = Blender.Draw.PupMenu(loadmenu) + if loadresult==1: + LoadPreset(txtFile.val) + Draw() + if AutoUpd.val != 0: + do_it() + if (evt == SaveFile_Evt ): + savemenu = "Save file ?%t|" + txtFile.val + saveresult = Blender.Draw.PupMenu(savemenu) + if saveresult==1: + SavePreset(txtFile.val) + Draw() + + ###--------------------------------------------------------- + # New Grid + ###------------------------- + if (evt == New_Evt): + scn = Blender.Scene.GetCurrent() + gridname = Create("Terrain") + gridres = Create(256) + curspos = Create(0) + block = [] + block.append(("OB: ", gridname, 0, 30, "New Object Name.")) + block.append(("Resol: ", gridres, 4, 1024, "New grid resolution")) + block.append(("At Cursor", curspos, "New grid at cursor position")) + retval = PupBlock("New Grid Mesh", block) + if retval !=0: + MakeGridMesh( gridres.val, gridname.val, curspos.val, scn ) + obj = scn.objects.active + if obj.type == 'Mesh': + actob=[] + actme=[] + actob.append( obj ) + actme.append( actob[0].getData(mesh=1) ) + Blender.Redraw() + + ###--------------------------------------------------------- + # Assign Grid + ###------------------------- + if (evt == App_Evt): + scn = Blender.Scene.GetCurrent() + obj = scn.objects.active + if obj: + if obj.type == 'Mesh': + actob=[] + actme=[] + actob.append( obj ) + actme.append( actob[0].getData(mesh=1) ) + Draw() + + ###------------------------- + if (evt not in [LoadFile_Evt,SaveFile_Evt] ): + filemessage = '' + #Draw() + + ### end events. ------------------------- + +####------------------------------------------------------------------------------------- +###------------------------------------------------------------------------------------- +##------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------- + +##---------------------------------- +# A.N.T. Auto Ipo generator: +def ANTAutoIpo( objname, iponame ): + scn=Scene.GetCurrent() + # Deselect all objects: + scn.objects.selected=[] + # Create new 'ANT_IPO_OBJECT': + obj = scn.objects.new('Empty', objname ) + obj.setDrawMode(8) + obj.select(1) + obj.layers = Window.ViewLayers() + # Set current frame at 1: + frame = Get('curframe') + if frame !=1: + Set('curframe',1) + frame = Get('curframe') + # Insert IpoKeys: + obj.setLocation(0.0, 0.0, 0.0) + obj.insertIpoKey(0) + Set('curframe',101) + obj.setLocation(100.0, 100.0, 100.0) + obj.insertIpoKey(0) + Set('curframe',1) + # Set Ipo name: + ip = obj.getIpo() + ip.name = iponame + #------------------------- + print "New ANT_IPO: " + objname +" (Object) and " + iponame + " (Ipo DataBlock) Created!" + #------------------------- + +##------------------------------------------------------------------------------------- + +##------------------------- +# Generate random numbers: +def randnum(low,high): + global RandMod, RSeed + if RandMod.val == 0: + # Noise.random setRandomSeed + s = Noise.setRandomSeed( RSeed.val ) + num = Noise.random() + num = num*(high-low) + num = num+low + elif RandMod.val == 1: + # Mathutils.Rand + num = Mathutils.Rand(low,high) + else: + # BPyMathutils Mersenne Twister genrand + num = genrand() + num = num*(high-low) + num = num+low + return num + +##------------------------- +# Randomise noise: height, size and location: +def randomiseNoise(): + global rand_I, rand_H, rand_S, rand_L, NSize, iScale, Offset, Invert, Lx, Ly, Sx, Sy + + if rand_I.val !=0: + iScale[0] = Create( randnum( 0.2 , 3.0 ) ) + Offset[0] = Create( randnum(-1.0 , 1.0 ) ) + if rand_H.val !=0: + iScale[2] = Create( randnum( 0.10 , 1.0 ) ) + Offset[2] = Create( randnum(-0.25 , 0.25 ) ) + if rand_S.val !=0: + NSize[0] = Create( randnum( 0.25 , 2.5 ) ) + #Sx[0] = Create( randnum( 0.5 , 1.5 ) ) + #Sy[0] = Create( randnum( 0.5 , 1.5 ) ) + if rand_L.val !=0: + Lx[0] = Create( randnum( -10000 , 10000 ) ) + Ly[0] = Create( randnum( -10000 , 10000 ) ) + +##------------------------------------------------------------------------------------- + +###-------------------------- +# Load Image: +def load_image( ImageFileName ): + Image.Load( ImageFileName ) + +###-------------------------- +# Select Image Menu: +def Image_Menu(): + try: + names=[] + imagelist = Image.Get() + imagelist.reverse() + for numbers, obnames in enumerate( imagelist ): + n = obnames.getName() + names.append( n ) + imlistText = string.join( [ '|' + str(names[key]) + '%x' + str(key) for key in xrange(numbers+1) ], '' ) + image_menu = Blender.Draw.PupMenu( "Images: %t" + imlistText ) + if image_menu == -1: + return '' + return imagelist[ image_menu ].getName() + except: + return 'No image found!' + +###-------------------------- +# Get Image Pixels: +def Image_Func( x,y ): + try: + pic = Image.Get( effect_image ) + except: + return 0.0 + w, h = pic.getSize() + x, y = x,-y + x = int(w * ((x + 1.0) % 2.0) / 2.0) + y = int((h-1) - h * ((y + 1.0) % 2.0) / 2.0) + c = pic.getPixelF( x,y ) + return ( c[0] + c[1] + c[2] ) / 3.0 + +##------------------------------------------------------------------------------------- + +# Transpose noise coords: +def Trans((x,y,z), size, loc ): + x = ( x / size[1] / size[0] + loc[0] ) + y = ( y / size[2] / size[0] + loc[1] ) + z = 0.0 #( z / size[3] / size[0] + loc[2] ) + return x,y,z + +# Transpose effect coords: +def Trans_Effect((x,y,z), size, loc ): + x = ( x * size[1] * size[0] + loc[0] ) + y = ( y * size[2] * size[0] + loc[1] ) + z = 0.0 + return x,y,z + +# Height scale: +def HeightScale( input, iscale, offset, invert ): + if invert !=0: + return (1.0-input) * iscale + offset + else: + return input * iscale + offset + +# dist. +def Dist(x,y): + return sqrt( (x*x)+(y*y) ) + +##----------------------------------- +# bias types: +def no_bias(a): + return a +def sin_bias(a): + return 0.5 + 0.5 * sin(a) +def cos_bias(a): + return 0.5 + 0.5 * cos(a) +def tri_bias(a): + b = 2 * phi + a = 1 - 2 * abs(floor((a * (1/b))+0.5) - (a*(1/b))) + return a +def saw_bias(a): + b = 2 * phi + n = int(a/b) + a -= n * b + if a < 0: a += b + return a / b +# sharpen types: +def soft(a): + return a +def sharp(a): + return a**0.5 +def sharper(a): + return sharp(sharp(a)) +Bias_Types = [ sin_bias, cos_bias, tri_bias, saw_bias, no_bias ] +Sharp_Types = [ soft, sharp, sharper ] + +##----------------------------------- +# clamp height +def clamp( height, min, max ): + if ( height < min ): height = min + if ( height > max ): height = max + return height + +##----------------------------------- +# Mix modes +def maximum( a, b ): + if ( a > b ): b = a + return b +def minimum( a, b ): + if ( a < b ): b = a + return b + +def Mix_Modes( (i,j),(x,y,z) , a,b, mixfactor, mode ): + a = a * ( 1.0 - mixfactor ) + b = b * ( 1.0 + mixfactor ) + if mode == 0: return ( b ) #0 effect only + elif mode == 1: return ( a*(1.0-0.5) + (b*0.5) ) #1 mix + elif mode == 2: return ( a + b ) #2 add + elif mode == 3: return ( a - b ) #3 sub. + elif mode == 4: return ( a * b ) #4 mult. + elif mode == 5: return (abs( a - b )) #5 abs diff. + elif mode == 6: return 1.0-((1.0-a)*(1.0-b)/1.0) #6 screen + elif mode == 7: return ( a + b ) % 1.0 #7 addmodulo + elif mode == 8: return min( a, b ) #8 min. + elif mode == 9: return max( a, b ) #9 max. + elif mode == 10: #10 warp: effect + noise = mixfactor * Noise_Function(x,y,z) + return Effects( (i,j),(x+noise,y+noise,z) ) + elif mode == 11: #11 warp: noise + effect = mixfactor * Effects( (i,j),(x,y,z) ) + return Noise_Function( x+effect, y+effect, z ) + else: return a + +###---------------------------------------------------------------------- +# Effect functions: + +# Effect_Basis_Function: +def Effect_Basis_Function((x,y), type, bias ): + + iscale = 1.0 + offset = 0.0 + ## gradient: + if type == 0: + effect = offset + iscale * ( Bias_Types[ bias ]( x + y ) ) + ## waves / bumps: + if type == 1: + effect = offset + iscale * 0.5 * ( Bias_Types[ bias ]( x*phi ) + Bias_Types[ bias ]( y*phi ) ) + ## zigzag: + if type == 2: + effect = offset + iscale * Bias_Types[ bias ]( offset + iscale * sin( x*phi + sin( y*phi ) ) ) + ## wavy: + if type == 3: + effect = offset + iscale * ( Bias_Types[ bias ]( cos( x ) + sin( y ) + cos( x*2+y*2 ) - sin( -x*4+y*4) ) ) + ## sine bump: + if type == 4: + effect = offset + iscale * 1-Bias_Types[ bias ](( sin( x*phi ) + sin( y*phi ) )) + ## dots: + if type == 5: + effect = offset + iscale * ( Bias_Types[ bias ](x*phi*2) * Bias_Types[ bias ](y*phi*2) )-0.5 + ## rings / dome: + if type == 6: + effect = offset + iscale * ( Bias_Types[ bias ]( 1.0-(x*x+y*y) ) ) + ## spiral: + if type == 7: + effect = offset + iscale * Bias_Types[ bias ](( x*sin( x*x+y*y ) + y*cos( x*x+y*y ) ))*0.5 + ## square / piramide: + if type == 8: + effect = offset + iscale * Bias_Types[ bias ](1.0-sqrt( (x*x)**10 + (y*y)**10 )**0.1) + ## blocks: + if type == 9: + effect = ( 0.5-max( Bias_Types[ bias ](x*phi) , Bias_Types[ bias ](y*phi) )) + if effect > 0.0: effect = 1.0 + effect = offset + iscale * effect + ## grid: + if type == 10: + effect = ( 0.025-min( Bias_Types[ bias ](x*phi) , Bias_Types[ bias ](y*phi) )) + if effect > 0.0: effect = 1.0 + effect = offset + iscale * effect + ## tech: + if type == 11: + a = ( max( Bias_Types[ bias ](x*pi) , Bias_Types[ bias ](y*pi) )) + b = ( max( Bias_Types[ bias ](x*pi*2+2) , Bias_Types[ bias ](y*pi*2+2) )) + effect = ( min( Bias_Types[ bias ](a) , Bias_Types[ bias ](b) ))*3.0-2.0 + if effect > 0.5: effect = 1.0 + effect = offset + iscale * effect + + ## crackle: + if type == 12: + t = turbulence(( x, y, 0 ), 6, 0, 0 ) * 0.25 + effect = vlNoise(( x, y, t ), 0.25, 0, 8 ) + if effect > 0.5: effect = 0.5 + effect = offset + iscale * ( effect ) + ## sparse cracks noise: + if type == 13: + effect = 2.5 * abs( noise((x*0.5,y*0.5, 0 ), 1 ) )-0.1 + if effect > 0.25: effect = 0.25 + effect = offset + iscale * ( effect * 2.5 ) + ## shattered rock noise: + if type == 14: + effect = 0.5 + noise((x,y,0), 7 ) + if effect > 0.75: effect = 0.75 + effect = offset + iscale * effect + ## lunar noise: + if type == 15: + effect = 0.25 + 1.5 * voronoi(( x+2, y+2, 0 ), 1 )[0][0] + if effect > 0.5: effect = 0.5 + effect = offset + iscale * ( effect * 2.0 ) + ## cosine noise: + if type == 16: + effect = cos( 5*noise(( x, y, 0 ), 0 ) ) + effect = offset + iscale * ( effect*0.5 ) + ## spikey noise: + if type == 17: + n = 0.5 + 0.5 * turbulence(( x*5, y*5, 0 ), 8, 0, 0 ) + effect = ( ( n*n )**5 ) + effect = offset + iscale * effect + ## stone noise: + if type == 18: + effect = offset + iscale *( noise((x*2,y*2, 0 ), 0 ) * 1.5 - 0.75) + ## Flat Turb: + if type == 19: + t = turbulence(( x, y, 0 ), 6, 0, 0 ) + effect = t*2.0 + if effect > 0.25: effect = 0.25 + effect = offset + iscale * ( effect ) + ## Flat Voroni: + if type == 20: + t = 1-noise(( x, y, 0 ), 3 ) + effect = t*2-1.75 + if effect > 0.25: effect = 0.25 + effect = offset + iscale * ( effect ) + + if effect < 0.0: effect = 0.0 + return effect + +# fractalize Effect_Basis_Function: ------------------------------ +def Effect_Function((x,y), type,bias, turb, depth,frequency,amplitude ): + + ## effect distortion: + if turb != 0.0: + t = vTurbulence(( x, y, 0 ), 6, 0, 0 ) + x = x + ( 0.5 + 0.5 * t[0] ) * turb + y = y + ( 0.5 + 0.5 * t[1] ) * turb + + result = Effect_Basis_Function((x,y), type, bias ) + ## fractalize effect: + if depth != 0: + i=0 + while i < depth: + i+=1 + x *= frequency + y *= frequency + amplitude = amplitude / i + result += Effect_Basis_Function( (x,y), type, bias ) * amplitude + return result + +###-------------------------------------------------- +# Custom effect: +def CustomEffect( x,y,z,h ): + global CustomFX + try: + a = eval( CustomFX[0].val ) + b = eval( CustomFX[1].val ) + result = eval( CustomFX[2].val ) + return result + except: + return 0.0 + +###-------------------------------------------------- +## Effect Selector: + +def Effects( (i,j),(x,y,z), h=0.0 ): + global Effect_Type, Effect_Ctrl, iScale, Offset, Invert + global NSize, Lx, Ly, Lz, Sx, Sy, Sz, marbleTwo, turbTwo, vlnoiTwo, Basis, musgrTwo + + x,y,z = Trans_Effect((x,y,z),( NSize[1].val, Sx[1].val, Sy[1].val, 0 ),( Lx[1].val, Ly[1].val, 0 ) ) + basis = Basis[1].val + if basis == 9: basis = 14 + vbasis = vlnoiTwo[1].val + if vbasis == 9: vbasis = 14 + if Effect_Ctrl[0].val == 1: + try: effect = Image_Func( x,y ) + except: effect = 0.0 + elif Effect_Ctrl[0].val == 2: effect = 0.5+0.5*turbulence(( x,y,z ),turbTwo[0].val, turbTwo[1].val, basis, turbTwo[2].val, turbTwo[3].val ) + elif Effect_Ctrl[0].val == 3: effect = 0.5+0.5*vlNoise(( x,y,z ),vlnoiTwo[0].val, vbasis, basis ) + elif Effect_Ctrl[0].val == 4: effect = 0.5*marbleNoise((x,y,z), marbleTwo[0].val, basis, marbleTwo[2].val, marbleTwo[3].val, marbleTwo[4].val, marbleTwo[5].val ) + elif Effect_Ctrl[0].val == 5: effect = 0.5*multiFractal(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, basis ) + elif Effect_Ctrl[0].val == 6: effect = 0.5*ridgedMFractal(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, musgrTwo[3].val, musgrTwo[4].val, basis ) + elif Effect_Ctrl[0].val == 7: effect = 0.5*hybridMFractal(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, musgrTwo[3].val, musgrTwo[4].val, basis ) + elif Effect_Ctrl[0].val == 8: effect = 0.5*heteroTerrain(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, musgrTwo[3].val, basis )*0.5 + elif Effect_Ctrl[0].val == 9: effect = 0.5*fBm(( x,y,z ),musgrTwo[0].val, musgrTwo[1].val, musgrTwo[2].val, basis )+0.5 + elif Effect_Ctrl[0].val > 9 and Effect_Ctrl[0].val < 31: + effect = Effect_Function((x,y), Effect_Ctrl[0].val-10, Effect_Ctrl[3].val, Effect_Ctrl[4].val, Effect_Ctrl[5].val, Effect_Ctrl[6].val, Effect_Ctrl[7].val ) + elif Effect_Ctrl[0].val == 31: effect = Effect_Ctrl[8].val * random() + elif Effect_Ctrl[0].val == 32: effect = Effect_Ctrl[8].val + elif Effect_Ctrl[0].val == 33: effect = CustomEffect( x,y,z, h ) + effect = HeightScale( effect, iScale[1].val , Offset[1].val, Invert[1].val ) + return effect*2.0 + +###---------------------------------------------------------------------- +# Noise: +##----------------------------------- + +## voronoi_turbulence: +def voroTurbMode((x,y,z), voro, mode ): + if mode == 0: # soft + return voronoi(( x,y,z ),voro[0], voro[1] )[0][0] + if mode == 1: # hard + return ( abs( 0.5-voronoi(( x,y,z ),voro[0], voro[1] )[0][0] ) )+0.5 +def voronoi_turbulence((x,y,z), voro, tur ): + result = voroTurbMode((x,y,z), voro, tur[1] ) + depth = tur[0] + amp = tur[2] + freq = tur[3] + i=0 + for i in xrange( depth ): + i+=1 + result += voroTurbMode( ( x*(freq*i), y*(freq*i), z ), voro, tur[1] )* ( amp*0.5/i ) + return (result*4.0-2.0) + +## DistortedNoise / vlNoise_turbulence: +def vlnTurbMode((x,y,z), vlno, basis, mode ): + if mode == 0: # soft + return vlNoise(( x,y,z ),vlno[0], vlno[1], basis ) + if mode == 1: # hard + return ( abs( -vlNoise(( x,y,z ),vlno[0], vlno[1], basis ) ) ) +def vlNoise_turbulence((x,y,z), vlno, tur, basis ): + result = vlnTurbMode((x,y,z), vlno, basis, tur[1] ) + depth = tur[0] + amp = tur[2] + freq = tur[3] + i=0 + for i in xrange( depth ): + i+=1 + result += vlnTurbMode( ( x*(freq*i), y*(freq*i), z ), vlno, basis, tur[1] ) * ( amp*0.5/i ) + return result*2.0+0.5 + +## marbleNoise: +def marbleNoise( (x,y,z), depth, basis, turb, bias, sharpnes, rescale ): + m = ( x * rescale + y * rescale + z ) * 5 + height = m + turb * turbulence( ( x ,y ,z ), depth, 0, basis, 0.5, 2.0 ) + height = Bias_Types[ bias ]( height ) + if bias != 4: + height = Sharp_Types[ sharpnes ]( height ) + return height*2.0 + +## lava_multiFractal: +def lava_multiFractal( ( x,y,z ),Ha, La, Oc, distort, Basis ): + m = multiFractal( ( x,y,z ), Ha, La, Oc, Basis) + d = m * distort + m2 = 0.5 * multiFractal( ( x+d,y+d,d*0.5 ), Ha, La, Oc, Basis) + return (m * m2)**0.5 + +## slopey_noise: +def slopey_noise((x,y,z), H, lacunarity, octaves, distort, basis ): + x=x*2 + y=y*2 + turb = fBm((x,y,z), H, lacunarity, octaves, 2 ) * 0.5 + map = 0.5 + noise( ( x+turb, y+turb, z ), basis ) + result = map + turb * distort + return result + +## duo_multiFractal: +def double_multiFractal((x,y,z), H, lacunarity, octaves, offset, gain, basis ): + n1 = multiFractal( (x*1.5+1,y*1.5+1,z), 1.0, 1.0, 1.0, basis[0] ) * offset + n2 = multiFractal( (x-1,y-1,z), H, lacunarity, octaves, basis[1] ) * gain + result = ( n1*n1 + n2*n2 )*0.5 + return result + +## distorted_heteroTerrain: +def distorted_heteroTerrain((x,y,z), H, lacunarity, octaves, offset, distort, basis ): + h1 = ( heteroTerrain((x,y,z), 1.0, 2.0, 1.0, 1.0, basis[0] ) * 0.5 ) + h2 = ( heteroTerrain(( x, y, h1*distort ), H, lacunarity, octaves, offset, basis[1] ) * 0.25 ) + result = ( h1*h1 + h2*h2 ) + return result + +## SlickRock: +def SlickRock((x,y,z), H, lacunarity, octaves, offset, gain, basis ): + n = multiFractal( (x,y,z), 1.0, 2.0, 1.0, basis[0] ) + r = ridgedMFractal((x,y,n*0.5), H, lacunarity, octaves, offset, gain, basis[1] )*0.5 + return n+(n*r) + +## terra_turbulence: +def terra_turbulence((x,y,z), depth, hard, basis, amp, freq ): + t2 = turbulence( ( x, y, z ), depth, hard , basis, amp, freq ) + return (t2*t2*t2)+0.5 + +## rocky_fBm: +def rocky_fBm((x,y,z), H, lacunarity, octaves, basis ): + turb = fBm((x,y,z), H, lacunarity, octaves, 2 ) * 0.25 + coords = ( x+turb, y+turb, z ) + map = noise( coords, 7 ) + result = map + fBm( coords, H, lacunarity, octaves, basis ) + 1.0 + return result + +## Shattered_hTerrain: +def Shattered_hTerrain((x,y,z), H, lacunarity, octaves, offset, distort, basis ): + d = ( turbulence( ( x, y, z ), 6, 0, 0, 0.5, 2.0 ) * 0.5 + 0.5 )*distort*0.25 + t0 = ( turbulence( ( x+d, y+d, z ), 0, 0, 7, 0.5, 2.0 ) + 0.5 ) + t2 = ( heteroTerrain(( x*2, y*2, t0*0.5 ), H, lacunarity, octaves, offset, basis ) ) + return (( t0*t2 )+t2*0.5)*0.75 + +## vlhTerrain +def vlhTerrain((x,y,z), H, lacunarity, octaves, offset, basis, vlbasis, distort ): + ht = heteroTerrain(( x, y, z ), H, lacunarity, octaves, offset, basis )*0.5 + vl = ht * vlNoise((x,y,z), distort, basis, vlbasis )*0.5+0.5 + return vl * ht + +####---------------------------------------. +### StatsByAlt, double terrain basis mode: +def TerrainBasisMode((x,y,z), basis, mode ): + if mode == 0: # noise + return noise((x,y,z),basis) + if mode == 1: # noise ridged + return ( 1.0-abs( noise((x,y,z),basis) ) )-0.5 + if mode == 2: # vlNoise + return vlNoise((x,y,z), 1.0, 0, basis ) + else: # vlNoise ridged + return ( 1.0-abs( vlNoise((x,y,z), 1.0, 0, basis ) ) )-0.5 + +#### StatsByAlt terrain: +def StatsByAltTerrain((x,y,z), exp, lacu, octs, offset, amp, basis, mode ): + result = 0.5 * (offset + TerrainBasisMode((x,y,z), basis, mode ) ) + octs = int( octs ) + i = 0 + for i in xrange( 1, octs ): + i += 1 + result += result * amp * 0.5 * (offset + TerrainBasisMode((x,y,z), basis, mode ) ) + x *= lacu + y *= lacu + amp /= ( exp * 0.5 ) * i + return result + +##### double terrain: +def doubleTerrain((x,y,z), exp, lacu, octs, offset, threshold, basis, mode ): + result = amp = freq = 1.0 + #octs = int( octs ) + offset*=0.5 + i = 1 + signal = result = 0.5 * (offset + TerrainBasisMode((x,y,z), basis, mode ) ) + for i in xrange( 1, octs ): + i += 1 + x = x * lacu + y = y * lacu + freq *= lacu + amp = pow( freq, -exp ) + amp *= i + weight = signal / threshold + if weight > 1.0: weight = 1.0 + if weight < 0.0: weigth = 0.0 + signal = weight * 0.5 * ( offset + TerrainBasisMode((x,y,z), basis, mode ) ) + result += amp * signal + return result * 2.0 + +##------------------------------------------------------------ +# Noise Functions: +def Noise_Function(x,y,z): + global Basis, NType, musgr, vlnoi, voron, turbOne, marbleOne, tBasismod + global vlBasis, Distort, VFunc, VExp, VDep + global iScale, Offset, Invert, NSize, Lx, Ly, Sx, Sy + + x,y,z = Trans((x,y,z),( NSize[0].val, Sx[0].val, Sy[0].val, 0 ),( Lx[0].val, Ly[0].val, 0 ) ) + basis = Basis[0].val + if basis == 9: basis = 14 + vbasis = vlnoi[1].val + if vbasis == 9: vbasis = 14 + if NType.val == 0: z = multiFractal(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, basis ) + elif NType.val == 1: z = ridgedMFractal(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, basis ) + elif NType.val == 2: z = hybridMFractal(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, basis ) + elif NType.val == 3: z = heteroTerrain(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, basis )*0.5 + elif NType.val == 4: z = fBm(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, basis )+0.5 + elif NType.val == 5: z = turbulence(( x,y,z ),turbOne[0].val, turbOne[1].val, basis, turbOne[2].val, turbOne[3].val )+0.5 + elif NType.val == 6: z = voronoi_turbulence((x,y,z),(voron[0].val,voron[1].val),(turbOne[0].val,turbOne[1].val,turbOne[2].val,turbOne[3].val) )*0.5+0.5 + elif NType.val == 7: z = vlNoise_turbulence((x,y,z),(vlnoi[0].val,vbasis), (turbOne[0].val,turbOne[1].val,turbOne[2].val,turbOne[3].val), basis )*0.5+0.5 + elif NType.val == 8: z = noise(( x,y,z ),basis )+0.5 + elif NType.val == 9: z = cellNoise(( x,y,z ))+0.5 + elif NType.val == 10: z = marbleNoise(( x,y,z), marbleOne[0].val, basis, marbleOne[2].val, marbleOne[3].val, marbleOne[4].val, marbleOne[5].val ) + elif NType.val == 11: z = lava_multiFractal(( x,y,z ), musgr[0].val, musgr[1].val, musgr[2].val, vlnoi[0].val, basis ) + elif NType.val == 12: z = slopey_noise(( x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, vlnoi[0].val, basis )+0.5 + elif NType.val == 13: z = double_multiFractal(( x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, (vbasis,basis) ) + elif NType.val == 14: z = distorted_heteroTerrain((x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, vlnoi[0].val, (vbasis,basis) ) + elif NType.val == 15: z = SlickRock(( x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val, (vbasis,basis) ) + elif NType.val == 16: z = terra_turbulence(( x,y,z), turbOne[0].val, turbOne[1].val, basis, turbOne[2].val, turbOne[3].val ) + elif NType.val == 17: z = rocky_fBm(( x,y,z ),musgr[0].val, musgr[1].val, musgr[2].val, basis ) + elif NType.val == 18: z = StatsByAltTerrain( (x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[4].val*0.5, basis, tBasismod.val ) + elif NType.val == 19: z = doubleTerrain( (x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, musgr[5].val, basis, tBasismod.val ) + elif NType.val == 20: z = Shattered_hTerrain((x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, vlnoi[0].val, basis ) + elif NType.val == 21: z = vlhTerrain((x,y,z), musgr[0].val, musgr[1].val, musgr[2].val, musgr[3].val, basis, vbasis, vlnoi[0].val ) + else: z = 0.0 + return HeightScale( z, iScale[0].val , Offset[0].val, Invert[0].val ) + +###---------------------------------------------------------------------- +##----------------------------------- +# Filter functions: + +##----------------------------------- +# Filter: Clamp height +def Clamp_Max( height, max ): + if ( height > max ): height = max + return height +def Clamp_Min( height, min ): + if ( height < min ): height = min + return height + +##----------------------------------- +# Filters: terrace / posterise / peaked / bias: +def Def_Filter((x,y,z), input, numb, type ): + if type == 0: + s = ( sin( input*numb*phi ) * ( 0.1/numb*phi ) ) + return ( input * (1.0-0.5) + s*0.5 ) * 2.0 + elif type == 1: + s = -abs( sin( input*(numb*0.5)*phi ) * ( 0.1/(numb*0.5)*phi ) ) + return ( input * (1.0-0.5) + s*0.5 ) * 2.0 + elif type == 2: + s = abs( sin( input*(numb*0.5)*phi ) * ( 0.1/(numb*0.5)*phi ) ) + return ( input * (1.0-0.5) + s*0.5 ) * 2.0 + elif type == 3: + numb = numb*0.5 + s = ( int( input*numb ) * 1.0/numb ) + return ( input * (1.0-0.5) + s*0.5 ) * 2.0 + elif type == 4: + numb = numb*0.5 + s = ( int( input*numb ) * 1.0/numb ) + return ( s ) * 2.0 + elif type == 5: + s = ( sin( input*(2*numb)*phi ) * ( 0.1/(2*numb)*phi ) ) + l = ( input * (1.0-0.5) + s*0.5 ) * 2.0 + p = ( ( l*numb*0.25 ) * ( l*numb*0.25 ) )**2 + return ( l * (1.0-0.5) + p*0.5 ) * 2.0 + elif type == 6: + return ( input*numb*0.25 )**4 + elif type == 7: + return 2.0-exp( 1.0-(input*numb/3.0) ) + elif type == 8: + return sin_bias( input*numb )*2.0 + elif type == 9: + return cos_bias( input*numb )*2.0 + elif type == 10: + return tri_bias( input*numb )*2.0 + elif type == 11: + return saw_bias( input*numb )*2.0 + elif type == 12: + return Clamp_Max( input, numb ) + else: + return input + +##----------------------------------- +# Filter: Edge falloff +def EdgeFalloff( (x,y,z), height, type ): + global Falloff, iScale, Offset + + x = x / Falloff[1].val + y = y / Falloff[2].val + + if Falloff[3].val != 0: + sealevel = (Min.val-Offset[2].val)*2.0/iScale[2].val + else: + sealevel = 0.0 + + falltypes = ( 0, sqrt(x*x+y*y), sqrt((x*x)**2+(y*y)**2), sqrt((x*x)**10+(y*y)**10), sqrt(y*y), sqrt(x*x), abs(x-y), abs(x+y), ((x*x)**10+(y*y)**10)**0.1, ((x*x)+(y*y)) ) + + dist = falltypes[ type ] + if Falloff[4].val != 0: + dist = 1.0 - dist + radius = 1.0 + height = height - sealevel + if( dist < radius ): + dist = dist / radius + dist = ( (dist) * (dist) * ( 3-2*(dist) ) ) + height = ( height - height * dist ) + sealevel + else: + height = sealevel + + if Falloff[3].val != 0: + height = Clamp_Min( height, sealevel ) + else: + height = Clamp_Min( height, Min.val ) + + return height + +##----------------------------------- +# Filter: Custom height filter: +def CustomFilter( x,y,z, h ): + global CustomFilt + try: + a = eval(CustomFilt[0].val) + b = eval(CustomFilt[1].val) + result = eval(CustomFilt[2].val) + return result + except: + return 0.0 + +#####-------------------------------------------------------------------------------------##### +####-------------------------------------------------------------------------------------#### +### Combine Functions: (get noise, Add effect, filter height and return result) ### +##-------------------------------------------------------------------------------------## + +def Combine_Functions( (i,j),(x,y,z) ): + global Effect_Ctrl, Blend_Effect, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order + global iScale, Offset, Invert, Min, Max, Falloff + + # get noise height: + height = Noise_Function(x,y,0.0) + + ### Filter On + if Filter_Mode.val !=0: + ### 0= Default Filter Order: Noise>Effect>Filter --------------------- + if Filter_Order.val ==0: + # mix noise with effect: + if Effect_Ctrl[0].val !=0: + height = Mix_Modes( (i,j),(x,y,z), height , Effects( (i,j),(x,y,z),height ), Effect_Ctrl[2].val, Effect_Ctrl[1].val ) + # edge fallof: + if Falloff[0].val !=0: + height = EdgeFalloff( (x,y,z), height, Falloff[0].val ) + #else: pass + + if Filter_Mode.val !=0: + # height Def_Filter (Terrace/peaked/bias): + if Filter_Mode.val ==1: + height = Def_Filter((x,y,z), height, Def_Filter_Ctrl[ 1 ].val, Def_Filter_Ctrl[ 0 ].val ) + + ## 'IPOCurve' height filter: + elif Filter_Mode.val ==2: + try: + height = selectedcurve.evaluate( 1 + ( height*Ipo_Filter_Ctrl[2].val/2 ) )*2.0/Ipo_Filter_Ctrl[3].val + except: + height = height + + ## Custom filter: + elif Filter_Mode.val ==3: + height = CustomFilter( x,y,z, height ) + + ### 1= Changed Filter Order: Noise>Filter>Effect --------------------- + if Filter_Order.val !=0: + # mix noise with effect: + if Effect_Ctrl[0].val !=0: + height = Mix_Modes( (i,j),(x,y,z), height , Effects( (i,j),(x,y,z),height ), Effect_Ctrl[2].val, Effect_Ctrl[1].val ) + # edge fallof: + if Falloff[0].val !=0: + height = EdgeFalloff( (x,y,z), height, Falloff[0].val ) + #else: pass + + ### Filter Off --------------------- + else: + # mix noise with effect: + if Effect_Ctrl[0].val !=0: + height = Mix_Modes( (i,j),(x,y,z), height , Effects( (i,j),(x,y,z),height ), Effect_Ctrl[2].val, Effect_Ctrl[1].val ) + # edge fallof: + if Falloff[0].val !=0: + height = EdgeFalloff( (x,y,z), height, Falloff[0].val ) + + # height scale: + height = HeightScale( height, 0.5*iScale[2].val , Offset[2].val, Invert[2].val ) + + # clamp height min. max.: + if Falloff[0].val !=1: + height = Clamp_Min( height, Min.val ) + height = Clamp_Max( height, Max.val ) + + # return height: + return height + + +#------------------------------------------------------------ +##------------------------------------------------------------ +### Render Noise to a Image('NAME') (you must create one first) +##------------------------------------------------------------ +#------------------------------------------------------------ + +def HeightFieldImage(): + global PreView, previewname + + iname = previewname.val + try: + pic = Image.Get( iname ) + except: + #print iname, ' No Image with this name' + PupMenu( 'No Image with this name' ) + return + res = pic.getMaxXY() + for i in xrange( res[0] ): + x = i - (res[0]) / 2.0 + x = (x*2.0) / (res[0]) + for j in xrange( res[1] ): + y = j - (res[1]) / 2.0 + y = (y*2.0) / (res[1]) + height = PreView[2].val + PreView[1].val * Combine_Functions( (i,j),(x,y,0) ) + if height > 1.0: height = 1.0 + if height < 0.0: height = 0.0 + pic.setPixelF( i, j, ( height,height,height, 1.0 ) ) + + +#------------------------------------------------------------ +##------------------------------------------------------------ +### Mesh +##------------------------------------------------------------ +#------------------------------------------------------------ + +#------------------------------------------------------------ +## Mesh: make new grid +###------------------------------------------------------------ + +def MakeGridMesh( RESOL=32, NAME='GridMesh', CURSORPOS=0, SCENE=None ): + # scene, object, mesh --------------------------------------- + if not SCENE: + SCENE = Blender.Scene.GetCurrent() + SCENE.objects.selected=[] + newme = Blender.Mesh.New( NAME ) + newob = SCENE.objects.new( newme, NAME ) + n = RESOL + # verts --------------------------------------- + v=[] + for i in xrange( n ): + x = i-(n-1)/2.0 + x = x*2.0/(n-1) + for j in xrange( n ): + y = j-(n-1)/2.0 + y = y*2.0/(n-1) + v.append( [ x, y, 0 ] ) + newme.verts.extend(v) + # faces --------------------------------------- + f=[] + for i in xrange( n-1 ): + for j in xrange( n-1 ): + f.append( [ i*n+j,\ + (i+1)*n+j,\ + (i+1)*n+j+1,\ + i*n+j+1 ] ) + + newme.faces.extend(f, smooth=True) + #--------------------------------------- + newme.calcNormals() + #--------------------------------------- + if CURSORPOS !=0: + newob.loc = Window.GetCursorPos() + newob.select(1) + +#------------------------------------------------------------ +## Mesh: Grid vert displace / update terrain +###------------------------------------------------------------ + +def displace( OB, ME, WORLD=0 ): + if WORLD == 1: + wx,wy,wz = OB.getLocation( 'worldspace' ) + elif WORLD ==2: + l = OB.getLocation( 'worldspace' ) + w = Window.GetCursorPos() + wx,wy,wz = l[0]-w[0], l[1]-w[1], l[2]-w[2] + else: + wx,wy,wz = 0,0,0 + + for v in ME.verts: + co = v.co + co[2] = Combine_Functions( (co[0]+wx,co[1]+wy),(co[0]+wx, co[1]+wy, 0.0+wz) ) + ME.update() + ME.calcNormals() + #OB.makeDisplayList() + + +#---------------------------------------------------------------------------------------------------- +##---------------------------------------------------------------------------------------------------- +###---------------------------------------------------------------------------------------------------- +####---------------------------------------------------------------------------------------------------- +###---------------------------------------------------------------------------------------------------- +## Do_it: +#-------------------------------------- + +#-------------------------------------- +def do_it(): + global PreView, actme, actob, WorldSpaceCo + if actme !=[]: + if print_time !=0: + t= sys.time() + Window.WaitCursor(1) + in_editmode = Window.EditMode() + if in_editmode: Window.EditMode(0) + if PreView[0].val != 0: + do_it_preview() + displace( actob[0], actme[0], WorldSpaceCo.val ) + Window.RedrawAll() + else: + displace( actob[0], actme[0], WorldSpaceCo.val ) + Window.RedrawAll() + if in_editmode: Window.EditMode(1) + Window.WaitCursor(0) + if print_time !=0: + print 'Generate Mesh: done in %.6f' % (sys.time()-t) + +#-------------------------------------- +def do_it_random(): + global PreView, actme, actob + if actme !=[]: + if print_time !=0: + t= sys.time() + Window.WaitCursor(1) + in_editmode = Window.EditMode() + if in_editmode: Window.EditMode(0) + randomiseNoise() + if PreView[0].val != 0: + do_it_preview() + displace( actob[0], actme[0], WorldSpaceCo.val ) + Window.RedrawAll() + else: + displace( actob[0], actme[0], WorldSpaceCo.val ) + Window.RedrawAll() + if in_editmode: Window.EditMode(1) + Window.WaitCursor(0) + if print_time !=0: + print 'Generate Mesh: done in %.6f' % (sys.time()-t) + +#-------------------------------------- +def do_it_preview(): + if print_time !=0: + t= sys.time() + HeightFieldImage() + Window.RedrawAll() + if print_time !=0: + print 'Generate Image: done in %.6f' % (sys.time()-t) + +###--------------------------------------------------------- +###--------------------------------------------------------- +## load and save: +#------------------------- + +def callback( filename ): + txtFile.val = filename + Register(drawgui, events, bevents) +def writeln(f,x): + f.write(str(x)) + f.write("\n") +def readint(f): + return int(f.readline()) +def readfloat(f): + return float(f.readline()) +def readstr(f): + s = (f.readline()) + return strip(s) + +#-------------------------------------------------- +# Save settings to .ant file +def SavePreset(FName): + global iScale, Offset, Invert, NSize, Sx, Sy, Lx, Ly + global NType, Basis, musgr, tBasismod, vlnoi, vlnoiTwo, voron, turbOne, turbTwo, marbleOne, marbleTwo, musgrTwo + global CustomFX, effect_image, Effect_Ctrl, Min, Max, Falloff, CustomFilt, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order + global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I, filemessage, fileinfo + + try: + f = open(FName,'w') + writeln(f,CurVersion) + except: + filemessage = "Unable to save file." + return + + writeln(f,fileinfo) + writeln(f,iScale[0].val) + writeln(f,iScale[1].val) + writeln(f,iScale[2].val) + writeln(f,Offset[0].val) + writeln(f,Offset[1].val) + writeln(f,Offset[2].val) + writeln(f,Invert[0].val) + writeln(f,Invert[1].val) + writeln(f,Invert[2].val) + writeln(f,NSize[0].val) + writeln(f,NSize[1].val) + writeln(f,Sx[0].val) + writeln(f,Sx[1].val) + writeln(f,Sy[0].val) + writeln(f,Sy[1].val) + writeln(f,Lx[0].val) + writeln(f,Lx[1].val) + writeln(f,Ly[0].val) + writeln(f,Ly[1].val) + writeln(f,NType.val) + writeln(f,Basis[0].val) + writeln(f,Basis[1].val) + writeln(f,musgr[0].val) + writeln(f,musgr[1].val) + writeln(f,musgr[2].val) + writeln(f,musgr[3].val) + writeln(f,musgr[4].val) + writeln(f,musgr[5].val) + writeln(f,tBasismod.val) + writeln(f,vlnoi[0].val) + writeln(f,vlnoi[1].val) + writeln(f,vlnoiTwo[0].val) + writeln(f,vlnoiTwo[1].val) + writeln(f,voron[0].val) + writeln(f,voron[1].val) + writeln(f,turbOne[0].val) + writeln(f,turbOne[1].val) + writeln(f,turbOne[2].val) + writeln(f,turbOne[3].val) + writeln(f,turbTwo[0].val) + writeln(f,turbTwo[1].val) + writeln(f,turbTwo[2].val) + writeln(f,turbTwo[3].val) + writeln(f,marbleOne[0].val) + writeln(f,marbleOne[1].val) + writeln(f,marbleOne[2].val) + writeln(f,marbleOne[3].val) + writeln(f,marbleOne[4].val) + writeln(f,marbleOne[5].val) + writeln(f,marbleTwo[0].val) + writeln(f,marbleTwo[1].val) + writeln(f,marbleTwo[2].val) + writeln(f,marbleTwo[3].val) + writeln(f,marbleTwo[4].val) + writeln(f,marbleTwo[5].val) + writeln(f,musgrTwo[0].val) + writeln(f,musgrTwo[1].val) + writeln(f,musgrTwo[2].val) + writeln(f,musgrTwo[3].val) + writeln(f,musgrTwo[4].val) + writeln(f,effect_image) + writeln(f,Effect_Ctrl[0].val) + writeln(f,Effect_Ctrl[1].val) + writeln(f,Effect_Ctrl[2].val) + writeln(f,Effect_Ctrl[3].val) + writeln(f,Effect_Ctrl[4].val) + writeln(f,Effect_Ctrl[5].val) + writeln(f,Effect_Ctrl[6].val) + writeln(f,Effect_Ctrl[7].val) + writeln(f,Effect_Ctrl[8].val) + writeln(f,CustomFX[0].val) + writeln(f,CustomFX[1].val) + writeln(f,CustomFX[2].val) + writeln(f,Min.val) + writeln(f,Max.val) + writeln(f,Falloff[0].val) + writeln(f,Falloff[1].val) + writeln(f,Falloff[2].val) + writeln(f,Falloff[3].val) + writeln(f,Falloff[4].val) + writeln(f,Filter_Mode.val) + writeln(f,Filter_Order.val) + writeln(f,CustomFilt[0].val) + writeln(f,CustomFilt[1].val) + writeln(f,CustomFilt[2].val) + writeln(f,Def_Filter_Ctrl[0].val) + writeln(f,Def_Filter_Ctrl[1].val) + writeln(f,Ipo_Filter_Ctrl[0].val) + writeln(f,Ipo_Filter_Ctrl[1].val) + writeln(f,Ipo_Filter_Ctrl[2].val) + writeln(f,Ipo_Filter_Ctrl[3].val) + writeln(f,RandMod.val) + writeln(f,RSeed.val) + writeln(f,rand_H.val) + writeln(f,rand_I.val) + writeln(f,rand_S.val) + writeln(f,rand_L.val) + filemessage = 'Settings saved to file.' + f.close() + +#-------------------------------------------------- +# load settings from .ant file +def LoadPreset(FName): + global iScale, Offset, Invert, NSize, Sx, Sy, Lx, Ly + global NType, Basis, musgr, tBasismod, vlnoi, vlnoiTwo, voron, turbOne, turbTwo, marbleOne, marbleTwo, musgrTwo + global CustomFX, effect_image, Effect_Ctrl, Min, Max, Falloff, CustomFilt, Filter_Mode, Def_Filter_Ctrl, Ipo_Filter_Ctrl, Filter_Order + global RandMod, RSeed, rand_H, rand_S, rand_L, rand_I, filemessage, fileinfo + + try: + f = open(FName,'r') + FVersion = readstr(f) + except: + filemessage = "Unable to open file." + return + + fileinfo = readstr(f) + iScale[0].val = readfloat(f) + iScale[1].val = readfloat(f) + iScale[2].val = readfloat(f) + Offset[0].val = readfloat(f) + Offset[1].val = readfloat(f) + Offset[2].val = readfloat(f) + Invert[0].val = readint(f) + Invert[1].val = readint(f) + Invert[2].val = readint(f) + NSize[0].val = readfloat(f) + NSize[1].val = readfloat(f) + Sx[0].val = readfloat(f) + Sx[1].val = readfloat(f) + Sy[0].val = readfloat(f) + Sy[1].val = readfloat(f) + Lx[0].val = readfloat(f) + Lx[1].val = readfloat(f) + Ly[0].val = readfloat(f) + Ly[1].val = readfloat(f) + NType.val = readint(f) + Basis[0].val = readint(f) + Basis[1].val = readint(f) + musgr[0].val = readfloat(f) + musgr[1].val = readfloat(f) + musgr[2].val = readint(f) + musgr[3].val = readfloat(f) + musgr[4].val = readfloat(f) + musgr[5].val = readfloat(f) + tBasismod.val = readint(f) + vlnoi[0].val = readfloat(f) + vlnoi[1].val = readint(f) + vlnoiTwo[0].val = readfloat(f) + vlnoiTwo[1].val = readint(f) + voron[0].val = readint(f) + voron[1].val = readfloat(f) + turbOne[0].val = readint(f) + turbOne[1].val = readint(f) + turbOne[2].val = readfloat(f) + turbOne[3].val = readfloat(f) + turbTwo[0].val = readint(f) + turbTwo[1].val = readint(f) + turbTwo[2].val = readfloat(f) + turbTwo[3].val = readfloat(f) + marbleOne[0].val = readint(f) + marbleOne[1].val = readint(f) + marbleOne[2].val = readfloat(f) + marbleOne[3].val = readint(f) + marbleOne[4].val = readint(f) + marbleOne[5].val = readfloat(f) + marbleTwo[0].val = readint(f) + marbleTwo[1].val = readint(f) + marbleTwo[2].val = readfloat(f) + marbleTwo[3].val = readint(f) + marbleTwo[4].val = readint(f) + marbleTwo[5].val = readfloat(f) + musgrTwo[0].val = readfloat(f) + musgrTwo[1].val = readfloat(f) + musgrTwo[2].val = readint(f) + musgrTwo[3].val = readfloat(f) + musgrTwo[4].val = readfloat(f) + effect_image = readstr(f) + Effect_Ctrl[0].val = readint(f) + Effect_Ctrl[1].val = readint(f) + Effect_Ctrl[2].val = readfloat(f) + Effect_Ctrl[3].val = readint(f) + Effect_Ctrl[4].val = readfloat(f) + Effect_Ctrl[5].val = readint(f) + Effect_Ctrl[6].val = readfloat(f) + Effect_Ctrl[7].val = readfloat(f) + Effect_Ctrl[8].val = readfloat(f) + CustomFX[0].val = readstr(f) + CustomFX[1].val = readstr(f) + CustomFX[2].val = readstr(f) + Min.val = readfloat(f) + Max.val = readfloat(f) + Falloff[0].val = readint(f) + Falloff[1].val = readfloat(f) + Falloff[2].val = readfloat(f) + Falloff[3].val = readint(f) + Falloff[4].val = readint(f) + Filter_Mode.val = readint(f) + Filter_Order.val = readint(f) + CustomFilt[0].val = readstr(f) + CustomFilt[1].val = readstr(f) + CustomFilt[2].val = readstr(f) + Def_Filter_Ctrl[0].val = readint(f) + Def_Filter_Ctrl[1].val = readfloat(f) + Ipo_Filter_Ctrl[0].val = readstr(f) + Ipo_Filter_Ctrl[1].val = readint(f) + Ipo_Filter_Ctrl[2].val = readfloat(f) + Ipo_Filter_Ctrl[3].val = readfloat(f) + RandMod.val = readint(f) + RSeed.val = readint(f) + rand_H.val = readint(f) + rand_I.val = readint(f) + rand_S.val = readint(f) + rand_L.val = readint(f) + filemessage = 'Settings loaded from file.' + f.close() + +##--------------------------------------------------------------------------- +# Register: + +Register( drawgui, events, bevents ) +###-------------------------------------------------------------------------- + \ No newline at end of file From ee1c29028d924c1ee7520d547da98b3fd88ece05 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 11 May 2009 12:41:48 +0000 Subject: [PATCH 206/444] BGE: Add MT_Vector3 support for Py attribute macro system. See KX_PYATTRIBUTE_VECTOR_... --- .../ketsji/network/KX_network.vcproj | 12 +-- .../gameengine/Expressions/PyObjectPlus.cpp | 52 ++++++++++- source/gameengine/Expressions/PyObjectPlus.h | 86 +++++++++++-------- .../Ketsji/KXNetwork/CMakeLists.txt | 1 + source/gameengine/Ketsji/KXNetwork/Makefile | 1 + source/gameengine/Ketsji/KXNetwork/SConscript | 2 +- 6 files changed, 108 insertions(+), 46 deletions(-) diff --git a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj index b6d3aa5e4bb..fc197d0d1f4 100644 --- a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj +++ b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj @@ -43,7 +43,7 @@ (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); diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index b69697f3290..45797fe7975 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -38,6 +38,7 @@ #include "KX_Python.h" #include "STR_String.h" +#include "MT_Vector3.h" #include "SG_QList.h" /*------------------------------ @@ -328,6 +329,7 @@ enum KX_PYATTRIBUTE_TYPE { KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_TYPE_DUMMY, KX_PYATTRIBUTE_TYPE_FUNCTION, + KX_PYATTRIBUTE_TYPE_VECTOR, }; enum KX_PYATTRIBUTE_ACCESS { @@ -365,97 +367,105 @@ typedef struct KX_PYATTRIBUTE_DEF { int *m_intPtr; float *m_floatPtr; STR_String *m_stringPtr; + MT_Vector3 *m_vectorPtr; } m_typeCheck; } PyAttributeDef; #define KX_PYATTRIBUTE_DUMMY(name) \ - { name, KX_PYATTRIBUTE_TYPE_DUMMY, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_DUMMY, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \ - { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL} } // enum field cannot be mapped to pointer (because we would need a pointer for each enum) // use field size to verify mapping at runtime only, assuming enum size is equal to int size. #define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \ - { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} } // SHORT_LIST #define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_RO(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} } // INT_LIST #define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} } // always clamp for float #define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} } + { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} } #define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \ - { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} } + { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} } #define KX_PYATTRIBUTE_STRING_RO(name,object,field) \ - { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} } + { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} } + +#define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \ + { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} } +#define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \ + { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} } +#define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \ + { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field} } #define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \ - { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \ - { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \ - { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \ - { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL} } /*------------------------------ diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt index eb1d5fc67a3..999e7148039 100644 --- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt +++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt @@ -30,6 +30,7 @@ SET(INC . ../../../../source/kernel/gen_system ../../../../intern/string + ../../../../intern/moto/include ../../../../source/gameengine/Ketsji ../../../../source/gameengine/GameLogic ../../../../source/gameengine/Expressions diff --git a/source/gameengine/Ketsji/KXNetwork/Makefile b/source/gameengine/Ketsji/KXNetwork/Makefile index ec3099611e0..8c626d344f5 100644 --- a/source/gameengine/Ketsji/KXNetwork/Makefile +++ b/source/gameengine/Ketsji/KXNetwork/Makefile @@ -38,6 +38,7 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../Expressions CPPFLAGS += -I../../GameLogic CPPFLAGS += -I../../Scenegraph diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 9dc68669b4a..5d9dd1464b3 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('*.cpp') -incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Ketsji' +incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Ketsji' incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions' incs += ' #source/gameengine/Network #source/gameengine/SceneGraph' From 0c6ec76a4c7de61e84cc4dddbbda1698b7bf2a4b Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Mon, 11 May 2009 15:34:46 +0000 Subject: [PATCH 207/444] Fix Makefiles for gameengine. --- source/gameengine/Expressions/Makefile | 2 +- source/gameengine/GameLogic/Joystick/Makefile | 2 +- source/gameengine/GameLogic/Makefile | 2 +- source/gameengine/Ketsji/KXNetwork/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile index a1400c4e461..f46c0037200 100644 --- a/source/gameengine/Expressions/Makefile +++ b/source/gameengine/Expressions/Makefile @@ -41,5 +41,5 @@ CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../kernel/gen_system -CPPFLAGS += -I../../gameengine/Scenegraph +CPPFLAGS += -I../../gameengine/SceneGraph diff --git a/source/gameengine/GameLogic/Joystick/Makefile b/source/gameengine/GameLogic/Joystick/Makefile index 7016f1ed16f..02def1cec62 100644 --- a/source/gameengine/GameLogic/Joystick/Makefile +++ b/source/gameengine/GameLogic/Joystick/Makefile @@ -40,5 +40,5 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += $(NAN_SDLCFLAGS) - +CPPFLAGS += -I../../SceneGraph CPPFLAGS += -I../../../kernel/gen_system diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile index 6e9af674549..a1794a60452 100644 --- a/source/gameengine/GameLogic/Makefile +++ b/source/gameengine/GameLogic/Makefile @@ -39,7 +39,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I../Expressions -CPPFLAGS += -I../Scenegraph +CPPFLAGS += -I../SceneGraph CPPFLAGS += -I../Rasterizer CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/Ketsji/KXNetwork/Makefile b/source/gameengine/Ketsji/KXNetwork/Makefile index 8c626d344f5..365ed8fc9c3 100644 --- a/source/gameengine/Ketsji/KXNetwork/Makefile +++ b/source/gameengine/Ketsji/KXNetwork/Makefile @@ -41,7 +41,7 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I../../Expressions CPPFLAGS += -I../../GameLogic -CPPFLAGS += -I../../Scenegraph +CPPFLAGS += -I../../SceneGraph CPPFLAGS += -I../../Network CPPFLAGS += -I../../../kernel/gen_system CPPFLAGS += -I.. From c24a81a29385f177771e1d1957c8980e25e0856d Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Mon, 11 May 2009 16:57:54 +0000 Subject: [PATCH 208/444] Remove incorrect "w" attribute from Eulers, gave warning in epydocs. --- source/blender/python/api2_2x/doc/Mathutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index 7ca10c53d02..d8492558317 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -546,7 +546,7 @@ class Euler: The Euler object ================ This object gives access to Eulers in Blender. - @group Axises: x, y, z, w + @group Axises: x, y, z @ivar x: The heading value in degrees. @ivar y: The pitch value in degrees. @ivar z: The roll value in degrees. From 0aeaf08242631cd53a2d1065b3a7686d0022d77c Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Mon, 11 May 2009 19:19:36 +0000 Subject: [PATCH 209/444] Ugh, yet another try to fix [#18697] 2.49RC1: Keyed Particles fine in viewport but give me a crash during render. Hopefully it's now fixed for good. --- source/blender/blenkernel/intern/particle.c | 12 +++++++++++- source/blender/blenkernel/intern/particle_system.c | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 0ebdcdf58e0..41ce23347a3 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -351,8 +351,18 @@ void free_hair(ParticleSystem *psys, int softbody) } void free_keyed_keys(ParticleSystem *psys) { - if(psys->particles && psys->particles->keys) + ParticleData *pa; + int i; + + if(psys->particles && psys->particles->keys) { MEM_freeN(psys->particles->keys); + + for(i=0, pa=psys->particles; itotpart; i++, pa++) + if(pa->keys) { + pa->keys= NULL; + pa->totkey= 0; + } + } } void free_child_path_cache(ParticleSystem *psys) { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index f74e32acdbf..3445556b53b 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -203,7 +203,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) if(psys->particles->keys) MEM_freeN(psys->particles->keys); - for(i=totsaved, pa=psys->particles+totsaved; itotpart; i++, pa++) + for(i=0, pa=psys->particles; itotpart; i++, pa++) if(pa->keys) { pa->keys= NULL; pa->totkey= 0; From e847bcf784f2f5b8006d836789fb0c42a0d68e35 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 21:35:38 +0000 Subject: [PATCH 210/444] BGE Doc updates thanks to Roelf de Kock --- Notes from Roelf, maybe some other BGE devs could help resolve these Here is what I have so far. I've left "TODO's" were there needs to be some more comments. The following things also need to be resolved: -KX_VehicleWrapper.getWheelOrientationQuaternion looks like it should return a quaternion but if I look at the code it looks like it returns a rotation matrix. -I still need to find out what exactly KX_VehicleWrapper.getWheelRotation is. I've got the return type but I would like to add some explanation for what it actualy means (and units if any). -BL_Shader.setNumberOfPasses ignores the parameter but from the comment in the code it looks like the parameter that is being set (it is harcoded to be =1) in setNumberOfPasses is not used. So I'm not sure if this method should be documented at all. --- source/gameengine/PyDoc/BL_Shader.py | 307 +++++++++--------- .../PyDoc/KX_PhysicsObjectWrapper.py | 63 ++-- source/gameengine/PyDoc/KX_VehicleWrapper.py | 196 ++++++----- source/gameengine/PyDoc/epy_docgen.sh | 2 +- 4 files changed, 294 insertions(+), 274 deletions(-) diff --git a/source/gameengine/PyDoc/BL_Shader.py b/source/gameengine/PyDoc/BL_Shader.py index 10e8b7c94ef..8fd4ae7c7ac 100644 --- a/source/gameengine/PyDoc/BL_Shader.py +++ b/source/gameengine/PyDoc/BL_Shader.py @@ -5,227 +5,244 @@ class BL_Shader(PyObjectPlus): """ BL_Shader GLSL shaders. - All placeholders have a __ prefix + TODO - Description """ - def __setUniformfv(val): + def setUniformfv(name, fList): """ - TODO - Description + Set a uniform with a list of float values - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string - @rtype: integer - @return: TODO Description + @param fList: a list (2, 3 or 4 elements) of float values + @type fList: list[float] """ - def __delSource(val): + def delSource(): """ TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + """ - def __getFragmentProg(val): + def getFragmentProg(): """ - TODO - Description + Returns the fragment program. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @rtype: string + @return: The fragment program. """ - def __getVertexProg(val): + def getVertexProg(): """ - TODO - Description + Get the vertex program. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @rtype: string + @return: The vertex program. """ - def __isValid(val): + def isValid(): """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + Check if the shader is valid. + + @rtype: bool + @return: True if the shader is valid """ - def __setAttrib(val): + def setAttrib(enum): """ - TODO - Description + Set attribute location. (The parameter is ignored a.t.m. and the value of "tangent" is always used.) - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param enum: attribute location value + @type enum: integer """ - def __setNumberOfPasses(val): + def setNumberOfPasses( max_pass ): """ - TODO - Description + Set the maximum number of passes. Not used a.t.m. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param max_pass: the maximum number of passes + @type max_pass: integer """ - def __setSampler(val): + def setSampler(name, index): """ - TODO - Description + Set uniform texture sample index. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param name: Uniform name + @type name: string + + @param index: Texture sample index. + @type index: integer """ - def __setSource(val): + def setSource(vertexProgram, fragmentProgram): """ - TODO - Description + Set the vertex and fragment programs - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param vertexProgram: Vertex program + @type vertexProgram: string + + @param fragmentProgram: Fragment program + @type fragmentProgram: string """ - def __setUniform1f(val): + def setUniform1f(name, fx): """ - TODO - Description + Set a uniform with 1 float value. - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string - @rtype: integer - @return: TODO Description + @param fx: Uniform value + @type fx: float """ - def __setUniform1i(val): + def setUniform1i(name, ix): """ - TODO - Description + Set a uniform with an integer value. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param name: the uniform name + @type name: string + + @param ix: the uniform value + @type ix: integer """ - def __setUniform2f(val): + def setUniform2f(name, fx, fy): """ - TODO - Description + Set a uniform with 2 float values - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param fx: first float value + @type fx: float - @rtype: integer - @return: TODO Description + @param fy: second float value + @type fy: float """ - def __setUniform2i(val): + def setUniform2i(name, ix, iy): """ - TODO - Description + Set a uniform with 2 integer values - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param ix: first integer value + @type ix: integer - @rtype: integer - @return: TODO Description + @param iy: second integer value + @type iy: integer """ - def __setUniform3f(val): + def setUniform3f(name, fx,fy,fz): """ - TODO - Description + Set a uniform with 3 float values. - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param fx: first float value + @type fx: float - @rtype: integer - @return: TODO Description + @param fy: second float value + @type fy: float + + @param fz: third float value + @type fz: float """ - def __setUniform3i(val): + def setUniform3i(name, ix,iy,iz): """ - TODO - Description + Set a uniform with 3 integer values - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param ix: first integer value + @type ix: integer - @rtype: integer - @return: TODO Description + @param iy: second integer value + @type iy: integer + + @param iz: third integer value + @type iz: integer """ - def __setUniform4f(val): + def setUniform4f(name, fx,fy,fz,fw): """ - TODO - Description + Set a uniform with 4 float values. - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param fx: first float value + @type fx: float - @rtype: integer - @return: TODO Description + @param fy: second float value + @type fy: float + + @param fz: third float value + @type fz: float + + @param fw: fourth float value + @type fw: float """ - def __setUniform4i(val): + def setUniform4i(name, ix,iy,iz, iw): """ - TODO - Description + Set a uniform with 4 integer values - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param ix: first integer value + @type ix: integer - @rtype: integer - @return: TODO Description + @param iy: second integer value + @type iy: integer + + @param iz: third integer value + @type iz: integer + + @param iw: fourth integer value + @type iw: integer """ - def __setUniformDef(val): + def setUniformDef(name, type): """ - TODO - Description + Define a new uniform - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param name: the uniform name + @type name: string + + @param type: uniform type + @type type: UNI_NONE, UNI_INT, UNI_FLOAT, UNI_INT2, UNI_FLOAT2, UNI_INT3, UNI_FLOAT3, UNI_INT4, UNI_FLOAT4, UNI_MAT3, UNI_MAT4, UNI_MAX """ - def __setUniformMatrix3(val): + def setUniformMatrix3(name, mat, transpose): """ - TODO - Description + Set a uniform with a 3x3 matrix value - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param mat: A 3x3 matrix [[f,f,f], [f,f,f], [f,f,f]] + @type mat: 3x3 matrix - @rtype: integer - @return: TODO Description + @param transpose: set to True to transpose the matrix + @type transpose: bool """ - def __setUniformMatrix4(val): + def setUniformMatrix4(name, mat, transpose): """ - TODO - Description + Set a uniform with a 4x4 matrix value - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string + + @param mat: A 4x4 matrix [[f,f,f,f], [f,f,f,f], [f,f,f,f], [f,f,f,f]] + @type mat: 4x4 matrix - @rtype: integer - @return: TODO Description + @param transpose: set to True to transpose the matrix + @type transpose: bool """ - def __setUniformiv(val): + def setUniformiv(name, iList): """ - TODO - Description + Set a uniform with a list of integer values - @param val: the starting frame of the animation - @type val: float + @param name: the uniform name + @type name: string - @rtype: integer - @return: TODO Description + @param iList: a list (2, 3 or 4 elements) of integer values + @type iList: list[integer] """ - def __validate(val): + def validate(): """ - TODO - Description + Validate the shader object. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description """ diff --git a/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py b/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py index ea9a2a3a411..4cbdbf7cebb 100644 --- a/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py +++ b/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py @@ -4,46 +4,57 @@ class KX_PhysicsObjectWrapper(PyObjectPlus): """ KX_PhysicsObjectWrapper - All placeholders have a __ prefix """ - def __setActive(val): + def setActive(active): """ - TODO - Description + Set the object to be active. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param active: set to True to be active + @type active: bool """ - def __setAngularVelocity(val): + def setAngularVelocity(x, y, z, local): """ - TODO - Description + Set the angular velocity of the object. - @param val: the starting frame of the animation - @type val: float + @param x: angular velocity for the x-axis + @type x: float - @rtype: integer - @return: TODO Description + @param y: angular velocity for the y-axis + @type y: float + + @param z: angular velocity for the z-axis + @type z: float + + @param local: set to True for local axis + @type local: bool """ - def __setLinearVelocity(val): + def setLinearVelocity(x, y, z, local): """ - TODO - Description + Set the linear velocity of the object. - @param val: the starting frame of the animation - @type val: float + @param x: linear velocity for the x-axis + @type x: float - @rtype: integer - @return: TODO Description + @param y: linear velocity for the y-axis + @type y: float + + @param z: linear velocity for the z-axis + @type z: float + + @param local: set to True for local axis + @type local: bool """ - def __setPosition(val): + def setPosition(x, y, z): """ - TODO - Description + Set the position of the object - @param val: the starting frame of the animation - @type val: float + @param x: x coordinate + @type x: float - @rtype: integer - @return: TODO Description + @param y: y coordinate + @type y: float + + @param z: z coordinate + @type z: float """ diff --git a/source/gameengine/PyDoc/KX_VehicleWrapper.py b/source/gameengine/PyDoc/KX_VehicleWrapper.py index 3d91b7db676..86991634f2d 100644 --- a/source/gameengine/PyDoc/KX_VehicleWrapper.py +++ b/source/gameengine/PyDoc/KX_VehicleWrapper.py @@ -4,13 +4,13 @@ class KX_VehicleWrapper(PyObjectPlus): """ KX_VehicleWrapper - All placeholders have a __ prefix + TODO - description """ def addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering): """ - TODO - Description + Add a wheel to the vehicle @param wheel: The object to use as a wheel. @type wheel: L{KX_GameObject} or a KX_GameObject name @@ -26,143 +26,135 @@ class KX_VehicleWrapper(PyObjectPlus): @type wheelRadius: float """ - def __applyBraking(val): + def applyBraking(force, wheelIndex): """ - TODO - Description + Apply a braking force to the specified wheel - @param val: the starting frame of the animation - @type val: float + @param force: the brake force + @type force: float + + @param wheelIndex: index of the wheel where the force needs to be applied + @type wheelIndex: integer + """ + def applyEngineForce(force, wheelIndex): + """ + Apply an engine force to the specified wheel + + @param force: the engine force + @type force: float + + @param wheelIndex: index of the wheel where the force needs to be applied + @type wheelIndex: integer + """ + def getConstraintId(): + """ + Get the constraint ID @rtype: integer - @return: TODO Description + @return: the constraint id """ - def __applyEngineForce(val): + def getConstraintType(): """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float + Returns the constraint type. @rtype: integer - @return: TODO Description + @return: constraint type """ - def __getConstraintId(val): + def getNumWheels(): """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float + Returns the number of wheels. @rtype: integer + @return: the number of wheels for this vehicle + """ + def getWheelOrientationQuaternion(wheelIndex): + """ + Returns the wheel orientation as a quaternion. + + @param wheelIndex: the wheel index + @type wheelIndex: integer + + @rtype: TODO - type should be quat as per method name but from the code it looks like a matrix @return: TODO Description """ - def __getConstraintType(val): + def getWheelPosition(wheelIndex): """ - TODO - Description + Returns the position of the specified wheel - @param val: the starting frame of the animation - @type val: float + @param wheelIndex: the wheel index + @type wheelIndex: integer - @rtype: integer - @return: TODO Description + @rtype: list[x, y, z] + @return: position vector """ - def __getNumWheels(val): + def getWheelRotation(wheelIndex): """ - TODO - Description + Returns the rotation of the specified wheel - @param val: the starting frame of the animation - @type val: float + @param wheelIndex: the wheel index + @type wheelIndex: integer - @rtype: integer - @return: TODO Description + @rtype: float + @return: the wheel rotation """ - def __getWheelOrientationQuaternion(val): + def setRollInfluence(rollInfluece, wheelIndex): """ - TODO - Description + Set the specified wheel's roll influence. + The higher the roll influence the more the vehicle will tend to roll over in corners. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param rollInfluece: the wheel roll influence + @type rollInfluece: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer """ - def __getWheelPosition(val): + def setSteeringValue(steering, wheelIndex): """ - TODO - Description + Set the specified wheel's steering - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param steering: the wheel steering + @type steering: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer """ - def __getWheelRotation(val): + def setSuspensionCompression(compression, wheelIndex): """ - TODO - Description + Set the specified wheel's compression - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param compression: the wheel compression + @type compression: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer """ - def __setRollInfluence(val): + def setSuspensionDamping(damping, wheelIndex): """ - TODO - Description + Set the specified wheel's damping - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param damping: the wheel damping + @type damping: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer """ - def __setSteeringValue(val): + def setSuspensionStiffness(stiffness, wheelIndex): """ - TODO - Description + Set the specified wheel's stiffness - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param stiffness: the wheel stiffness + @type stiffness: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer """ - def __setSuspensionCompression(val): + def setTyreFriction(friction, wheelIndex): """ - TODO - Description + Set the specified wheel's tyre friction - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - def __setSuspensionDamping(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - def __setSuspensionStiffness(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - def __setTyreFriction(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @param friction: the tyre friction + @type friction: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer """ diff --git a/source/gameengine/PyDoc/epy_docgen.sh b/source/gameengine/PyDoc/epy_docgen.sh index ddf39dcc081..0872d2abbbd 100755 --- a/source/gameengine/PyDoc/epy_docgen.sh +++ b/source/gameengine/PyDoc/epy_docgen.sh @@ -8,4 +8,4 @@ LC_ALL=POSIX epydoc --debug -v -o BPY_GE --url "http://www.blender.org" --top GameLogic \ - --name "Blender GameEngine" --no-private --no-frames --no-sourcecode --inheritance=included *.py + --name "Blender GameEngine" --no-private --no-sourcecode --inheritance=included *.py From 24906dc9626c0acb40d8ee77070df7f95b58e0ce Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 11 May 2009 22:07:30 +0000 Subject: [PATCH 211/444] BGE #18724: Modifier cause crash in 2.49RC2. My bad, I was too quick to fix the soft body problem in revision 20119. This time I tested against modifiers, soft body, armatures and replace mesh. --- .../Converter/BL_BlenderDataConversion.cpp | 7 ++----- .../Converter/BL_DeformableGameObject.cpp | 13 +++++++++++++ .../gameengine/Converter/BL_DeformableGameObject.h | 5 +---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 7d0bbbe107c..09604e5c2e3 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2121,8 +2121,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, //tf.Add(gameobj->GetSGNode()); gameobj->NodeUpdateGS(0); - //move to after finishing everything so that soft body deformer is included - //gameobj->AddMeshUser(); + gameobj->AddMeshUser(); } else @@ -2312,8 +2311,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, //tf.Add(gameobj->GetSGNode()); gameobj->NodeUpdateGS(0); - //move to after finishing everything so that soft body deformer is included - //gameobj->AddMeshUser(); + gameobj->AddMeshUser(); } else { @@ -2665,7 +2663,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { KX_GameObject* gameobj = static_cast(objectlist->GetValue(i)); gameobj->ResetState(); - gameobj->AddMeshUser(); } #endif //CONVERT_LOGIC diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp index a9d5b643fd4..cb882f31e80 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.cpp +++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp @@ -30,6 +30,8 @@ #include "BL_DeformableGameObject.h" #include "BL_ShapeDeformer.h" #include "BL_ShapeActionActuator.h" +#include "RAS_MaterialBucket.h" + #ifdef HAVE_CONFIG_H #include @@ -101,3 +103,14 @@ bool BL_DeformableGameObject::GetShape(vector &shape) return !shape.empty(); } +void BL_DeformableGameObject::SetDeformer(class RAS_Deformer* deformer) +{ + m_pDeformer = deformer; + + SG_QList::iterator mit(m_meshSlots); + for(mit.begin(); !mit.end(); ++mit) + { + (*mit)->SetDeformer(deformer); + } +} + diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index dbc89bd2a20..b20b8e81b37 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -83,10 +83,7 @@ public: return (m_pDeformer) ? ((BL_MeshDeformer*)m_pDeformer)->GetMesh()->key : NULL; } - virtual void SetDeformer(class RAS_Deformer* deformer) - { - m_pDeformer = deformer; - } + virtual void SetDeformer(class RAS_Deformer* deformer); virtual class RAS_Deformer* GetDeformer() { return m_pDeformer; From b75268d412cdce0867a12e4234fd3843d44c5cba Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 11 May 2009 22:17:58 +0000 Subject: [PATCH 212/444] problem with unloading modules, py modules would be refreshed but external modules that were pyc or pyo's would be kept. This made it not refresh the module when taking an external BGE Module and making it internal because the external pyc would never be freed so the internal text wouldn't get used until restarting blender. --- source/blender/python/api2_2x/bpy_internal_import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/bpy_internal_import.c b/source/blender/python/api2_2x/bpy_internal_import.c index 125993cc425..3bc90eb4f54 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.c +++ b/source/blender/python/api2_2x/bpy_internal_import.c @@ -316,7 +316,7 @@ void bpy_text_clear_modules(int clear_all) if(fname) { if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */ file_extension = strstr(fname, ".py"); - if(file_extension && *(file_extension + 3) == '\0') { /* .py extension ? */ + if(file_extension && (*(file_extension + 3) == '\0' || *(file_extension + 4) == '\0')) { /* .py or pyc extension? */ /* now we can be fairly sure its a python import from the blendfile */ PyList_Append(list, key); /* free'd with the list */ } From 75b7bcab7711043e3475d8ef8d80770ed57abeda Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Mon, 11 May 2009 22:27:06 +0000 Subject: [PATCH 213/444] Python API ---------- Patch by Jean-michel Soler (jms) to support ShrinkWrap and SimpleDeform modifiers. --- source/blender/python/api2_2x/Modifier.c | 248 +++++++++++++++++- source/blender/python/api2_2x/doc/Modifier.py | 55 ++-- 2 files changed, 279 insertions(+), 24 deletions(-) diff --git a/source/blender/python/api2_2x/Modifier.c b/source/blender/python/api2_2x/Modifier.c index b43c810b435..49220bcd05e 100644 --- a/source/blender/python/api2_2x/Modifier.c +++ b/source/blender/python/api2_2x/Modifier.c @@ -64,17 +64,19 @@ enum mod_constants { EXPP_MOD_ONCAGE, /*GENERIC*/ - EXPP_MOD_OBJECT, /*ARMATURE, LATTICE, CURVE, BOOLEAN, ARRAY*/ - EXPP_MOD_VERTGROUP, /*ARMATURE, LATTICE, CURVE, SMOOTH, CAST*/ + EXPP_MOD_OBJECT, /*ARMATURE, LATTICE, CURVE, BOOLEAN, ARRAY, + SHRINKWRAP, SIMPLEDEFORM*/ + EXPP_MOD_VERTGROUP, /*ARMATURE, LATTICE, CURVE, SMOOTH, CAST, + SHRINKWRAP, SIMPLEDEFORM */ EXPP_MOD_LIMIT, /*ARRAY, MIRROR*/ EXPP_MOD_FLAG, /*MIRROR, WAVE*/ EXPP_MOD_COUNT, /*DECIMATOR, ARRAY*/ EXPP_MOD_LENGTH, /*BUILD, ARRAY*/ - EXPP_MOD_FACTOR, /*SMOOTH, CAST*/ + EXPP_MOD_FACTOR, /*SMOOTH, CAST, SIMPLEDEFORM*/ EXPP_MOD_ENABLE_X, /*SMOOTH, CAST*/ EXPP_MOD_ENABLE_Y, /*SMOOTH, CAST*/ EXPP_MOD_ENABLE_Z, /*SMOOTH, CAST*/ - EXPP_MOD_TYPES, /*SUBSURF, CAST*/ + EXPP_MOD_TYPES, /*SUBSURF, CAST, SHRINKWRAP, SIMPLEDEFORM*/ /*SUBSURF SPECIFIC*/ EXPP_MOD_LEVELS, @@ -144,8 +146,29 @@ enum mod_constants { EXPP_MOD_RADIUS, EXPP_MOD_SIZE, EXPP_MOD_USE_OB_TRANSFORM, - EXPP_MOD_SIZE_FROM_RADIUS - + EXPP_MOD_SIZE_FROM_RADIUS, + + /* SHRINKWRAP*/ + EXPP_MOD_OBJECT_AUX, + EXPP_MOD_KEEPDIST, + EXPP_MOD_PROJECT_OVER_X_AXIS, + EXPP_MOD_PROJECT_OVER_Y_AXIS, + EXPP_MOD_PROJECT_OVER_Z_AXIS, + EXPP_MOD_PROJECT_OVER_NORMAL, + EXPP_MOD_SUBSURFLEVELS, + EXPP_MOD_ALLOW_POS_DIR, + EXPP_MOD_ALLOW_NEG_DIR, + EXPP_MOD_CULL_TARGET_FRONTFACE, + EXPP_MOD_CULL_TARGET_BACKFACE, + EXPP_MOD_KEEP_ABOVE_SURFACE, + + /* SIMPLEDEFORM*/ + EXPP_MOD_RELATIVE, + EXPP_MOD_LOWER_LIMIT, + EXPP_MOD_UPPER_LIMIT, + EXPP_MOD_LOCK_AXIS_X, + EXPP_MOD_LOCK_AXIS_Y + /* yet to be implemented */ /* EXPP_MOD_HOOK_,*/ /* , */ @@ -989,6 +1012,43 @@ static PyObject *shrinkwrap_getter( BPy_Modifier * self, int type ) switch( type ) { case EXPP_MOD_OBJECT: return Object_CreatePyObject( md->target ); + case EXPP_MOD_OBJECT_AUX: + return Object_CreatePyObject( md->auxTarget ); + case EXPP_MOD_VERTGROUP: + return PyString_FromString( md->vgroup_name ) ; + case EXPP_MOD_TYPES: + return PyInt_FromLong( (long)md->shrinkType ); + case EXPP_MOD_ALLOW_POS_DIR: + return PyBool_FromLong( ( long ) + ( md->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) ) ; + case EXPP_MOD_ALLOW_NEG_DIR: + return PyBool_FromLong( ( long ) + ( md->shrinkOpts & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) ) ; + case EXPP_MOD_CULL_TARGET_FRONTFACE: + return PyBool_FromLong( ( long ) + ( md->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) ) ; + case EXPP_MOD_CULL_TARGET_BACKFACE: + return PyBool_FromLong( ( long ) + ( md->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) ) ; + case EXPP_MOD_KEEP_ABOVE_SURFACE: + return PyBool_FromLong( ( long ) + ( md->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) ) ; + case EXPP_MOD_KEEPDIST: + return PyFloat_FromDouble( (double)md->keepDist ); + case EXPP_MOD_PROJECT_OVER_X_AXIS: + return PyBool_FromLong( ( long ) + ( md->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) ) ; + case EXPP_MOD_PROJECT_OVER_Y_AXIS: + return PyBool_FromLong( ( long ) + ( md->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) ) ; + case EXPP_MOD_PROJECT_OVER_Z_AXIS: + return PyBool_FromLong( ( long ) + ( md->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) ) ; + case EXPP_MOD_PROJECT_OVER_NORMAL: + return PyBool_FromLong( ( long ) + ( md->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) ) ; + case EXPP_MOD_SUBSURFLEVELS: + return PyInt_FromLong( ( long )md->subsurfLevels ); default: return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" ); } @@ -1012,11 +1072,144 @@ static int shrinkwrap_setter( BPy_Modifier *self, int type, PyObject *value ) } return 0; } + case EXPP_MOD_OBJECT_AUX: { + Object *ob_new=NULL; + if (value == Py_None) { + md->auxTarget = NULL; + } else if (BPy_Object_Check( value )) { + ob_new = ((( BPy_Object * )value)->object); + md->auxTarget = ob_new; + } else { + return EXPP_ReturnIntError( PyExc_TypeError, + "Expected an Object or None value" ); + } + return 0; + } + case EXPP_MOD_VERTGROUP:{ + char *defgrp_name = PyString_AsString( value ); + if( !defgrp_name ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected string arg" ); + BLI_strncpy( md->vgroup_name, defgrp_name, sizeof( md->vgroup_name ) ); + return 0; + } + case EXPP_MOD_TYPES: + return EXPP_setIValueRange( value, &md->shrinkType, 0, + MOD_SHRINKWRAP_NEAREST_VERTEX, 'h' ); + case EXPP_MOD_KEEPDIST: + return EXPP_setFloatClamped( value, &md->keepDist, -1000.0, +1000.0 ); + case EXPP_MOD_PROJECT_OVER_X_AXIS: + return EXPP_setBitfield( value, &md->projAxis, + MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS, 'h' ); + case EXPP_MOD_PROJECT_OVER_Y_AXIS: + return EXPP_setBitfield( value, &md->projAxis, + MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS, 'h' ); + case EXPP_MOD_PROJECT_OVER_Z_AXIS: + return EXPP_setBitfield( value, &md->projAxis, + MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS, 'h' ); + case EXPP_MOD_PROJECT_OVER_NORMAL: + return EXPP_setBitfield( value, &md->projAxis, + MOD_SHRINKWRAP_PROJECT_OVER_NORMAL, 'h' ); + + case EXPP_MOD_ALLOW_POS_DIR: + return EXPP_setBitfield( value, &md->shrinkOpts, + MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR, 'h' ); + case EXPP_MOD_ALLOW_NEG_DIR: + return EXPP_setBitfield( value, &md->shrinkOpts, + MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR, 'h' ); + case EXPP_MOD_CULL_TARGET_FRONTFACE: + return EXPP_setBitfield( value, &md->shrinkOpts, + MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE, 'h' ); + case EXPP_MOD_CULL_TARGET_BACKFACE: + return EXPP_setBitfield( value, &md->shrinkOpts, + MOD_SHRINKWRAP_CULL_TARGET_BACKFACE, 'h' ); + case EXPP_MOD_KEEP_ABOVE_SURFACE: + return EXPP_setBitfield( value, &md->shrinkOpts, + MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE, 'h' ); + case EXPP_MOD_SUBSURFLEVELS: + return EXPP_setIValueClamped( value, &md->subsurfLevels, 1, 6, 'h' ); + default: return EXPP_ReturnIntError( PyExc_KeyError, "key not found" ); } } +static PyObject *simpledeform_getter( BPy_Modifier * self, int type ) +{ + SimpleDeformModifierData *md = (SimpleDeformModifierData *)(self->md); + + switch( type ) { + case EXPP_MOD_OBJECT: + return Object_CreatePyObject( md->origin ); + case EXPP_MOD_TYPES: + return PyInt_FromLong( (long)md->mode ); + case EXPP_MOD_FACTOR: + return PyFloat_FromDouble( (double)md->factor ); + case EXPP_MOD_UPPER_LIMIT: + return PyFloat_FromDouble( (double)md->limit[1] ); + case EXPP_MOD_LOWER_LIMIT: + return PyFloat_FromDouble( (double)md->limit[0] ); + case EXPP_MOD_VERTGROUP: + return PyString_FromString( md->vgroup_name ) ; + case EXPP_MOD_RELATIVE: + return PyBool_FromLong( (long) md->originOpts ) ; + case EXPP_MOD_LOCK_AXIS_X: + return PyBool_FromLong( (long) + ( md->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) ) ; + case EXPP_MOD_LOCK_AXIS_Y: + return PyBool_FromLong( (long) + ( md->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) ) ; + default: + return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" ); + } +} + +static int simpledeform_setter( BPy_Modifier *self, int type, PyObject *value ) +{ + SimpleDeformModifierData *md = (SimpleDeformModifierData *)(self->md); + + switch( type ) { + case EXPP_MOD_OBJECT: { /* Only object for now */ + Object *ob_new=NULL; + if (value == Py_None) { + md->origin = NULL; + } else if (BPy_Object_Check( value )) { + ob_new = ((( BPy_Object * )value)->object); + md->origin = ob_new; + } else { + return EXPP_ReturnIntError( PyExc_TypeError, + "Expected an Object or None value" ); + } + return 0; + } + case EXPP_MOD_TYPES: + return EXPP_setIValueRange( value, &md->mode, 1, MOD_SIMPLEDEFORM_MODE_STRETCH, 'h' ); + case EXPP_MOD_FACTOR: + return EXPP_setFloatClamped( value, &md->factor, -10.0, 10.0 ); + case EXPP_MOD_LOWER_LIMIT: + return EXPP_setFloatClamped( value, &md->limit[0], 0.0, md->limit[1] ); + case EXPP_MOD_UPPER_LIMIT: + return EXPP_setFloatClamped( value, &md->limit[1], md->limit[0], 1.0 ); + case EXPP_MOD_VERTGROUP:{ + char *defgrp_name = PyString_AsString( value ); + if( !defgrp_name ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected string arg" ); + BLI_strncpy( md->vgroup_name, defgrp_name, sizeof( md->vgroup_name ) ); + return 0; + } + case EXPP_MOD_RELATIVE: + return EXPP_setBitfield( value, &md->originOpts, 1, 'h' ); + case EXPP_MOD_LOCK_AXIS_X: + return EXPP_setBitfield( value, &md->axis, + MOD_SIMPLEDEFORM_LOCK_AXIS_X, 'h' ); + case EXPP_MOD_LOCK_AXIS_Y: + return EXPP_setBitfield( value, &md->axis, + MOD_SIMPLEDEFORM_LOCK_AXIS_Y, 'h' ); + default: + return EXPP_ReturnIntError( PyExc_KeyError, "key not found" ); + } +} /* static PyObject *uvproject_getter( BPy_Modifier * self, int type ) { @@ -1100,7 +1293,9 @@ static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key ) case eModifierType_Shrinkwrap: return shrinkwrap_getter( self, setting ); /*case eModifierType_UVProject: - return uvproject_getter( self, setting );*/ + return uvproject_getter( self, setting );*/ + case eModifierType_SimpleDeform: + return simpledeform_getter( self, setting ); case eModifierType_Hook: case eModifierType_Softbody: case eModifierType_None: @@ -1171,6 +1366,8 @@ static int Modifier_setData( BPy_Modifier * self, PyObject * key, return displace_setter( self, key_int, arg ); case eModifierType_Shrinkwrap: return shrinkwrap_setter( self, key_int, arg ); + case eModifierType_SimpleDeform: + return simpledeform_setter( self, key_int, arg ); /*case eModifierType_UVProject: return uvproject_setter( self, key_int, arg );*/ case eModifierType_Hook: @@ -1603,8 +1800,8 @@ static PyObject *M_Modifier_TypeDict( void ) PyInt_FromLong( eModifierType_Bevel ) ); PyConstant_Insert( d, "SHRINKWRAP", PyInt_FromLong( eModifierType_Shrinkwrap ) ); - PyConstant_Insert( d, "SHRINKWRAP", - PyInt_FromLong( eModifierType_Shrinkwrap ) ); + PyConstant_Insert( d, "SIMPLEDEFORM", + PyInt_FromLong( eModifierType_SimpleDeform ) ); } return S; } @@ -1768,6 +1965,39 @@ for var in st.replace(',','').split('\n'): PyConstant_Insert( d, "SIZE_FROM_RADIUS", PyInt_FromLong( EXPP_MOD_SIZE_FROM_RADIUS ) ); /*End Auto generated code*/ + PyConstant_Insert( d, "RELATIVE", + PyInt_FromLong( EXPP_MOD_RELATIVE ) ); + PyConstant_Insert( d, "UPPER_LIMIT", + PyInt_FromLong( EXPP_MOD_UPPER_LIMIT ) ); + PyConstant_Insert( d, "LOWER_LIMIT", + PyInt_FromLong( EXPP_MOD_LOWER_LIMIT ) ); + PyConstant_Insert( d, "LOCK_AXIS_X", + PyInt_FromLong( EXPP_MOD_LOCK_AXIS_X ) ); + PyConstant_Insert( d, "LOCK_AXIS_Y", + PyInt_FromLong( EXPP_MOD_LOCK_AXIS_Y ) ); + + PyConstant_Insert( d, "OBJECT_AUX", + PyInt_FromLong( EXPP_MOD_OBJECT_AUX ) ); + PyConstant_Insert( d, "KEEPDIST", + PyInt_FromLong( EXPP_MOD_KEEPDIST ) ); + PyConstant_Insert( d, "PROJECT_OVER_X_AXIS", + PyInt_FromLong( EXPP_MOD_PROJECT_OVER_X_AXIS ) ); + PyConstant_Insert( d, "PROJECT_OVER_Y_AXIS", + PyInt_FromLong( EXPP_MOD_PROJECT_OVER_Y_AXIS ) ); + PyConstant_Insert( d, "PROJECT_OVER_Z_AXIS", + PyInt_FromLong( EXPP_MOD_PROJECT_OVER_Z_AXIS ) ); + PyConstant_Insert( d, "SUBSURFLEVELS", + PyInt_FromLong( EXPP_MOD_SUBSURFLEVELS ) ); + PyConstant_Insert( d, "ALLOW_POS_DIR", + PyInt_FromLong( EXPP_MOD_ALLOW_POS_DIR ) ); + PyConstant_Insert( d, "ALLOW_NEG_DIR", + PyInt_FromLong( EXPP_MOD_ALLOW_NEG_DIR ) ); + PyConstant_Insert( d, "CULL_TARGET_FRONTFACE", + PyInt_FromLong( EXPP_MOD_CULL_TARGET_FRONTFACE ) ); + PyConstant_Insert( d, "CULL_TARGET_BACKFACE", + PyInt_FromLong( EXPP_MOD_CULL_TARGET_BACKFACE ) ); + PyConstant_Insert( d, "KEEP_ABOVE_SURFACE", + PyInt_FromLong( EXPP_MOD_KEEP_ABOVE_SURFACE ) ); } return S; } diff --git a/source/blender/python/api2_2x/doc/Modifier.py b/source/blender/python/api2_2x/doc/Modifier.py index 03b868d3605..8b62a7270f0 100644 --- a/source/blender/python/api2_2x/doc/Modifier.py +++ b/source/blender/python/api2_2x/doc/Modifier.py @@ -50,18 +50,23 @@ Example:: modifier sequence and comparing with L{Modifier.type}: - ARMATURE - type value for Armature modifiers - ARRAY - type value for Array modifiers - - BOOLEAN - type value for Boolean modifiers + - BEVEL - type value for Bevel modifiers + - BOOLEAN - type value for Boolean modifiers - BUILD - type value for Build modifiers - - CURVE - type value for Curve modifiers - - MIRROR - type value for Mirror modifiers - - DECIMATE - type value for Decimate modifiers - - LATTICE - type value for Lattice modifiers - - SUBSURF - type value for Subsurf modifiers - - WAVE - type value for Wave modifiers - - EDGESPLIT - type value for Edge Split modifiers - - DISPLACE - type value for Displace modifiers - - SMOOTH - type value for Smooth modifiers - CAST - type value for Cast modifiers + - CURVE - type value for Curve modifiers + - DECIMATE - type value for Decimate modifiers + - DISPLACE - type value for Displace modifiers + - EDGESPLIT - type value for Edge Split modifiers + - LATTICE - type value for Lattice modifiers + - MESHDEFORM - type value for MeshDeform modifiers + - MASK - type value for Mask modifiers + - MIRROR - type value for Mirror modifiers + - SHRINKWRAP - type value for Shrinkwrap modifiers + - SIMPLEDEFORM - type value for SimpleDeform modifiers + - SMOOTH - type value for Smooth modifiers + - SUBSURF - type value for Subsurf modifiers + - WAVE - type value for Wave modifiers @type Settings: readonly dictionary @var Settings: Constant Modifier dict used for changing modifier settings. @@ -70,17 +75,17 @@ Example:: - EDITMODE - Used for all modifiers (bool) If both REALTIME and EDITMODE are true, the modifier is enabled for interactive display while the object is in edit mode. - ONCAGE - Used for all modifiers (bool) If true, the modifier is enabled for the editing cage during edit mode. - - OBJECT - Used for Armature, Lattice, Curve, Boolean and Array (Object) - - VERTGROUP - Used for Armature, Lattice, Curve, Smooth and Cast (String) - - LIMIT - Array and Mirror (float [0.0 - 1.0]) + - OBJECT - Used for Armature, Lattice, Curve, Boolean, Array, Shrinkwrap and SimpleDeform (Object) + - VERTGROUP - Used for Armature, Lattice, Curve, Smooth, Cast, Shrinkwrap and SimpleDeform (String) + - LIMIT - Array, Mirror (float [0.0 - 1.0]) - FLAG - Mirror and Wave (int) - COUNT - Decimator Polycount (readonly) and Array (int) - LENGTH - Build [1.0-300000.0] and Array [0.0 - 10000.0] (float) - - FACTOR - Smooth [-10.0, 10.0] and Cast [-10.0, 10.0] (float) + - FACTOR - Smooth [-10.0, 10.0], Cast [-10.0, 10.0] and SimpleDeform [-10.0, 10.0] (float) - ENABLE_X = Smooth and Cast (bool, default: True) - ENABLE_Y = Smooth and Cast (bool, default: True) - ENABLE_Z = Smooth and Cast (bool, default: True) - - TYPES - Subsurf and Cast. For Subsurf it determines the subdivision algorithm - (int): 0 = Catmull-Clark; 1 = simple subdivision. For Cast it determines the shape to deform to = (int): 0 = Sphere; 1 = Cylinder; 2 = Cuboid + - TYPES - Subsurf, Cast, Shrinkwrap and SimpleDeform. For Subsurf it determines the subdivision algorithm - (int): 0 = Catmull-Clark; 1 = simple subdivision. For Cast it determines the shape to deform to = (int): 0 = Sphere; 1 = Cylinder; 2 = Cuboid. For Shrinkwrap it determines where it has to project = (int): 0 = Nearest surface; 1 = Project; 2 = Nearest vertex. For DeformMesh it determines the function to apply = (int): 1 = Twist; 2 = Bend; 3 = Taper; 4 = Stretch. - LEVELS - Used for Subsurf only (int [0 - 6]). The number of subdivision levels used for interactive display. - RENDLEVELS - Used for Subsurf only (int [0 - 6]). The number of subdivision levels used for rendering. @@ -139,6 +144,26 @@ Example:: - SIZE - Used for Cast only (float [0.0, 100.0], default: 0.0) - SIZE_FROM_RADIUS - Used for Cast only (bool, default: True) - USE_OB_TRANSFORM - Used for Cast only (bool, default: False) + + - OBJECT_AUX - Used for Shrinkwrap only, (Object) + - KEEPDIST - Used for Shrinkwrap only (float [-1000.0, 1000.0, default: 0.0) + - PROJECT_OVER_X_AXIS - Used for Shrinkwrap only, should the modifier not project over normal (bool) + - PROJECT_OVER_Y_AXIS - Used for Shrinkwrap only, should the modifier not project over normal (bool) + - PROJECT_OVER_Z_AXIS - Used for Shrinkwrap only, should the modifier not project over normal (bool) + - PROJECT_OVER_NORMAL - Used for Shrinkwrap only (bool) + - ALLOW_POS_DIR - Used for Shrinkwrap only, should the modifier use Project TYPES (bool) + - ALLOW_NEG_DIR - Used for Shrinkwrap only, should the modifier use Project TYPES (bool) + - CULL_TARGET_FRONTFACE - Used for Shrinkwrap only, should the modifier use Project TYPES (bool) + - CULL_TARGET_BACKFACE - Used for Shrinkwrap only, should the modifier use Project TYPES (bool) + - KEEP_ABOVE_SURFACE - Used for Shrinkwrap only , should the modifier use Nearest Surface TYPES(bool) + - SUBSURFLEVELS - Used for Shrinkwrap only (int [0 - 6]). The number of subdivision levels used. + + - RELATIVE - Used for Simpledeform only (bool, default: False) + - LOWER_LIMIT - Used for Simpledeform only (float [0.0, UPPER_LIMIT], default: 0.0)) + - UPPER_LIMIT - Used for Simpledeform only (float [LOWER_LIMIT,1.0], default: 1.0)) + - LOCK_AXIS_X - Used for Simpledeform only (bool, default: False) + - LOCK_AXIS_Y - Used for Simpledeform only (bool, default: False) + """ class ModSeq: From 732c3ee66f228660ae856079eced41c57d1206f1 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 11 May 2009 23:05:13 +0000 Subject: [PATCH 214/444] BGE bug #18596: No ipo dynamics is 2.49rc1. --- .../gameengine/Ketsji/KX_IPO_SGController.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 55a7e2ade60..bd7e09d1dda 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -194,7 +194,8 @@ bool KX_IpoSGController::Update(double currentTime) else newPosition = m_ipo_start_point + newPosition; } - ob->SetLocalPosition(newPosition); + if (m_game_object) + m_game_object->NodeSetLocalPosition(newPosition); } } //modifies orientation? @@ -233,7 +234,8 @@ bool KX_IpoSGController::Update(double currentTime) rotation = m_ipo_start_orient * rotation; else rotation = rotation * m_ipo_start_orient; - ob->SetLocalOrientation(rotation); + if (m_game_object) + m_game_object->NodeSetLocalOrientation(rotation); } } else if (m_ipo_channels_active[OB_ROT_X] || m_ipo_channels_active[OB_ROT_Y] || m_ipo_channels_active[OB_ROT_Z]) { if (m_ipo_euler_initialized) { @@ -265,7 +267,8 @@ bool KX_IpoSGController::Update(double currentTime) else if (m_ipo_channels_active[OB_DROT_Z]) { roll += m_ipo_xform.GetDeltaEulerAngles()[2]; } - ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll)); + if (m_game_object) + m_game_object->NodeSetLocalOrientation(MT_Vector3(yaw, pitch, roll)); } } else if (m_ipo_start_initialized) { // only DROT, treat as Add @@ -286,7 +289,8 @@ bool KX_IpoSGController::Update(double currentTime) // dRot are always local MT_Matrix3x3 rotation(MT_Vector3(yaw, pitch, roll)); rotation = m_ipo_start_orient * rotation; - ob->SetLocalOrientation(rotation); + if (m_game_object) + m_game_object->NodeSetLocalOrientation(rotation); } } //modifies scale? @@ -322,8 +326,8 @@ bool KX_IpoSGController::Update(double currentTime) if (m_ipo_add) { newScale = m_ipo_start_scale * newScale; } - - ob->SetLocalScale(newScale); + if (m_game_object) + m_game_object->NodeSetLocalScale(newScale); } m_modified=false; @@ -342,6 +346,7 @@ SG_Controller* KX_IpoSGController::GetReplica(class SG_Node* destnode) KX_IpoSGController* iporeplica = new KX_IpoSGController(*this); // clear object that ipo acts on in the replica. iporeplica->ClearObject(); + iporeplica->SetGameObject((KX_GameObject*)destnode->GetSGClientObject()); // dirty hack, ask Gino for a better solution in the ipo implementation // hacken en zagen, in what we call datahiding, not written for replication :( From b6fa9afccb941aa413ac788a5bc73d9170fd6228 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 May 2009 15:28:07 +0000 Subject: [PATCH 215/444] [#13726] Segfault with (Re)Appending objects fix this by freeing the lib-file-data after linking or appending, re-appending will be slower now (as slow as appending for the first time). Not strictly needed, set the memory for bhead's to zero in readfile.c since comparisons are done later on with this data making valgrind complain. Added some missing headers too. --- source/blender/blenkernel/intern/fluidsim.c | 2 ++ source/blender/blenloader/intern/readfile.c | 8 ++++++++ source/blender/src/filelist.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 29c4e0f2fb5..b650f3a3e98 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -36,6 +36,8 @@ #include "DNA_particle_types.h" #include "DNA_scene_types.h" // N_T +#include "PIL_time.h" // for PIL_sleep_ms + #include "BLI_arithb.h" #include "BLI_blenlib.h" diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ce154755651..0873c572382 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -133,6 +133,7 @@ #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) #include "BKE_modifier.h" +#include "BKE_multires.h" // for multires_free #include "BKE_node.h" // for tree type defines #include "BKE_object.h" #include "BKE_particle.h" @@ -617,6 +618,11 @@ static BHeadN *get_bhead(FileData *fd) BHeadN *new_bhead = 0; int readsize; + /* not strictly needed but shuts valgrind up + * since uninitialized memory gets compared */ + memset(&bhead8, 0, sizeof(BHead8)); + memset(&bhead4, 0, sizeof(BHead4)); + if (fd) { if ( ! fd->eof) { @@ -9233,6 +9239,8 @@ void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) { BLO_library_append_(&sfile->libfiledata, sfile->filelist, sfile->totfile, dir, sfile->file, sfile->flag, idcode); + BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= NULL; } void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode) diff --git a/source/blender/src/filelist.c b/source/blender/src/filelist.c index 008bcbe147d..5c8fab77e04 100644 --- a/source/blender/src/filelist.c +++ b/source/blender/src/filelist.c @@ -913,6 +913,8 @@ void BIF_filelist_from_library(struct FileList* filelist) void BIF_filelist_append_library(struct FileList *filelist, char *dir, char *file, short flag, int idcode) { BLO_library_append_(&filelist->libfiledata, filelist->filelist, filelist->numfiles, dir, file, flag, idcode); + BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= NULL; } void BIF_filelist_from_main(struct FileList *filelist) From 705764fe050fd15703fe2ab410516ff3ccc3f421 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 May 2009 16:20:23 +0000 Subject: [PATCH 216/444] Fix face occlusion for projection paint, (was broken for all RC's but nobody noticed) Its still not working right in perspective mode. For bleed use a faster method then Barycentric weights function since the point is always on the edge. last commit with memset in readfile.c missed one var. --- source/blender/blenloader/intern/readfile.c | 11 ++--- source/blender/src/imagepaint.c | 46 +++++++++++++-------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0873c572382..cbf2516da77 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -617,15 +617,16 @@ static BHeadN *get_bhead(FileData *fd) BHead bhead; BHeadN *new_bhead = 0; int readsize; - - /* not strictly needed but shuts valgrind up - * since uninitialized memory gets compared */ - memset(&bhead8, 0, sizeof(BHead8)); - memset(&bhead4, 0, sizeof(BHead4)); if (fd) { if ( ! fd->eof) { + /* not strictly needed but shuts valgrind up + * since uninitialized memory gets compared */ + memset(&bhead8, 0, sizeof(BHead8)); + memset(&bhead4, 0, sizeof(BHead4)); + memset(&bhead, 0, sizeof(BHead)); + // First read the bhead structure. // Depending on the platform the file was written on this can // be a big or little endian BHead4 or BHead8 structure. diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 86534438ba0..37670d09749 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -230,8 +230,8 @@ typedef struct ProjPaintState { char *faceSeamFlags; /* store info about faces, if they are initialized etc*/ float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */ LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */ - char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */ #endif + char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */ int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */ int buckets_y; @@ -867,7 +867,7 @@ static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *buc else isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho); } - if (isect_ret==1) { + if (isect_ret>=1) { /* TODO - we may want to cache the first hit, * it is not possible to swap the face order in the list anymore */ return 1; @@ -952,6 +952,7 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve * Its possible this gives incorrect results, when the UVs for 1 face go into the next * tile, but do not do this for the adjacent face, it could return a false positive. * This is so unlikely that Id not worry about it. */ +#ifndef PROJ_DEBUG_NOSEAMBLEED static int cmp_uv(const float vec2a[2], const float vec2b[2]) { /* if the UV's are not between 0.0 and 1.0 */ @@ -969,10 +970,11 @@ static int cmp_uv(const float vec2a[2], const float vec2b[2]) return ((fabsf(xa-xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya-yb) < PROJ_GEOM_TOLERANCE)) ? 1:0; } - +#endif /* set min_px and max_px to the image space bounds of the UV coords * return zero if there is no area in the returned rectangle */ +#ifndef PROJ_DEBUG_NOSEAMBLEED static int pixel_bounds_uv( const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2], rcti *bounds_px, @@ -1000,6 +1002,7 @@ static int pixel_bounds_uv( /* face uses no UV area when quantized to pixels? */ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1; } +#endif static int pixel_bounds_array(float (* uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot) { @@ -2498,7 +2501,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float (*outset_uv)[2] = ps->faceSeamUVs[face_index]; float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */ - float *uv_seam_quad[4]; float fac; float *vCoSS[4]; /* vertex screenspace coords */ @@ -2554,16 +2556,11 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i fac1 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[0]) / ftot; fac2 = Vec2Lenf(vCoSS[fidx1], bucket_clip_edges[1]) / ftot; - uv_seam_quad[0] = tf_uv_pxoffset[fidx1]; - uv_seam_quad[1] = tf_uv_pxoffset[fidx2]; - uv_seam_quad[2] = outset_uv[fidx2]; - uv_seam_quad[3] = outset_uv[fidx1]; - - Vec2Lerpf(seam_subsection[0], uv_seam_quad[0], uv_seam_quad[1], fac1); - Vec2Lerpf(seam_subsection[1], uv_seam_quad[0], uv_seam_quad[1], fac2); - - Vec2Lerpf(seam_subsection[2], uv_seam_quad[3], uv_seam_quad[2], fac2); - Vec2Lerpf(seam_subsection[3], uv_seam_quad[3], uv_seam_quad[2], fac1); + Vec2Lerpf(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1); + Vec2Lerpf(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2); + + Vec2Lerpf(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2); + Vec2Lerpf(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1); /* if the bucket_clip_edges values Z values was kept we could avoid this * Inset needs to be added so occlusion tests wont hit adjacent faces */ @@ -2616,14 +2613,28 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* Only bother calculating the weights if we intersect */ if (ps->do_mask_normal || ps->dm_mtface_clone) { - /* TODO, this is not QUITE correct since UV is not inside the UV's but good enough for seams */ +#if 0 + /* This is not QUITE correct since UV is not inside the UV's but good enough for seams */ if (side) { BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], w); } else { BarycentricWeights2f(uv, tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], w); } - +#endif +#if 1 + /* Cheat, we know where we are along the edge so work out the weights from that */ + fac = fac1 + (fac * (fac2-fac1)); + w[0]=w[1]=w[2]= 0.0; + if (side) { + w[fidx1?fidx1-1:0] = fac; + w[fidx2?fidx2-1:0] = 1.0-fac; + } + else { + w[fidx1] = fac; + w[fidx2] = 1.0-fac; + } +#endif } /* a pitty we need to get the worldspace pixel location here */ @@ -3356,15 +3367,16 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->bucketFaces); MEM_freeN(ps->bucketFlags); +#ifndef PROJ_DEBUG_NOSEAMBLEED if (ps->seam_bleed_px > 0.0f) { MEM_freeN(ps->vertFaces); MEM_freeN(ps->faceSeamFlags); MEM_freeN(ps->faceSeamUVs); } +#endif if (ps->vertFlags) MEM_freeN(ps->vertFlags); - for (a=0; athread_tot; a++) { BLI_memarena_free(ps->arena_mt[a]); } From 5a0de728b0a6a4b916f88554322cc56884f17ad8 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 12 May 2009 19:48:18 +0000 Subject: [PATCH 217/444] BGE performance: allow to create display list on meshes with modifiers but without armature and shape keys. These modified meshes are static and can be put safely in a display list. As the rendering of modifiers is done in direct openGL call, it results is a bit performance boost. --- source/gameengine/Converter/BL_MeshDeformer.h | 2 +- source/gameengine/Converter/BL_ShapeDeformer.cpp | 6 ++++-- source/gameengine/Converter/BL_SkinDeformer.cpp | 3 ++- source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp | 2 ++ source/gameengine/Rasterizer/RAS_Deformer.h | 8 +++++++- source/gameengine/Rasterizer/RAS_MaterialBucket.cpp | 2 +- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index d1754618df2..11ca3b00a1d 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -66,7 +66,7 @@ public: virtual bool Update(void){ return false; }; virtual bool UpdateBuckets(void){ return false; }; virtual RAS_Deformer* GetReplica(){return NULL;}; - virtual void ProcessReplica() { }; + virtual void ProcessReplica() {m_bDynamic=false;}; struct Mesh* GetMesh() { return m_bmesh; }; // virtual void InitDeform(double time){}; diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index bf5eb5cbcb3..e04d4dad015 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -121,7 +121,7 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void) ForceUpdate(); m_armobj->RestorePose(); - + m_bDynamic = true; return true; } return false; @@ -144,8 +144,10 @@ bool BL_ShapeDeformer::Update(void) /* we will blend the key directly in mvert array: it is used by armature as the start position */ /* m_bmesh->key can be NULL in case of Modifier deformer */ - if (m_bmesh->key) + if (m_bmesh->key) { do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0); + m_bDynamic = true; + } // Don't release the weight array as in Blender, it will most likely be reusable on next frame // The weight array are ultimately deleted when the skin mesh is destroyed diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index d40776a645d..e92c3b29543 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -201,7 +201,8 @@ bool BL_SkinDeformer::Update(void) m_lastArmaUpdate=m_armobj->GetLastFrame(); m_armobj->RestorePose(); - + /* dynamic vertex, cannot use display list */ + m_bDynamic = true; /* indicate that the m_transverts and normals are up to date */ return true; } diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 1943c436258..07fdc8ec41b 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -757,6 +757,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, virtual bool Update(void) { //printf("update\n"); + m_bDynamic = true; return true;//?? } virtual bool UpdateBuckets(void) @@ -775,6 +776,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj, virtual void ProcessReplica() { // we have two pointers to deal with but we cannot do it now, will be done in Relink + m_bDynamic = false; } virtual bool SkipVertexTransform() { diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index fe081dd4aa5..bb8e3750485 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -39,7 +39,7 @@ class RAS_Deformer { public: - RAS_Deformer(){}; + RAS_Deformer() : m_pMesh(0), m_bDynamic(false) {}; virtual ~RAS_Deformer(){}; virtual void Relink(GEN_Map*map)=0; virtual bool Apply(class RAS_IPolyMaterial *polymat)=0; @@ -55,8 +55,14 @@ public: { return true; } + // true when deformer produces varying vertex (shape or armature) + bool IsDynamic() + { + return m_bDynamic; + } protected: class RAS_MeshObject *m_pMesh; + bool m_bDynamic; }; #endif diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index db6394c1ec0..841264465cf 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -597,7 +597,7 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa // then it won't have texture coordinates for actual drawing. also // for zsort we can't make a display list, since the polygon order // changes all the time. - if(ms.m_pDeformer) + if(ms.m_pDeformer && ms.m_pDeformer->IsDynamic()) ms.m_bDisplayList = false; else if(!ms.m_DisplayList && rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW) ms.m_bDisplayList = false; From 7d923df2bf524c0155439c2d68cd0f512c93b794 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 May 2009 21:13:29 +0000 Subject: [PATCH 218/444] [#18728] Particle (newtonian) physics API for Python patch from Alberto Santos (dnakhain) --- source/blender/python/api2_2x/Particle.c | 578 ++++++++++++++++++ source/blender/python/api2_2x/doc/Particle.py | 73 ++- 2 files changed, 650 insertions(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c index a7db8290c62..ac3e418bb6a 100644 --- a/source/blender/python/api2_2x/Particle.c +++ b/source/blender/python/api2_2x/Particle.c @@ -133,6 +133,50 @@ static int Part_setRenderStep( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getRenderStep( BPy_PartSys * self ); static PyObject *Part_getDupOb( BPy_PartSys * self ); static PyObject *Part_getDrawAs( BPy_PartSys * self ); +static int Part_setPhysType( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getPhysType( BPy_PartSys * self ); +static int Part_setIntegrator( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIntegrator( BPy_PartSys * self ); +static int Part_setIniVelObject( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelObject( BPy_PartSys * self ); +static int Part_setIniVelNormal( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelNormal( BPy_PartSys * self ); +static int Part_setIniVelRandom( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelRandom( BPy_PartSys * self ); +static int Part_setIniVelTan( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelTan( BPy_PartSys * self ); +static int Part_setIniVelRot( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelRot( BPy_PartSys * self ); +static int Part_setIniVelPart( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelPart( BPy_PartSys * self ); +static int Part_setIniVelReact( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getIniVelReact( BPy_PartSys * self ); +static int Part_setRotDynamic( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotDynamic( BPy_PartSys * self ); +static int Part_setRotation( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotation( BPy_PartSys * self ); +static int Part_setRotRandom( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotRandom( BPy_PartSys * self ); +static int Part_setRotPhase( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotPhase( BPy_PartSys * self ); +static int Part_setRotPhaseR( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotPhaseR( BPy_PartSys * self ); +static int Part_setRotAngularV( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotAngularV( BPy_PartSys * self ); +static int Part_setRotAngularVAm( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRotAngularVAm( BPy_PartSys * self ); +static int Part_setGlobAccX( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getGlobAccX( BPy_PartSys * self ); +static int Part_setGlobAccY( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getGlobAccY( BPy_PartSys * self ); +static int Part_setGlobAccZ( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getGlobAccZ( BPy_PartSys * self ); +static int Part_setGlobDrag( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getGlobDrag( BPy_PartSys * self ); +static int Part_setGlobBrown( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getGlobBrown( BPy_PartSys * self ); +static int Part_setGlobDamp( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getGlobDamp( BPy_PartSys * self ); static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ); static int Part_setChildAmount( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getChildAmount( BPy_PartSys * self ); @@ -366,6 +410,95 @@ static PyGetSetDef BPy_ParticleSys_getseters[] = { (getter)Part_getDrawAs, NULL, "Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )", NULL}, +/* Newtonian Physics */ + {"physics", + (getter)Part_getPhysType, (setter)Part_setPhysType, + "Select particle physics type Particle.PHYSICS([ 'BOIDS' | 'KEYED' | 'NEWTONIAN' | 'NONE' ])", + NULL}, + {"integration", + (getter)Part_getIntegrator, (setter)Part_setIntegrator, + "Select physics integrator type Particle.INTEGRATOR([ 'RK4' | 'MIDPOINT' | 'EULER' ])", + NULL}, + {"inVelObj", + (getter)Part_getIniVelObject, (setter)Part_setIniVelObject, + "Let the object give the particle a starting speed", + NULL}, + {"inVelNor", + (getter)Part_getIniVelNormal, (setter)Part_setIniVelNormal, + "Let the surface normal give the particle a starting speed", + NULL}, + {"inVelRan", + (getter)Part_getIniVelRandom, (setter)Part_setIniVelRandom, + "Give the starting speed a random variation", + NULL}, + {"inVelTan", + (getter)Part_getIniVelTan, (setter)Part_setIniVelTan, + "Let the surface tangent give the particle a starting speed", + NULL}, + {"inVelRot", + (getter)Part_getIniVelRot, (setter)Part_setIniVelRot, + "Rotate the surface tangent", + NULL}, + {"inVelPart", + (getter)Part_getIniVelPart, (setter)Part_setIniVelPart, + "Let the target particle give the particle a starting speed", + NULL}, + {"inVelReact", + (getter)Part_getIniVelReact, (setter)Part_setIniVelReact, + "Let the vector away from the target particles location give the particle a starting speed", + NULL}, + {"rotation", + (getter)Part_getRotation, (setter)Part_setRotation, + "Particles initial rotation Particle.ROTATION([ 'OBZ' | 'OBY' | 'OBX' | 'GLZ' | 'GLY' | 'GLX' | 'VEL' | 'NOR' | 'NONE' ])", + NULL}, + {"rotDyn", + (getter)Part_getRotDynamic, (setter)Part_setRotDynamic, + "Sets rotation to dynamic/constant", + NULL}, + {"rotRand", + (getter)Part_getRotRandom, (setter)Part_setRotRandom, + "Randomize rotation", + NULL}, + {"rotPhase", + (getter)Part_getRotPhase, (setter)Part_setRotPhase, + "Initial rotation phase", + NULL}, + {"rotPhaseR", + (getter)Part_getRotPhaseR, (setter)Part_setRotPhaseR, + "Randomize rotation phase", + NULL}, + {"rotAnV", + (getter)Part_getRotAngularV, (setter)Part_setRotAngularV, + "Select particle angular velocity mode Particle.ANGULARV([ 'RANDOM' | 'SPIN' | 'NONE' ])", + NULL}, + {"rotAnVAm", + (getter)Part_getRotAngularVAm, (setter)Part_setRotAngularVAm, + "Angular velocity amount", + NULL}, + {"glAccX", + (getter)Part_getGlobAccX, (setter)Part_setGlobAccX, + "Specify a constant acceleration along the X-axis", + NULL}, + {"glAccY", + (getter)Part_getGlobAccY, (setter)Part_setGlobAccY, + "Specify a constant acceleration along the Y-axis", + NULL}, + {"glAccZ", + (getter)Part_getGlobAccZ, (setter)Part_setGlobAccZ, + "Specify a constant acceleration along the Z-axis", + NULL}, + {"glDrag", + (getter)Part_getGlobDrag, (setter)Part_setGlobDrag, + "Specify the amount of air-drag", + NULL}, + {"glBrown", + (getter)Part_getGlobBrown, (setter)Part_setGlobBrown, + "Specify the amount of brownian motion", + NULL}, + {"glDamp", + (getter)Part_getGlobDamp, (setter)Part_setGlobDamp, + "Specify the amount of damping", + NULL}, /* Children */ {"childAmount", (getter)Part_getChildAmount, (setter)Part_setChildAmount, @@ -859,6 +992,95 @@ static PyObject *Particle_ReactOnDict( void ) return ReactOn; } +/* create the Blender.Particle.Physics constant dict */ + +static PyObject *Particle_PhysicsDict( void ) +{ + PyObject *Physics = PyConstant_New( ); + + if( Physics ) { + BPy_constant *c = ( BPy_constant * ) Physics; + + PyConstant_Insert( c, "BOIDS", + PyInt_FromLong( 3 ) ); + PyConstant_Insert( c, "KEYED", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "NEWTONIAN", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "NONE", + PyInt_FromLong( 0 ) ); + } + return Physics; +} + +/* create the Blender.Particle.Integrator constant dict */ + +static PyObject *Particle_IntegratorDict( void ) +{ + PyObject *Integrator = PyConstant_New( ); + + if( Integrator ) { + BPy_constant *c = ( BPy_constant * ) Integrator; + + PyConstant_Insert( c, "EULER", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "MIDPOINT", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "EULER", + PyInt_FromLong( 0 ) ); + } + return Integrator; +} + +/* create the Blender.Particle.Rotation constant dict */ + +static PyObject *Particle_RotationDict( void ) +{ + PyObject *Rotation = PyConstant_New( ); + + if( Rotation ) { + BPy_constant *c = ( BPy_constant * ) Rotation; + + PyConstant_Insert( c, "OBZ", + PyInt_FromLong( 8 ) ); + PyConstant_Insert( c, "OBY", + PyInt_FromLong( 7 ) ); + PyConstant_Insert( c, "OBX", + PyInt_FromLong( 6 ) ); + PyConstant_Insert( c, "GLZ", + PyInt_FromLong( 5 ) ); + PyConstant_Insert( c, "GLY", + PyInt_FromLong( 4 ) ); + PyConstant_Insert( c, "GLX", + PyInt_FromLong( 3 ) ); + PyConstant_Insert( c, "VEL", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "NOR", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "NONE", + PyInt_FromLong( 0 ) ); + } + return Rotation; +} + +/* create the Blender.Particle.AngularV constant dict */ + +static PyObject *Particle_AngularVDict( void ) +{ + PyObject *AngularV = PyConstant_New( ); + + if( AngularV ) { + BPy_constant *c = ( BPy_constant * ) AngularV; + + PyConstant_Insert( c, "RANDOM", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "SPIN", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "NONE", + PyInt_FromLong( 0 ) ); + } + return AngularV; +} /* create the Blender.Particle.ChildType constant dict */ @@ -967,6 +1189,10 @@ PyObject *ParticleSys_Init( void ){ PyObject *EmitFrom; PyObject *Dist; PyObject *DrawAs; + PyObject *Physics; + PyObject *Integrator; + PyObject *Rotation; + PyObject *AngularV; PyObject *ChildTypes; PyObject *ChildKinks; PyObject *ChildKinkAxes; @@ -980,6 +1206,10 @@ PyObject *ParticleSys_Init( void ){ EmitFrom = Particle_EmitFrom(); DrawAs = Particle_DrawAs(); Dist = Particle_DistrDict(); + Physics = Particle_PhysicsDict(); + Integrator = Particle_IntegratorDict(); + Rotation = Particle_RotationDict(); + AngularV = Particle_AngularVDict(); ChildTypes = Particle_ChildTypeDict(); ChildKinks = Particle_ChildKinkDict(); ChildKinkAxes = Particle_ChildKinkAxisDict(); @@ -997,6 +1227,14 @@ PyObject *ParticleSys_Init( void ){ PyModule_AddObject( submodule, "DISTRIBUTION", Dist ); if( DrawAs ) PyModule_AddObject( submodule, "DRAWAS", DrawAs ); + if( Physics ) + PyModule_AddObject( submodule, "PHYSICS", Physics ); + if( Integrator ) + PyModule_AddObject( submodule, "INTEGRATOR", Integrator ); + if( Rotation ) + PyModule_AddObject( submodule, "ROTATION", Rotation ); + if( AngularV ) + PyModule_AddObject( submodule, "ANGULARV", AngularV ); if( ChildTypes ) PyModule_AddObject( submodule, "CHILDTYPE", ChildTypes ); if( ChildKinks ) @@ -2202,6 +2440,346 @@ static PyObject *Part_getDrawAs( BPy_PartSys * self ) return PyInt_FromLong( (long)( self->psys->part->draw_as ) ); } +static int Part_setPhysType( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->phystype, + 0, 3, 'h' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getPhysType( BPy_PartSys * self ) +{ + return PyInt_FromLong( (short)( self->psys->part->phystype ) ); +} + +static int Part_setIntegrator( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->integrator, + 0, 2, 'h' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIntegrator( BPy_PartSys * self ) +{ + return PyInt_FromLong( (short)( self->psys->part->integrator ) ); +} + +static int Part_setIniVelObject( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->obfac, + -1.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelObject( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->obfac )) ); +} + +static int Part_setIniVelNormal( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->normfac, + -200.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelNormal( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->normfac )) ); +} + +static int Part_setIniVelRandom( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->randfac, + 0.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelRandom( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->randfac )) ); +} + +static int Part_setIniVelTan( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->tanfac, + -200.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelTan( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->tanfac )) ); +} + +static int Part_setIniVelRot( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->tanphase, + -1.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelRot( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->tanphase )) ); +} + +static int Part_setIniVelPart( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->partfac, + -10.0, 10.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelPart( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->partfac )) ); +} + +static int Part_setIniVelReact( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->reactfac, + -10.0, 10.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getIniVelReact( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->reactfac )) ); +} + +static int Part_setRotation( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->rotmode, + 0, 8, 'h' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRotation( BPy_PartSys * self ) +{ + return PyInt_FromLong( (short)( self->psys->part->rotmode ) ); +} + +static int Part_setRotDynamic( BPy_PartSys * self, PyObject * args ) +{ + int number; + + if( !PyInt_Check( args ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->flag |= PART_ROT_DYN; + }else{ + self->psys->part->flag &= ~PART_ROT_DYN; + } + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return 0; +} + +static PyObject *Part_getRotDynamic( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_ROT_DYN )) > 0 ); +} + +static int Part_setRotRandom( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->randrotfac, + 0.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRotRandom( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->randrotfac )) ); +} + +static int Part_setRotPhase( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->phasefac, + -1.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRotPhase( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->phasefac )) ); +} + +static int Part_setRotPhaseR( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->randphasefac, + 0.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRotPhaseR( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->randphasefac )) ); +} + +static int Part_setRotAngularV( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->avemode, + 0, 2, 'h' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRotAngularV( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((int)( self->psys->part->avemode )) ); +} + +static int Part_setRotAngularVAm( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->avefac, + -200.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRotAngularVAm( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->avefac )) ); +} + +static int Part_setGlobAccX( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->acc[0], + -200.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getGlobAccX( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->acc[0] )) ); +} + +static int Part_setGlobAccY( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->acc[1], + -200.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getGlobAccY( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->acc[1] )) ); +} + +static int Part_setGlobAccZ( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->acc[2], + -200.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getGlobAccZ( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->acc[2] )) ); +} + +static int Part_setGlobDrag( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->dragfac, + 0.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getGlobDrag( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->dragfac )) ); +} + +static int Part_setGlobBrown( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->brownfac, + 0.0, 200.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getGlobBrown( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->brownfac )) ); +} + +static int Part_setGlobDamp( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->dampfac, + 0.0, 1.0 ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getGlobDamp( BPy_PartSys * self ) +{ + return PyFloat_FromDouble( ((float)( self->psys->part->dampfac )) ); +} + static int Part_setChildAmount( BPy_PartSys * self, PyObject * args ) { int res = EXPP_setIValueRange( args, &self->psys->part->child_nbr, diff --git a/source/blender/python/api2_2x/doc/Particle.py b/source/blender/python/api2_2x/doc/Particle.py index 6107f0bda2f..962e8c16249 100644 --- a/source/blender/python/api2_2x/doc/Particle.py +++ b/source/blender/python/api2_2x/doc/Particle.py @@ -42,8 +42,35 @@ This module provides access to the B{Particle} in Blender. - OBJECT: Draw object - GROUP: Draw group - BILLBOARD: Draw as billboard +@type PHYSICS: readonly dictionary +@var PHYSICS: Constant dict used for with L{Particle.PHYSICS} + - NONE: No physics + - NEWTONIAN: Use newtonian physics + - KEYED: Use keyed physics + - BOIDS: Use Boids physics +@type INTEGRATOR: readonly dictionary +@var INTEGRATOR: Constant dict used for with L{Particle.INTEGRATOR} + - EULER: Use Euler integrator + - MIDPOINT: Use Midpoint integrator + - RK4: Use RK4 integrator +@type ROTATION: readonly dictionary +@var ROTATION: Constant dict used for with L{Particle.ROTATION} + - NONE: No particle initial rotation + - NOR: Rotate along the normal + - VEL: Rotate affect to velocity + - GLX: Rotate along global X-Axis + - GLY: Rotate along global Y-Axis + - GLZ: Rotate along global Z-Axis + - OBX: Rotate along local X-Axis + - OBY: Rotate along local Y-Axis + - OBZ: Rotate along local Z-Axis +@type ANGULARV: readonly dictionary +@var ANGULARV: Constant dict used for with L{Particle.ANGULARV} + - NONE: No particle angular velocity + - SPIN: Spin particle angular velocity + - RANDOM: Random particle angular velocity @type CHILDTYPE: readonly dictionary -@var CHILDTYPE: Constant dict used for whith L{Particle.CHILDTYPE} +@var CHILDTYPE: Constant dict used for with L{Particle.CHILDTYPE} - NONE: set no children - PARTICLES: set children born from particles - FACES: set children born from faces @@ -135,6 +162,50 @@ class Particle: @type duplicateObject: Blender Object @ivar drawAs: Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]). @type drawAs: int + @ivar physics: Select particle physics type Particle.PHYSICS([ 'BOIDS' | 'KEYED' | 'NEWTONIAN' | 'NONE' ]) + @type physics: int + @ivar integration: Select physics integrator type Particle.INTEGRATOR([ 'RK4' | 'MIDPOINT' | 'EULER' ]) + @type integration: int + @ivar inVelObj: Let the object give the particle a starting speed + @type inVelObj: float + @ivar inVelNor: Let the surface normal give the particle a starting speed + @type inVelNor: float + @ivar inVelRan: Give the starting speed a random variation + @type inVelRan: float + @ivar inVelTan: Let the surface tangent give the particle a starting speed + @type inVelTan: float + @ivar inVelRot: Rotate the surface tangent + @type inVelRot: float + @ivar inVelPart: Let the target particle give the particle a starting speed + @type inVelPart: float + @ivar inVelReact: Let the vector away from the target particles location give the particle a starting speed + @type inVelReact: float + @ivar rotation: Particles initial rotation Particle.ROTATION([ 'OBZ' | 'OBY' | 'OBX' | 'GLZ' | 'GLY' | 'GLX' | 'VEL' | 'NOR' | 'NONE' ]) + @type rotation: int + @ivar rotDyn: Sets rotation to dynamic/constant + @type rotDyn: int + @ivar rotRand: Randomize rotation + @type rotRand: float + @ivar rotPhase: Initial rotation phase + @type rotPhase: float + @ivar rotPhaseR: Randomize rotation phase + @type rotPhaseR: float + @ivar rotAnV: Select particle angular velocity mode Particle.ANGULARV([ 'RANDOM' | 'SPIN' | 'NONE' ]) + @type rotAnV: int + @ivar rotAnVAm: Angular velocity amount + @type rotAnVAm: float + @ivar glAccX: Specify a constant acceleration along the X-axis + @type glAccX: float + @ivar glAccY: Specify a constant acceleration along the Y-axis + @type glAccY: float + @ivar glAccZ: Specify a constant acceleration along the Z-axis + @type glAccZ: float + @ivar glDrag: Specify the amount of air-drag + @type glDrag: float + @ivar glBrown: Specify the amount of brownian motion + @type glBrown: float + @ivar glDamp: Specify the amount of damping + @type glDamp: float @ivar childAmount: The total number of children @type childAmount: int @ivar childType: Type of childrens ( Particle.CHILDTYPE[ 'FACES' | 'PARTICLES' | 'NONE' ] ) From 3c0f6b65fb5491c73c9fc79889e818f277400bd2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 May 2009 21:27:01 +0000 Subject: [PATCH 219/444] [#18711] Particle render API for Python from Alberto Santos (dnakhain) --- source/blender/python/api2_2x/Particle.c | 173 ++++++++++++++++++ source/blender/python/api2_2x/doc/Particle.py | 19 ++ 2 files changed, 192 insertions(+) diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c index ac3e418bb6a..5d40763bb3e 100644 --- a/source/blender/python/api2_2x/Particle.c +++ b/source/blender/python/api2_2x/Particle.c @@ -64,6 +64,7 @@ static PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args ); static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_SetMat( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ); static int Part_setSeed( BPy_PartSys * self, PyObject * args ); @@ -127,6 +128,16 @@ static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getTargetPsys( BPy_PartSys * self ); static int Part_setRenderObject( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getRenderObject( BPy_PartSys * self ); +static int Part_setRenderMaterialColor( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRenderMaterialColor( BPy_PartSys * self ); +static int Part_setRenderParents( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRenderParents( BPy_PartSys * self ); +static int Part_setRenderUnborn( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRenderUnborn( BPy_PartSys * self ); +static int Part_setRenderDied( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRenderDied( BPy_PartSys * self ); +static int Part_setRenderMaterialIndex( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getRenderMaterialIndex( BPy_PartSys * self ); static int Part_setStep( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getStep( BPy_PartSys * self ); static int Part_setRenderStep( BPy_PartSys * self, PyObject * args ); @@ -257,6 +268,8 @@ static PyMethodDef BPy_ParticleSys_methods[] = { METH_VARARGS, "() - Get particles location"}, {"getRot", ( PyCFunction ) Part_GetRot, METH_VARARGS, "() - Get particles rotations (list of 4 floats quaternion)"}, + {"setMat", ( PyCFunction ) Part_SetMat, + METH_VARARGS, "() - Set particles material"}, {"getMat", ( PyCFunction ) Part_GetMat, METH_NOARGS, "() - Get particles material"}, {"getSize", ( PyCFunction ) Part_GetSize, @@ -390,6 +403,26 @@ static PyGetSetDef BPy_ParticleSys_getseters[] = { (getter)Part_getRenderObject, (setter)Part_setRenderObject, "Render emitter object", NULL}, + {"renderMatCol", + (getter)Part_getRenderMaterialColor, (setter)Part_setRenderMaterialColor, + "Draw particles using material's diffuse color", + NULL}, + {"renderParents", + (getter)Part_getRenderParents, (setter)Part_setRenderParents, + "Render parent particles", + NULL}, + {"renderUnborn", + (getter)Part_getRenderUnborn, (setter)Part_setRenderUnborn, + "Show particles before they are emitted", + NULL}, + {"renderDied", + (getter)Part_getRenderDied, (setter)Part_setRenderDied, + "Show particles after they have died", + NULL}, + {"renderMaterial", + (getter)Part_getRenderMaterialIndex, (setter)Part_setRenderMaterialIndex, + "Specify material index used for the particles", + NULL}, {"displayPercentage", (getter)Part_getParticleDisp, (setter)Part_setParticleDisp, "Particle display percentage", @@ -1778,6 +1811,37 @@ error: return NULL; } +static PyObject *Part_SetMat( BPy_PartSys * self, PyObject * args ) +{ + Object *ob = self->object; + BPy_Material *pymat; + Material *mat; + short index; + + if( !PyArg_ParseTuple( args, "O!", &Material_Type, &pymat ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected Blender Material PyObject" ); + + mat = pymat->material; + + if( ob->totcol >= MAXMAT ) + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "object data material lists can't have more than 16 materials" ); + + index = find_material_index(ob,mat); + if (index == 0){ /*Not found*/ + assign_material(ob,mat,ob->totcol+1); + index = find_material_index(ob,mat); + } + + if (index>0 && indexpsys->part->omat = index; + + /* since we have messed with object, we need to flag for DAG recalc */ + self->object->recalc |= OB_RECALC_OB; + + Py_RETURN_NONE; +} static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ){ Material *ma; @@ -2387,6 +2451,115 @@ static PyObject *Part_getRenderObject( BPy_PartSys * self ) return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_EMITTER )) > 0 ); } +static int Part_setRenderMaterialColor( BPy_PartSys * self, PyObject * args ) +{ + int number; + + if( !PyInt_Check( args ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->draw |= PART_DRAW_MAT_COL; + }else{ + self->psys->part->draw &= ~PART_DRAW_MAT_COL; + } + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return 0; +} + +static PyObject *Part_getRenderMaterialColor( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_MAT_COL )) > 0 ); +} + +static int Part_setRenderParents( BPy_PartSys * self, PyObject * args ) +{ + int number; + + if( !PyInt_Check( args ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->draw |= PART_DRAW_PARENT; + }else{ + self->psys->part->draw &= ~PART_DRAW_PARENT; + } + + return 0; +} + +static PyObject *Part_getRenderParents( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_PARENT )) > 0 ); +} + +static int Part_setRenderUnborn( BPy_PartSys * self, PyObject * args ) +{ + int number; + + if( !PyInt_Check( args ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->flag |= PART_UNBORN; + }else{ + self->psys->part->flag &= ~PART_UNBORN; + } + + return 0; +} + +static PyObject *Part_getRenderUnborn( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_UNBORN )) > 0 ); +} + +static int Part_setRenderDied( BPy_PartSys * self, PyObject * args ) +{ + int number; + + if( !PyInt_Check( args ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->flag |= PART_DIED; + }else{ + self->psys->part->flag &= ~PART_DIED; + } + + return 0; +} + +static int Part_setRenderMaterialIndex( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->omat, + 1, 16, 'i' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getRenderMaterialIndex( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((int)( self->psys->part->omat )) ); +} + +static PyObject *Part_getRenderDied( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_DIED )) > 0 ); +} + static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args ) { int res = EXPP_setIValueRange( args, &self->psys->part->disp, diff --git a/source/blender/python/api2_2x/doc/Particle.py b/source/blender/python/api2_2x/doc/Particle.py index 962e8c16249..82d197f71dd 100644 --- a/source/blender/python/api2_2x/doc/Particle.py +++ b/source/blender/python/api2_2x/doc/Particle.py @@ -152,6 +152,16 @@ class Particle: @type object: Blender Object @ivar renderEmitter: Render emitter object. @type renderEmitter: int + @ivar renderMatCol: Draw particles using material's diffuse color. + @type renderMatCol: int + @ivar renderParents: Render parent particles. + @type renderParents: int + @ivar renderUnborn: Show particles before they are emitted. + @type renderUnborn: int + @ivar renderDied: Show particles after they have died. + @type renderDied: int + @ivar renderMaterial: Specify material used for the particles. + @type renderMaterial: int @ivar displayPercentage: Particle display percentage. @type displayPercentage: int @ivar hairDisplayStep: How many steps paths are drawn with (power of 2) in visu mode. @@ -291,6 +301,15 @@ class Particle: @return: list of 4-tuples or None if system is disabled """ + def setMat(mat): + """ + Set the particles' material. This method checks if the argument + given is really a material, imposes a limit of 16 materials and adds + the material if it wasn't already in the list of the object. + @type mat: Blender Material + @param mat: The material to be assigned to particles + """ + def getMat(): """ Get the particles' material. From a70440d918b13b62e7a6695f562089bd5d4b613a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 12 May 2009 21:41:04 +0000 Subject: [PATCH 220/444] [#18735] Particle vertex group API for Python from Alberto Santos (dnakhain) Changed "None" to "" for returning an unset vertex group. "" is a valid name for a vertex group this is asking for trouble. --- source/blender/python/api2_2x/Particle.c | 153 ++++++++++++++++++ source/blender/python/api2_2x/doc/Particle.py | 21 +++ 2 files changed, 174 insertions(+) diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c index 5d40763bb3e..97bdc127426 100644 --- a/source/blender/python/api2_2x/Particle.c +++ b/source/blender/python/api2_2x/Particle.c @@ -67,6 +67,8 @@ static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ); static PyObject *Part_SetMat( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_GetVertGroup( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_SetVertGroup( BPy_PartSys * self, PyObject * args ); static int Part_setSeed( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getSeed( BPy_PartSys * self ); static int Part_setType( BPy_PartSys * self, PyObject * args ); @@ -276,6 +278,10 @@ static PyMethodDef BPy_ParticleSys_methods[] = { METH_VARARGS, "() - Get particles size in a list"}, {"getAge", ( PyCFunction ) Part_GetAge, METH_VARARGS, "() - Get particles life in a list"}, + {"getVertGroup", ( PyCFunction ) Part_GetVertGroup, + METH_VARARGS, "() - Get the vertex group which affects a particles attribute"}, + {"setVertGroup", ( PyCFunction ) Part_SetVertGroup, + METH_VARARGS, "() - Set the vertex group to affect a particles attribute"}, {NULL, NULL, 0, NULL} }; @@ -1134,6 +1140,44 @@ static PyObject *Particle_ChildTypeDict( void ) return ChildTypes; } +/* create the Blender.Particle.VertexGroups constant dict */ + +static PyObject *Particle_VertexGroupsDict( void ) +{ + PyObject *VertexGroups = PyConstant_New( ); + + if( VertexGroups ) { + BPy_constant *c = ( BPy_constant * ) VertexGroups; + + PyConstant_Insert( c, "EFFECTOR", + PyInt_FromLong( 11 ) ); + PyConstant_Insert( c, "TANROT", + PyInt_FromLong( 10 ) ); + PyConstant_Insert( c, "TANVEL", + PyInt_FromLong( 9 ) ); + PyConstant_Insert( c, "SIZE", + PyInt_FromLong( 8 ) ); + PyConstant_Insert( c, "ROUGHE", + PyInt_FromLong( 7 ) ); + PyConstant_Insert( c, "ROUGH2", + PyInt_FromLong( 6 ) ); + PyConstant_Insert( c, "ROUGH1", + PyInt_FromLong( 5 ) ); + PyConstant_Insert( c, "KINK", + PyInt_FromLong( 4 ) ); + PyConstant_Insert( c, "CLUMP", + PyInt_FromLong( 3 ) ); + PyConstant_Insert( c, "LENGHT", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "VELOCITY", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "DENSITY", + PyInt_FromLong( 0 ) ); + } + return VertexGroups; +} + + /* create the Blender.Particle.ChildKink constant dict */ static PyObject *Particle_ChildKinkDict( void ) @@ -1227,6 +1271,7 @@ PyObject *ParticleSys_Init( void ){ PyObject *Rotation; PyObject *AngularV; PyObject *ChildTypes; + PyObject *VertexGroups; PyObject *ChildKinks; PyObject *ChildKinkAxes; @@ -1243,6 +1288,7 @@ PyObject *ParticleSys_Init( void ){ Integrator = Particle_IntegratorDict(); Rotation = Particle_RotationDict(); AngularV = Particle_AngularVDict(); + VertexGroups = Particle_VertexGroupsDict(); ChildTypes = Particle_ChildTypeDict(); ChildKinks = Particle_ChildKinkDict(); ChildKinkAxes = Particle_ChildKinkAxisDict(); @@ -1268,6 +1314,8 @@ PyObject *ParticleSys_Init( void ){ PyModule_AddObject( submodule, "ROTATION", Rotation ); if( AngularV ) PyModule_AddObject( submodule, "ANGULARV", AngularV ); + if( VertexGroups ) + PyModule_AddObject( submodule, "VERTEXGROUPS", VertexGroups ); if( ChildTypes ) PyModule_AddObject( submodule, "CHILDTYPE", ChildTypes ); if( ChildKinks ) @@ -1854,6 +1902,111 @@ static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ){ return mat; } +static PyObject *Part_GetVertGroup( BPy_PartSys * self, PyObject * args ){ + PyObject *list; + char errstr[128]; + bDeformGroup *defGroup = NULL; + Object *obj = self->object; + int vg_attribute = 0; + int vg_number = 0; + int count; + PyObject *vg_neg; + PyObject *vg_name; + + if( !obj ) + return EXPP_ReturnPyObjError( PyExc_AttributeError, + "particle system must be linked to an object first" ); + + if( obj->type != OB_MESH ) + return EXPP_ReturnPyObjError( PyExc_AttributeError, + "linked object is not a mesh" ); + + if( !PyArg_ParseTuple( args, "i", &vg_attribute ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected integer argument" ); + + if( vg_attribute < 0 || vg_attribute > PSYS_TOT_VG-1 ){ + sprintf ( errstr, "expected int argument in [0,%d]", PSYS_TOT_VG-1 ); + return EXPP_ReturnPyObjError( PyExc_TypeError, errstr ); + } + + /*search*/ + vg_number = self->psys->vgroup[vg_attribute]; + count = 1; + defGroup = obj->defbase.first; + while(countnext; + count++; + } + + /*vg_name*/ + if (defGroup && vg_number>0) + vg_name = PyString_FromString( defGroup->name ); + else + vg_name = PyString_FromString( "" ); + + /*vg_neg*/ + vg_neg = PyInt_FromLong( ((long)( self->psys->vg_neg & (1< 0 ); + + list = PyList_New( 2 ); + PyList_SET_ITEM( list, 0, vg_name ); + PyList_SET_ITEM( list, 1, vg_neg ); + + return list; +} + +static PyObject *Part_SetVertGroup( BPy_PartSys * self, PyObject * args ){ + char errstr[128]; + bDeformGroup *defGroup; + Object *obj = self->object; + char *vg_name = NULL; + int vg_attribute = 0; + int vg_neg = 0; + int vg_number = 0; + int count; + + if( !obj ) + return EXPP_ReturnPyObjError( PyExc_AttributeError, + "particle system must be linked to an object first" ); + + if( obj->type != OB_MESH ) + return EXPP_ReturnPyObjError( PyExc_AttributeError, + "linked object is not a mesh" ); + + if( !PyArg_ParseTuple( args, "sii", &vg_name, &vg_attribute, &vg_neg ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected one string and two integers arguments" ); + + if( vg_attribute < 0 || vg_attribute > PSYS_TOT_VG-1 ){ + sprintf ( errstr, "expected int argument in [0,%d]", PSYS_TOT_VG-1 ); + return EXPP_ReturnPyObjError( PyExc_TypeError, errstr ); + } + + /*search*/ + count = 1; + defGroup = obj->defbase.first; + while (defGroup){ + if (strcmp(vg_name,defGroup->name)==0) + vg_number = count; + defGroup = defGroup->next; + count++; + } + + /*vgroup*/ + self->psys->vgroup[vg_attribute] = vg_number; + + /*vg_neg*/ + if (vg_neg){ + self->psys->vg_neg |= (1<psys->vg_neg &= ~(1<psys->part, PSYS_ALLOC, 1 ); + + Py_RETURN_NONE; +} + /*****************************************************************************/ /* Function: Set/Get Seed */ diff --git a/source/blender/python/api2_2x/doc/Particle.py b/source/blender/python/api2_2x/doc/Particle.py index 82d197f71dd..888747f6225 100644 --- a/source/blender/python/api2_2x/doc/Particle.py +++ b/source/blender/python/api2_2x/doc/Particle.py @@ -340,3 +340,24 @@ class Particle: @rtype: list of floats @return: list of floats or list of tuples if id is not zero (size,id) or None if system is disabled. """ + + def getVertGroup(attribute): + """ + Get vertex group name and negation bit assigned to affect parameter attribute. + A list of string and integer (vertex group name, negation bit). + @type attribute: int + @param attribute: Particle.VERTEXGROUPS([ 'DENSITY' | 'VELOCITY' | ... ]) + @rtype: list of objects + @return: first element is the vg name and second the negation bit + """ + def setVertGroup(name,attribute,negated): + """ + Set vertex group and negation bit to affect particles system attribute. + @type name: string + @param name: Name of the vertex group + @type attribute: int + @param attribute: Particle.VERTEXGROUPS([ 'DENSITY' | 'VELOCITY' | ... ]) + @type negated: int + @param negated: Negate the effect of the vertex group + @return: None + """ From f790744faf3ee8e3d65afa0cdc65f7efc24b87ab Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 12 May 2009 23:41:46 +0000 Subject: [PATCH 221/444] Fix crash when missing int argument for -s -e and -j. --- source/creator/creator.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 2b542b13c97..a39d2916a84 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -662,7 +662,8 @@ int main(int argc, char **argv) a++; if (G.scene) { if (a < argc) { - int frame= MIN2(MAXFRAME, MAX2(1, atoi(argv[a]))); + int frame = atoi(argv[a]); + frame = MIN2(MAXFRAME, MAX2(1, frame)); Render *re= RE_NewRender(G.scene->id.name); #ifndef DISABLE_PYTHON if (G.f & G_DOSCRIPTLINKS) @@ -701,8 +702,10 @@ int main(int argc, char **argv) case 's': a++; if(G.scene) { - int frame= MIN2(MAXFRAME, MAX2(1, atoi(argv[a]))); - if (a < argc) (G.scene->r.sfra) = frame; + if (a < argc) { + int frame = atoi(argv[a]); + (G.scene->r.sfra) = MIN2(MAXFRAME, MAX2(1, frame)); + } } else { printf("\nError: no blend loaded. cannot use '-s'.\n"); } @@ -710,8 +713,10 @@ int main(int argc, char **argv) case 'e': a++; if(G.scene) { - int frame= MIN2(MAXFRAME, MAX2(1, atoi(argv[a]))); - if (a < argc) (G.scene->r.efra) = frame; + if (a < argc) { + int frame = atoi(argv[a]); + (G.scene->r.efra) = MIN2(MAXFRAME, MAX2(1, frame)); + } } else { printf("\nError: no blend loaded. cannot use '-e'.\n"); } @@ -719,8 +724,10 @@ int main(int argc, char **argv) case 'j': a++; if(G.scene) { - int fstep= MIN2(MAXFRAME, MAX2(1, atoi(argv[a]))); - if (a < argc) (G.scene->frame_step) = fstep; + if (a < argc) { + int frame = atoi(argv[a]); + (G.scene->frame_step) = MIN2(MAXFRAME, MAX2(1, frame)); + } } else { printf("\nError: no blend loaded. cannot use '-j'.\n"); } From 9147124ac2813f79bc44ae54ca2676c8afab0ade Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 12 May 2009 23:53:55 +0000 Subject: [PATCH 222/444] Mixed declaration and code. That should teach me to ignore warnings. --- source/creator/creator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index a39d2916a84..e04a5b1db3d 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -663,8 +663,9 @@ int main(int argc, char **argv) if (G.scene) { if (a < argc) { int frame = atoi(argv[a]); + Render *re = RE_NewRender(G.scene->id.name); + frame = MIN2(MAXFRAME, MAX2(1, frame)); - Render *re= RE_NewRender(G.scene->id.name); #ifndef DISABLE_PYTHON if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_RENDER, 0); From c19baf85cca1ecdd0b07c35a61a4999bc27d1e6b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 May 2009 00:20:14 +0000 Subject: [PATCH 223/444] [#18694] Added support for Wavefront OBJ groups for both the import and export scripts from Paolo Ciccone (pciccone) Im not that keen on this functionality since vertex groups in blender are for weight painting and OBJ's groups are more like sub-objects, The conversion between these is a poor approximation (one vertex group per face). But this is still useful for using blender with poser so accepting these 2 patches. Made some changes from the patch *Export* - vgroup off by default, since this is mainly useful for corner cases - findVertexGroupName() - changed how exporting selects a vertex group for a face, use the highest combind weight for each group instead of the number of checking how many times the verts are in a group because they could have a zero weight. - findVertexGroupName() - would fail if a faces verts were not in any groups, now return a (null) group - Allow modifiers to export with vgroups *Import* - disable by default - ignore (null) groups - fixed a problem where the patch broke SPLIT_GROUPS - move the group definition out of global namespace, breaks importing as a module. --- Patch submission info The import/export scripts included with Blender 2.48 don't save/preserve groups defined in OBJ file. This presents a couple of issues: users loading an obj file with groups are not able to use a rather important set of data. When the file is then saved the groups are lost bringing up both the issue of data loss and loss of functionality as groups are used for rigging and morph target creation for Poser/DAZ Studio and all compatible applications. Of course other animation/modeling packages that use OBJ files might be affected. The solution that I present here simply patches the excellent python scripts written by Campbell Barton and Jiri Hnidek. The new code implements the preservation of groups by creating Blender vertex groups during import and by re-writing those groups in the OBJ file during export. Of course group ownership is idetermined at the face/polygon level and not at the vertex level. This rather simple solution makes Blender instantly one of the better tools to create Poser Morph targets (Full Body Morphs) and conforming figures and clothing. Of course it's also adding a more complete support for the whole OBJ spec. The patches are fitting well inside the established logic, have a minimal impact and are totally transparent to the user. See the attached video (about 7 minutes long) for more details. I noticed that the original scripts are formatted with tabs. I think it would be a good idea to follow the standard Python recommendation and convert the scripts to use spaces. I didn't want to do it on my side as it would generate a patch that replaces the whole file, not something that I wanted to do with my first submission :) But it would help if people with access to SVN could do it. Here is a short video that demonstrates the updates: http://www.paolociccone.com/blender_obj_scripts.html Cheers! ---- --- release/scripts/export_obj.py | 106 +++++++++++++++++++++++++--------- release/scripts/import_obj.py | 68 +++++++++++++++++----- 2 files changed, 133 insertions(+), 41 deletions(-) diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py index 28e1443e953..0edc70a874b 100644 --- a/release/scripts/export_obj.py +++ b/release/scripts/export_obj.py @@ -7,9 +7,9 @@ Group: 'Export' Tooltip: 'Save a Wavefront OBJ File' """ -__author__ = "Campbell Barton, Jiri Hnidek" +__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone" __url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] -__version__ = "1.2" +__version__ = "1.21" __bpydoc__ = """\ This script is an exporter to OBJ file format. @@ -185,7 +185,8 @@ def write(filename, objects,\ EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ -EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False): +EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False,\ +EXPORT_POLYGROUPS=False): ''' Basic write function. The context and options must be alredy set This can be accessed externaly @@ -199,6 +200,29 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal def veckey2d(v): return round(v.x, 6), round(v.y, 6) + def findVertexGroupName(face, vWeightMap): + """ + Searches the vertexDict to see what groups is assigned to a given face. + We use a frequency system in order to sort out the name because a given vetex can + belong to two or more groups at the same time. To find the right name for the face + we list all the possible vertex group names with their frequency and then sort by + frequency in descend order. The top element is the one shared by the highest number + of vertices is the face's group + """ + weightDict = {} + for vert in face: + vWeights = vWeightMap[vert.index] + for vGroupName, weight in vWeights: + weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight + + if weightDict: + alist = [(weight,vGroupName) for vGroupName, weight in weightDict.iteritems()] # sort least to greatest amount of weight + alist.sort() + return(alist[-1][1]) # highest value last + else: + return '(null)' + + print 'OBJ Export path: "%s"' % filename temp_mesh_name = '~tmp-mesh' @@ -239,12 +263,12 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal globalNormals = {} - # Get all meshs + # Get all meshes for ob_main in objects: for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): # Will work for non meshes now! :) # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) - me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scn) + me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) if not me: continue @@ -397,6 +421,17 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal if not faceuv: f_image = None + if EXPORT_POLYGROUPS: + # Retrieve the list of vertex groups + vertGroupNames = me.getVertGroupNames() + + currentVGroup = '' + # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to + vgroupsMap = [[] for _i in xrange(len(me.verts))] + for vertexGroupName in vertGroupNames: + for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): + vgroupsMap[vIdx].append((vertexGroupName, vWeight)) + for f_index, f in enumerate(faces): f_v= f.v f_smooth= f.smooth @@ -411,9 +446,18 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal else: key = materialNames[f_mat], None # No image, use None instead. + # Write the vertex group + if EXPORT_POLYGROUPS: + if vertGroupNames: + # find what vertext group the face belongs to + theVGroup = findVertexGroupName(f,vgroupsMap) + if theVGroup != currentVGroup: + currentVGroup = theVGroup + file.write('g %s\n' % theVGroup) + # CHECK FOR CONTEXT SWITCH if key == contextMat: - pass # Context alredy switched, dont do anythoing + pass # Context alredy switched, dont do anything else: if key[0] == None and key[1] == None: # Write a null material, since we know the context has changed. @@ -438,6 +482,7 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal if EXPORT_GROUP_BY_MAT: file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) + file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) contextMat = key @@ -539,7 +584,8 @@ def write_ui(filename): EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ + EXPORT_POLYGROUPS EXPORT_APPLY_MODIFIERS = Draw.Create(0) EXPORT_ROTX90 = Draw.Create(1) @@ -557,6 +603,8 @@ def write_ui(filename): EXPORT_GROUP_BY_OB = Draw.Create(0) EXPORT_GROUP_BY_MAT = Draw.Create(0) EXPORT_KEEP_VERT_ORDER = Draw.Create(1) + EXPORT_POLYGROUPS = Draw.Create(0) + # Old UI ''' @@ -607,7 +655,7 @@ def write_ui(filename): GLOBALS['EVENT'] = e def do_split(e,v): - global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER + global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER, EXPORT_POLYGROUPS if EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val: EXPORT_KEEP_VERT_ORDER.val = 0 else: @@ -621,6 +669,7 @@ def write_ui(filename): if not (EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val): EXPORT_KEEP_VERT_ORDER.val = 1 + def do_help(e,v): url = __url__[0] print 'Trying to open web browser with documentation at this address...' @@ -637,43 +686,45 @@ def write_ui(filename): # Center based on overall pup size ui_x -= 165 - ui_y -= 110 + ui_y -= 140 global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ + EXPORT_POLYGROUPS - Draw.Label('Context...', ui_x+9, ui_y+209, 220, 20) + Draw.Label('Context...', ui_x+9, ui_y+239, 220, 20) Draw.BeginAlign() - EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+189, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.') - EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+189, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.') - EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+189, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.') + EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+219, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.') + EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+219, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.') + EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+219, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.') Draw.EndAlign() - Draw.Label('Output Options...', ui_x+9, ui_y+159, 220, 20) + Draw.Label('Output Options...', ui_x+9, ui_y+189, 220, 20) Draw.BeginAlign() - EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+140, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split) - EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+140, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP') - EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+140, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.') + EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+170, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split) + EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+170, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP') + EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+170, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.') Draw.EndAlign() - Draw.Label('Export...', ui_x+9, ui_y+109, 220, 20) + Draw.Label('Export...', ui_x+9, ui_y+139, 220, 20) Draw.BeginAlign() - EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+90, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.') - EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+90, 70, 20, EXPORT_TRI.val, 'Triangulate quads.') + EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+120, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.') + EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+120, 70, 20, EXPORT_TRI.val, 'Triangulate quads.') Draw.EndAlign() Draw.BeginAlign() - EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+90, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.') - EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+90, 31, 20, EXPORT_UV.val, 'Export texface UV coords.') + EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+120, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.') + EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+120, 31, 20, EXPORT_UV.val, 'Export texface UV coords.') Draw.EndAlign() Draw.BeginAlign() - EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+90, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).') - EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+90, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.') + EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+120, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).') + EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+120, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.') Draw.EndAlign() + EXPORT_POLYGROUPS = Draw.Toggle('Polygroups', EVENT_REDRAW, ui_x+9, ui_y+95, 120, 20, EXPORT_POLYGROUPS.val, 'Export vertex groups as OBJ groups (one group per face approximation).') Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20) @@ -727,7 +778,7 @@ def write_ui(filename): EXPORT_GROUP_BY_OB = EXPORT_GROUP_BY_OB.val EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val EXPORT_KEEP_VERT_ORDER = EXPORT_KEEP_VERT_ORDER.val - + EXPORT_POLYGROUPS = EXPORT_POLYGROUPS.val base_name, ext = splitExt(filename) @@ -776,7 +827,8 @@ def write_ui(filename): EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ EXPORT_ROTX90, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER) + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ + EXPORT_POLYGROUPS) Blender.Set('curframe', orig_frame) diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py index 63da4606f38..31501173fda 100644 --- a/release/scripts/import_obj.py +++ b/release/scripts/import_obj.py @@ -7,9 +7,9 @@ Group: 'Import' Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' """ -__author__= "Campbell Barton", "Jiri Hnidek" +__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" __url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] -__version__= "2.1" +__version__= "2.11" __bpydoc__= """\ This script imports a Wavefront OBJ files to Blender. @@ -49,7 +49,6 @@ import BPyMessages try: import os except: os= False - # Generic path functions def stripFile(path): '''Return directory, where the file is''' @@ -320,7 +319,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.iteritems()] -def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, dataname): +def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): ''' Takes all the data gathered and generates a mesh, adding the new object to new_objects deals with fgons, sharp edges and assigning materials @@ -530,6 +529,13 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l ob= scn.objects.new(me) new_objects.append(ob) + # Create the vertex groups. No need to have the flag passed here since we test for the + # content of the vertex_groups. If the user selects to NOT have vertex groups saved then + # the following test will never run + for group_name, group_indicies in vertex_groups.iteritems(): + me.addVertGroup(group_name) + me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE) + def get_float_func(filepath): ''' find the float function for this obj file @@ -547,7 +553,16 @@ def get_float_func(filepath): # incase all vert values were ints return float -def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS= True, CREATE_EDGES= True, SPLIT_OBJECTS= True, SPLIT_GROUPS= True, SPLIT_MATERIALS= True, IMAGE_SEARCH=True): +def load_obj(filepath, + CLAMP_SIZE= 0.0, + CREATE_FGONS= True, + CREATE_SMOOTH_GROUPS= True, + CREATE_EDGES= True, + SPLIT_OBJECTS= True, + SPLIT_GROUPS= True, + SPLIT_MATERIALS= True, + IMAGE_SEARCH=True, + POLYGROUPS=False): ''' Called by the user interface or another script. load_obj(path) - should give acceptable results. @@ -556,13 +571,16 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS ''' print '\nimporting obj "%s"' % filepath + if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: + POLYGROUPS = False + time_main= sys.time() verts_loc= [] verts_tex= [] faces= [] # tuples of the faces material_libs= [] # filanems to material libs this uses - + vertex_groups = {} # when POLYGROUPS is true # Get the string to float conversion func for this file- is 'float' for almost all files. float_func= get_float_func(filepath) @@ -571,7 +589,8 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS context_material= None context_smooth_group= None context_object= None - + context_vgroup = None + has_ngons= False # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0 @@ -589,6 +608,7 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS print '\tparsing obj file "%s"...' % filepath, time_sub= sys.time() + file= open(filepath, 'rU') for line in file: #.xreadlines(): line = line.lstrip() # rare cases there is white space at the start of the line @@ -641,6 +661,10 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS obj_vert= v.split('/') vert_loc_index= int(obj_vert[0])-1 + # Add the vertex to the current group + # *warning*, this wont work for files that have groups defined around verts + if POLYGROUPS and context_vgroup: + vertex_groups[context_vgroup].append(vert_loc_index) # Make relative negative vert indicies absolute if vert_loc_index < 0: @@ -684,6 +708,12 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS context_object= line_value(line.split()) # print 'context_object', context_object # unique_obects[context_object]= None + elif POLYGROUPS: + context_vgroup = line_value(line.split()) + if context_vgroup and context_vgroup != '(null)': + vertex_groups.setdefault(context_vgroup, []) + else: + context_vgroup = None # dont assign a vgroup elif line.startswith('usemtl'): context_material= line_value(line.split()) @@ -721,8 +751,8 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS else: SPLIT_OB_OR_GROUP = False for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): - # Create meshes from the data - create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, dataname) + # Create meshes from the data, warning 'vertex_groups' wont support splitting + create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) axis_min= [ 1000000000]*3 axis_max= [-1000000000]*3 @@ -758,7 +788,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): if BPyMessages.Error_NoFile(filepath): return - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, KEEP_VERT_ORDER + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER CREATE_SMOOTH_GROUPS= Draw.Create(0) CREATE_FGONS= Draw.Create(1) @@ -768,6 +798,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): SPLIT_MATERIALS= Draw.Create(0) CLAMP_SIZE= Draw.Create(10.0) IMAGE_SEARCH= Draw.Create(1) + POLYGROUPS= Draw.Create(0) KEEP_VERT_ORDER= Draw.Create(1) @@ -817,9 +848,10 @@ def load_obj_ui(filepath, BATCH_LOAD= False): GLOBALS['EVENT'] = e def do_split(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val: KEEP_VERT_ORDER.val = 0 + POLYGROUPS.val = 0 else: KEEP_VERT_ORDER.val = 1 @@ -831,6 +863,11 @@ def load_obj_ui(filepath, BATCH_LOAD= False): if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val): KEEP_VERT_ORDER.val = 1 + def do_polygroups(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS + if POLYGROUPS.val: + SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 + def do_help(e,v): url = __url__[0] print 'Trying to open web browser with documentation at this address...' @@ -849,7 +886,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): ui_x -= 165 ui_y -= 90 - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, KEEP_VERT_ORDER + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21) Draw.BeginAlign() @@ -869,8 +906,9 @@ def load_obj_ui(filepath, BATCH_LOAD= False): KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+229, ui_y+89, 110, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20) - CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 211, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') - IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+229, ui_y+39, 110, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)') + CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') + POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups) + IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)') Draw.BeginAlign() Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help) Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event) @@ -921,6 +959,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): SPLIT_GROUPS.val,\ SPLIT_MATERIALS.val,\ IMAGE_SEARCH.val,\ + POLYGROUPS.val ) else: # Normal load @@ -933,6 +972,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): SPLIT_GROUPS.val,\ SPLIT_MATERIALS.val,\ IMAGE_SEARCH.val,\ + POLYGROUPS.val ) Window.WaitCursor(0) From 82b4975ccfa8fe2c72278388a3cf3a8432cc9fb0 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 13 May 2009 06:42:15 +0000 Subject: [PATCH 224/444] BGE #18732: Python Light options don't work with GLSL materials. Commited patch from dfelinto and moguri, thanks for the good work. --- source/blender/gpu/GPU_material.h | 1 + source/blender/gpu/intern/gpu_material.c | 12 ++++++++++++ source/blender/src/drawview.c | 2 ++ source/gameengine/Ketsji/KX_Light.cpp | 9 +++++++++ source/gameengine/Ketsji/KX_Light.h | 1 + 5 files changed, 25 insertions(+) diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index ccc687858f4..49c0dc166c1 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -159,6 +159,7 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]); +void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); int GPU_lamp_shadow_layer(GPULamp *lamp); #ifdef __cplusplus diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 87703bc73bf..f7052694fc7 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1306,6 +1306,18 @@ void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]) Mat4Invert(lamp->imat, mat); } +void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy) +{ + lamp->la->energy = energy; + lamp->la->r = r; + lamp->la->g = g; + lamp->la->b = b; + + lamp->col[0]= lamp->la->r*lamp->energy; + lamp->col[1]= lamp->la->g*lamp->energy; + lamp->col[2]= lamp->la->b*lamp->energy; +} + static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) { float temp, angle, pixsize, wsize; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index d6184f42410..9b2f7fe53d9 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3152,12 +3152,14 @@ typedef struct View3DShadow{ static void gpu_render_lamp_update(View3D *v3d, Object *ob, Object *par, float obmat[][4], ListBase *shadows) { GPULamp *lamp; + Lamp *la = (Lamp*)ob->data; View3DShadow *shadow; lamp = GPU_lamp_from_blender(G.scene, ob, par); if(lamp) { GPU_lamp_update(lamp, ob->lay, obmat); + GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy); if((ob->lay & v3d->lay) && GPU_lamp_has_shadow_buffer(lamp)) { shadow= MEM_callocN(sizeof(View3DShadow), "View3DShadow"); diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 777a7f32629..3af34c39123 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -61,6 +61,11 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_rendertools->AddLight(&m_lightobj); m_glsl = glsl; m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene(); + + m_initialvalues[0] = lightobj.m_red; + m_initialvalues[1] = lightobj.m_green; + m_initialvalues[2] = lightobj.m_blue; + m_initialvalues[3] = lightobj.m_energy; }; @@ -71,6 +76,8 @@ KX_LightObject::~KX_LightObject() if((lamp = GetGPULamp())) { float obmat[4][4] = {{0}}; GPU_lamp_update(lamp, 0, obmat); + GPU_lamp_update_colors(lamp, m_initialvalues[0], m_initialvalues[1], + m_initialvalues[2], m_initialvalues[3]); } m_rendertools->RemoveLight(&m_lightobj); @@ -114,6 +121,8 @@ void KX_LightObject::Update() obmat[i][j] = (float)*dobmat; GPU_lamp_update(lamp, m_lightobj.m_layer, obmat); + GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green, + m_lightobj.m_blue, m_lightobj.m_energy); } } diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 35f25515e3b..690231ff090 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -44,6 +44,7 @@ class KX_LightObject : public KX_GameObject Py_Header; protected: RAS_LightObject m_lightobj; + float m_initialvalues [4]; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj bool m_glsl; Scene* m_blenderscene; From b22605c4dfc31f4e6e1419ca19cbd2ada57c52ce Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 13 May 2009 06:53:21 +0000 Subject: [PATCH 225/444] BGE #18691: Blenderplayer fullscreen messes up desktop on OS X Leopard. Applied patch #18705 by sbn. I cannot compile osx but the patch seems perfectly alright to me. Can OSX users confirm that it compiles well on the various OSX version? --- intern/ghost/intern/GHOST_SystemCarbon.cpp | 24 +++++++++++++++++++++- intern/ghost/intern/GHOST_SystemCarbon.h | 8 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp index 067c8deee32..e6ab6528c70 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.cpp +++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp @@ -34,7 +34,6 @@ * @date May 7, 2001 */ - #include #include #include "GHOST_SystemCarbon.h" @@ -430,6 +429,29 @@ GHOST_IWindow* GHOST_SystemCarbon::createWindow( return window; } +GHOST_TSuccess GHOST_SystemCarbon::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual) +{ + GHOST_TSuccess success = GHOST_kFailure; + + // need yo make this Carbon all on 10.5 for fullscreen to work correctly + CGCaptureAllDisplays(); + + success = GHOST_System::beginFullScreen( setting, window, stereoVisual); + + if( success != GHOST_kSuccess ) { + // fullscreen failed for other reasons, release + CGReleaseAllDisplays(); + } + + return success; +} + +GHOST_TSuccess GHOST_SystemCarbon::endFullScreen(void) +{ + CGReleaseAllDisplays(); + return GHOST_System::endFullScreen(); +} + /* this is an old style low level event queue. As we want to handle our own timers, this is ok. the full screen hack should be removed */ diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h index 2a1d6325784..71ac5719370 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.h +++ b/intern/ghost/intern/GHOST_SystemCarbon.h @@ -118,6 +118,14 @@ public: const GHOST_TEmbedderWindowID parentWindow = 0 ); + virtual GHOST_TSuccess beginFullScreen( + const GHOST_DisplaySetting& setting, + GHOST_IWindow** window, + const bool stereoVisual + ); + + virtual GHOST_TSuccess endFullScreen( void ); + /*************************************************************************************** ** Event management functionality ***************************************************************************************/ From 24f326fb014be09b63850ef1effd02f9697ccf79 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 May 2009 10:15:19 +0000 Subject: [PATCH 226/444] Moved game engine types into GameTypes.py because every type put into a module giving lots of references to KX_GameObject.KX_GameObject and having to write in links like L{CListValue}. Looked into ways around this but epydoc has no way to import a class without its module and the @include field is maked as 'TODO'. Also removed the outdated 'WhatsNew' section and linked to the 2.49 release notes. --- source/gameengine/PyDoc/BL_ActionActuator.py | 230 - source/gameengine/PyDoc/BL_Shader.py | 248 - .../PyDoc/BL_ShapeActionActuator.py | 199 - source/gameengine/PyDoc/CListValue.py | 61 - source/gameengine/PyDoc/CPropValue.py | 8 - source/gameengine/PyDoc/CValue.py | 8 - source/gameengine/PyDoc/GameLogic.py | 70 +- source/gameengine/PyDoc/GameTypes.py | 5468 ++++++++++++++++- source/gameengine/PyDoc/KX_BlenderMaterial.py | 41 - source/gameengine/PyDoc/KX_CDActuator.py | 55 - source/gameengine/PyDoc/KX_Camera.py | 212 - source/gameengine/PyDoc/KX_CameraActuator.py | 98 - .../gameengine/PyDoc/KX_ConstraintActuator.py | 249 - .../gameengine/PyDoc/KX_ConstraintWrapper.py | 28 - source/gameengine/PyDoc/KX_GameActuator.py | 31 - source/gameengine/PyDoc/KX_GameObject.py | 507 -- source/gameengine/PyDoc/KX_IpoActuator.py | 124 - source/gameengine/PyDoc/KX_LightObject.py | 45 - source/gameengine/PyDoc/KX_MeshProxy.py | 134 - .../gameengine/PyDoc/KX_MouseFocusSensor.py | 67 - source/gameengine/PyDoc/KX_NearSensor.py | 14 - .../PyDoc/KX_NetworkMessageActuator.py | 49 - .../PyDoc/KX_NetworkMessageSensor.py | 60 - source/gameengine/PyDoc/KX_ObjectActuator.py | 250 - source/gameengine/PyDoc/KX_ParentActuator.py | 29 - .../PyDoc/KX_PhysicsObjectWrapper.py | 60 - source/gameengine/PyDoc/KX_PolyProxy.py | 101 - source/gameengine/PyDoc/KX_PolygonMaterial.py | 281 - source/gameengine/PyDoc/KX_RadarSensor.py | 49 - source/gameengine/PyDoc/KX_RaySensor.py | 58 - .../PyDoc/KX_SCA_AddObjectActuator.py | 118 - .../PyDoc/KX_SCA_DynamicActuator.py | 30 - .../PyDoc/KX_SCA_EndObjectActuator.py | 11 - .../PyDoc/KX_SCA_ReplaceMeshActuator.py | 84 - source/gameengine/PyDoc/KX_Scene.py | 97 - source/gameengine/PyDoc/KX_SceneActuator.py | 71 - source/gameengine/PyDoc/KX_SoundActuator.py | 195 - source/gameengine/PyDoc/KX_StateActuator.py | 44 - source/gameengine/PyDoc/KX_TouchSensor.py | 63 - source/gameengine/PyDoc/KX_TrackToActuator.py | 70 - source/gameengine/PyDoc/KX_VehicleWrapper.py | 160 - source/gameengine/PyDoc/KX_VertexProxy.py | 152 - .../gameengine/PyDoc/KX_VisibilityActuator.py | 22 - source/gameengine/PyDoc/PyObjectPlus.py | 26 - .../gameengine/PyDoc/SCA_2DFilterActuator.py | 44 - source/gameengine/PyDoc/SCA_ANDController.py | 11 - source/gameengine/PyDoc/SCA_ActuatorSensor.py | 33 - source/gameengine/PyDoc/SCA_AlwaysSensor.py | 9 - source/gameengine/PyDoc/SCA_DelaySensor.py | 72 - source/gameengine/PyDoc/SCA_IActuator.py | 9 - source/gameengine/PyDoc/SCA_IController.py | 63 - source/gameengine/PyDoc/SCA_ILogicBrick.py | 49 - source/gameengine/PyDoc/SCA_IObject.py | 9 - source/gameengine/PyDoc/SCA_ISensor.py | 112 - source/gameengine/PyDoc/SCA_JoystickSensor.py | 169 - source/gameengine/PyDoc/SCA_KeyboardSensor.py | 116 - source/gameengine/PyDoc/SCA_MouseSensor.py | 44 - source/gameengine/PyDoc/SCA_NANDController.py | 11 - source/gameengine/PyDoc/SCA_NORController.py | 11 - source/gameengine/PyDoc/SCA_ORController.py | 11 - .../gameengine/PyDoc/SCA_PropertyActuator.py | 49 - source/gameengine/PyDoc/SCA_PropertySensor.py | 74 - .../gameengine/PyDoc/SCA_PythonController.py | 41 - source/gameengine/PyDoc/SCA_RandomActuator.py | 175 - source/gameengine/PyDoc/SCA_RandomSensor.py | 35 - source/gameengine/PyDoc/SCA_XNORController.py | 11 - source/gameengine/PyDoc/SCA_XORController.py | 11 - source/gameengine/PyDoc/WhatsNew.py | 34 - 68 files changed, 5432 insertions(+), 5748 deletions(-) delete mode 100644 source/gameengine/PyDoc/BL_ActionActuator.py delete mode 100644 source/gameengine/PyDoc/BL_Shader.py delete mode 100644 source/gameengine/PyDoc/BL_ShapeActionActuator.py delete mode 100644 source/gameengine/PyDoc/CListValue.py delete mode 100644 source/gameengine/PyDoc/CPropValue.py delete mode 100644 source/gameengine/PyDoc/CValue.py delete mode 100644 source/gameengine/PyDoc/KX_BlenderMaterial.py delete mode 100644 source/gameengine/PyDoc/KX_CDActuator.py delete mode 100644 source/gameengine/PyDoc/KX_Camera.py delete mode 100644 source/gameengine/PyDoc/KX_CameraActuator.py delete mode 100644 source/gameengine/PyDoc/KX_ConstraintActuator.py delete mode 100644 source/gameengine/PyDoc/KX_ConstraintWrapper.py delete mode 100644 source/gameengine/PyDoc/KX_GameActuator.py delete mode 100644 source/gameengine/PyDoc/KX_GameObject.py delete mode 100644 source/gameengine/PyDoc/KX_IpoActuator.py delete mode 100644 source/gameengine/PyDoc/KX_LightObject.py delete mode 100644 source/gameengine/PyDoc/KX_MeshProxy.py delete mode 100644 source/gameengine/PyDoc/KX_MouseFocusSensor.py delete mode 100644 source/gameengine/PyDoc/KX_NearSensor.py delete mode 100644 source/gameengine/PyDoc/KX_NetworkMessageActuator.py delete mode 100644 source/gameengine/PyDoc/KX_NetworkMessageSensor.py delete mode 100644 source/gameengine/PyDoc/KX_ObjectActuator.py delete mode 100644 source/gameengine/PyDoc/KX_ParentActuator.py delete mode 100644 source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py delete mode 100644 source/gameengine/PyDoc/KX_PolyProxy.py delete mode 100644 source/gameengine/PyDoc/KX_PolygonMaterial.py delete mode 100644 source/gameengine/PyDoc/KX_RadarSensor.py delete mode 100644 source/gameengine/PyDoc/KX_RaySensor.py delete mode 100644 source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py delete mode 100644 source/gameengine/PyDoc/KX_SCA_DynamicActuator.py delete mode 100644 source/gameengine/PyDoc/KX_SCA_EndObjectActuator.py delete mode 100644 source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py delete mode 100644 source/gameengine/PyDoc/KX_Scene.py delete mode 100644 source/gameengine/PyDoc/KX_SceneActuator.py delete mode 100644 source/gameengine/PyDoc/KX_SoundActuator.py delete mode 100644 source/gameengine/PyDoc/KX_StateActuator.py delete mode 100644 source/gameengine/PyDoc/KX_TouchSensor.py delete mode 100644 source/gameengine/PyDoc/KX_TrackToActuator.py delete mode 100644 source/gameengine/PyDoc/KX_VehicleWrapper.py delete mode 100644 source/gameengine/PyDoc/KX_VertexProxy.py delete mode 100644 source/gameengine/PyDoc/KX_VisibilityActuator.py delete mode 100644 source/gameengine/PyDoc/PyObjectPlus.py delete mode 100644 source/gameengine/PyDoc/SCA_2DFilterActuator.py delete mode 100644 source/gameengine/PyDoc/SCA_ANDController.py delete mode 100644 source/gameengine/PyDoc/SCA_ActuatorSensor.py delete mode 100644 source/gameengine/PyDoc/SCA_AlwaysSensor.py delete mode 100644 source/gameengine/PyDoc/SCA_DelaySensor.py delete mode 100644 source/gameengine/PyDoc/SCA_IActuator.py delete mode 100644 source/gameengine/PyDoc/SCA_IController.py delete mode 100644 source/gameengine/PyDoc/SCA_ILogicBrick.py delete mode 100644 source/gameengine/PyDoc/SCA_IObject.py delete mode 100644 source/gameengine/PyDoc/SCA_ISensor.py delete mode 100644 source/gameengine/PyDoc/SCA_JoystickSensor.py delete mode 100644 source/gameengine/PyDoc/SCA_KeyboardSensor.py delete mode 100644 source/gameengine/PyDoc/SCA_MouseSensor.py delete mode 100644 source/gameengine/PyDoc/SCA_NANDController.py delete mode 100644 source/gameengine/PyDoc/SCA_NORController.py delete mode 100644 source/gameengine/PyDoc/SCA_ORController.py delete mode 100644 source/gameengine/PyDoc/SCA_PropertyActuator.py delete mode 100644 source/gameengine/PyDoc/SCA_PropertySensor.py delete mode 100644 source/gameengine/PyDoc/SCA_PythonController.py delete mode 100644 source/gameengine/PyDoc/SCA_RandomActuator.py delete mode 100644 source/gameengine/PyDoc/SCA_RandomSensor.py delete mode 100644 source/gameengine/PyDoc/SCA_XNORController.py delete mode 100644 source/gameengine/PyDoc/SCA_XORController.py delete mode 100644 source/gameengine/PyDoc/WhatsNew.py diff --git a/source/gameengine/PyDoc/BL_ActionActuator.py b/source/gameengine/PyDoc/BL_ActionActuator.py deleted file mode 100644 index 455f83d5ce7..00000000000 --- a/source/gameengine/PyDoc/BL_ActionActuator.py +++ /dev/null @@ -1,230 +0,0 @@ -# $Id$ -# Documentation for BL_ActionActuator -import SCA_ILogicBrick -from SCA_IActuator import * - - -class BL_ActionActuator(SCA_IActuator): - """ - Action Actuators apply an action to an actor. - - @ivar action: The name of the action to set as the current action. - @type action: string - @ivar start: Specifies the starting frame of the animation. - @type start: float - @ivar end: Specifies the ending frame of the animation. - @type end: float - @ivar blendin: Specifies the number of frames of animation to generate when making transitions between actions. - @type blendin: float - @ivar priority: Sets the priority of this actuator. Actuators will lower - priority numbers will override actuators with higher - numbers. - @type priority: integer - @ivar frame: Sets the current frame for the animation. - @type frame: float - @ivar property: Sets the property to be used in FromProp playback mode. - @type property: string - @ivar blendTime: Sets the internal frame timer. This property must be in - the range from 0.0 to blendin. - @type blendTime: float - @ivar type: The operation mode of the actuator. KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - @type type: integer - @ivar useContinue: The actions continue option, True or False. - When True, the action will always play from where last left off, - otherwise negative events to this actuator will reset it to its start frame. - @type: boolean - @ivar frameProperty: The name of the property that is set to the current frame number. - @type frameProperty: string - """ - def setChannel(channel, matrix, mode = False): - """ - @param channel: A string specifying the name of the bone channel. - @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 - """ - - #--The following methods are deprecated-- - def setAction(action, reset = True): - """ - DEPRECATED: use the 'action' property - Sets the current action. - - @param action: The name of the action to set as the current action. - @type action: string - @param reset: Optional parameter indicating whether to reset the - blend timer or not. A value of 1 indicates that the - timer should be reset. A value of 0 will leave it - unchanged. If reset is not specified, the timer will - be reset. - """ - - def setStart(start): - """ - DEPRECATED: use the 'start' property - Specifies the starting frame of the animation. - - @param start: the starting frame of the animation - @type start: float - """ - - def setEnd(end): - """ - DEPRECATED: use the 'end' property - Specifies the ending frame of the animation. - - @param end: the ending frame of the animation - @type end: float - """ - def setBlendin(blendin): - """ - DEPRECATED: use the 'blendin' property - Specifies the number of frames of animation to generate - when making transitions between actions. - - @param blendin: the number of frames in transition. - @type blendin: float - """ - - def setPriority(priority): - """ - DEPRECATED: use the 'priority' property - Sets the priority of this actuator. - - @param priority: Specifies the new priority. Actuators will lower - priority numbers will override actuators with higher - numbers. - @type priority: integer - """ - def setFrame(frame): - """ - DEPRECATED: use the 'frame' property - Sets the current frame for the animation. - - @param frame: Specifies the new current frame for the animation - @type frame: float - """ - - def setProperty(prop): - """ - DEPRECATED: use the 'property' property - Sets the property to be used in FromProp playback mode. - - @param prop: the name of the property to use. - @type prop: string. - """ - - def setBlendtime(blendtime): - """ - DEPRECATED: use the 'blendTime' property - Sets the internal frame timer. - - Allows the script to directly modify the internal timer - used when generating transitions between actions. - - @param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0. - @type blendtime: float - """ - - def setType(mode): - """ - DEPRECATED: use the 'type' property - Sets the operation mode of the actuator - - @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - @type mode: integer - """ - - def setContinue(cont): - """ - DEPRECATED: use the 'continue' property - Set the actions continue option True or False. see getContinue. - - @param cont: The continue option. - @type cont: bool - """ - - def getType(): - """ - DEPRECATED: use the 'type' property - Returns the operation mode of the actuator - - @rtype: integer - @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - """ - - def getContinue(): - """ - DEPRECATED: use the 'continue' property - When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. - - @rtype: bool - """ - - def getAction(): - """ - DEPRECATED: use the 'action' property - getAction() returns the name of the action associated with this actuator. - - @rtype: string - """ - - def getStart(): - """ - DEPRECATED: use the 'start' property - Returns the starting frame of the action. - - @rtype: float - """ - def getEnd(): - """ - DEPRECATED: use the 'end' property - Returns the last frame of the action. - - @rtype: float - """ - def getBlendin(): - """ - DEPRECATED: use the 'blendin' property - Returns the number of interpolation animation frames to be generated when this actuator is triggered. - - @rtype: float - """ - def getPriority(): - """ - DEPRECATED: use the 'priority' property - Returns the priority for this actuator. Actuators with lower Priority numbers will - override actuators with higher numbers. - - @rtype: integer - """ - def getFrame(): - """ - DEPRECATED: use the 'frame' property - Returns the current frame number. - - @rtype: float - """ - def getProperty(): - """ - DEPRECATED: use the 'property' property - Returns the name of the property to be used in FromProp mode. - - @rtype: string - """ - def setFrameProperty(prop): - """ - DEPRECATED: use the 'frameProperty' property - @param prop: A string specifying the property of the object that will be updated with the action frame number. - @type prop: string - """ - def getFrameProperty(): - """ - DEPRECATED: use the 'frameProperty' property - Returns the name of the property that is set to the current frame number. - - @rtype: string - """ diff --git a/source/gameengine/PyDoc/BL_Shader.py b/source/gameengine/PyDoc/BL_Shader.py deleted file mode 100644 index 8fd4ae7c7ac..00000000000 --- a/source/gameengine/PyDoc/BL_Shader.py +++ /dev/null @@ -1,248 +0,0 @@ - -from PyObjectPlus import * - -class BL_Shader(PyObjectPlus): - """ - BL_Shader GLSL shaders. - - TODO - Description - """ - - def setUniformfv(name, fList): - """ - Set a uniform with a list of float values - - @param name: the uniform name - @type name: string - - @param fList: a list (2, 3 or 4 elements) of float values - @type fList: list[float] - """ - - def delSource(): - """ - TODO - Description - - """ - def getFragmentProg(): - """ - Returns the fragment program. - - @rtype: string - @return: The fragment program. - """ - def getVertexProg(): - """ - Get the vertex program. - - @rtype: string - @return: The vertex program. - """ - def isValid(): - """ - Check if the shader is valid. - - @rtype: bool - @return: True if the shader is valid - """ - def setAttrib(enum): - """ - Set attribute location. (The parameter is ignored a.t.m. and the value of "tangent" is always used.) - - @param enum: attribute location value - @type enum: integer - """ - def setNumberOfPasses( max_pass ): - """ - Set the maximum number of passes. Not used a.t.m. - - @param max_pass: the maximum number of passes - @type max_pass: integer - """ - def setSampler(name, index): - """ - Set uniform texture sample index. - - @param name: Uniform name - @type name: string - - @param index: Texture sample index. - @type index: integer - """ - def setSource(vertexProgram, fragmentProgram): - """ - Set the vertex and fragment programs - - @param vertexProgram: Vertex program - @type vertexProgram: string - - @param fragmentProgram: Fragment program - @type fragmentProgram: string - """ - def setUniform1f(name, fx): - """ - Set a uniform with 1 float value. - - @param name: the uniform name - @type name: string - - @param fx: Uniform value - @type fx: float - """ - def setUniform1i(name, ix): - """ - Set a uniform with an integer value. - - @param name: the uniform name - @type name: string - - @param ix: the uniform value - @type ix: integer - """ - def setUniform2f(name, fx, fy): - """ - Set a uniform with 2 float values - - @param name: the uniform name - @type name: string - - @param fx: first float value - @type fx: float - - @param fy: second float value - @type fy: float - """ - def setUniform2i(name, ix, iy): - """ - Set a uniform with 2 integer values - - @param name: the uniform name - @type name: string - - @param ix: first integer value - @type ix: integer - - @param iy: second integer value - @type iy: integer - """ - def setUniform3f(name, fx,fy,fz): - """ - Set a uniform with 3 float values. - - @param name: the uniform name - @type name: string - - @param fx: first float value - @type fx: float - - @param fy: second float value - @type fy: float - - @param fz: third float value - @type fz: float - """ - def setUniform3i(name, ix,iy,iz): - """ - Set a uniform with 3 integer values - - @param name: the uniform name - @type name: string - - @param ix: first integer value - @type ix: integer - - @param iy: second integer value - @type iy: integer - - @param iz: third integer value - @type iz: integer - """ - def setUniform4f(name, fx,fy,fz,fw): - """ - Set a uniform with 4 float values. - - @param name: the uniform name - @type name: string - - @param fx: first float value - @type fx: float - - @param fy: second float value - @type fy: float - - @param fz: third float value - @type fz: float - - @param fw: fourth float value - @type fw: float - """ - def setUniform4i(name, ix,iy,iz, iw): - """ - Set a uniform with 4 integer values - - @param name: the uniform name - @type name: string - - @param ix: first integer value - @type ix: integer - - @param iy: second integer value - @type iy: integer - - @param iz: third integer value - @type iz: integer - - @param iw: fourth integer value - @type iw: integer - """ - def setUniformDef(name, type): - """ - Define a new uniform - - @param name: the uniform name - @type name: string - - @param type: uniform type - @type type: UNI_NONE, UNI_INT, UNI_FLOAT, UNI_INT2, UNI_FLOAT2, UNI_INT3, UNI_FLOAT3, UNI_INT4, UNI_FLOAT4, UNI_MAT3, UNI_MAT4, UNI_MAX - """ - def setUniformMatrix3(name, mat, transpose): - """ - Set a uniform with a 3x3 matrix value - - @param name: the uniform name - @type name: string - - @param mat: A 3x3 matrix [[f,f,f], [f,f,f], [f,f,f]] - @type mat: 3x3 matrix - - @param transpose: set to True to transpose the matrix - @type transpose: bool - """ - def setUniformMatrix4(name, mat, transpose): - """ - Set a uniform with a 4x4 matrix value - - @param name: the uniform name - @type name: string - - @param mat: A 4x4 matrix [[f,f,f,f], [f,f,f,f], [f,f,f,f], [f,f,f,f]] - @type mat: 4x4 matrix - - @param transpose: set to True to transpose the matrix - @type transpose: bool - """ - def setUniformiv(name, iList): - """ - Set a uniform with a list of integer values - - @param name: the uniform name - @type name: string - - @param iList: a list (2, 3 or 4 elements) of integer values - @type iList: list[integer] - """ - def validate(): - """ - Validate the shader object. - - """ diff --git a/source/gameengine/PyDoc/BL_ShapeActionActuator.py b/source/gameengine/PyDoc/BL_ShapeActionActuator.py deleted file mode 100644 index e1e8b039749..00000000000 --- a/source/gameengine/PyDoc/BL_ShapeActionActuator.py +++ /dev/null @@ -1,199 +0,0 @@ -# $Id$ -# Documentation for BL_ShapeActionActuator -from SCA_IActuator import * -from SCA_ILogicBrick import * - -class BL_ShapeActionActuator(SCA_IActuator): - """ - ShapeAction Actuators apply an shape action to an mesh object.\ - - @ivar action: The name of the action to set as the current shape action. - @type action: string - @ivar start: Specifies the starting frame of the shape animation. - @type start: float - @ivar end: Specifies the ending frame of the shape animation. - @type end: float - @ivar blendin: Specifies the number of frames of animation to generate when making transitions between actions. - @type blendin: float - @ivar priority: Sets the priority of this actuator. Actuators will lower - priority numbers will override actuators with higher - numbers. - @type priority: integer - @ivar frame: Sets the current frame for the animation. - @type frame: float - @ivar property: Sets the property to be used in FromProp playback mode. - @type property: string - @ivar blendTime: Sets the internal frame timer. This property must be in - the range from 0.0 to blendin. - @type blendTime: float - @ivar type: The operation mode of the actuator. - KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, - KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - @type type: integer - @ivar frameProperty: The name of the property that is set to the current frame number. - @type frameProperty: string - - """ - def setAction(action, reset = True): - """ - DEPRECATED: use the 'action' property - Sets the current action. - - @param action: The name of the action to set as the current action. - @type action: string - @param reset: Optional parameter indicating whether to reset the - blend timer or not. A value of 1 indicates that the - timer should be reset. A value of 0 will leave it - unchanged. If reset is not specified, the timer will - be reset. - """ - - def setStart(start): - """ - DEPRECATED: use the 'start' property - Specifies the starting frame of the animation. - - @param start: the starting frame of the animation - @type start: float - """ - - def setEnd(end): - """ - DEPRECATED: use the 'end' property - Specifies the ending frame of the animation. - - @param end: the ending frame of the animation - @type end: float - """ - def setBlendin(blendin): - """ - DEPRECATED: use the 'blendin' property - Specifies the number of frames of animation to generate - when making transitions between actions. - - @param blendin: the number of frames in transition. - @type blendin: float - """ - - def setPriority(priority): - """ - DEPRECATED: use the 'priority' property - Sets the priority of this actuator. - - @param priority: Specifies the new priority. Actuators will lower - priority numbers will override actuators with higher - numbers. - @type priority: integer - """ - def setFrame(frame): - """ - DEPRECATED: use the 'frame' property - Sets the current frame for the animation. - - @param frame: Specifies the new current frame for the animation - @type frame: float - """ - - def setProperty(prop): - """ - DEPRECATED: use the 'property' property - Sets the property to be used in FromProp playback mode. - - @param prop: the name of the property to use. - @type prop: string. - """ - - def setBlendtime(blendtime): - """ - DEPRECATED: use the 'blendTime' property - Sets the internal frame timer. - - Allows the script to directly modify the internal timer - used when generating transitions between actions. - - @param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0. - @type blendtime: float - """ - - def setType(mode): - """ - DEPRECATED: use the 'type' property - Sets the operation mode of the actuator - - @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - @type mode: integer - """ - - def getType(): - """ - DEPRECATED: use the 'type' property - Returns the operation mode of the actuator - - @rtype: integer - @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - """ - - def getAction(): - """ - DEPRECATED: use the 'action' property - getAction() returns the name of the action associated with this actuator. - - @rtype: string - """ - - def getStart(): - """ - DEPRECATED: use the 'start' property - Returns the starting frame of the action. - - @rtype: float - """ - def getEnd(): - """ - DEPRECATED: use the 'end' property - Returns the last frame of the action. - - @rtype: float - """ - def getBlendin(): - """ - DEPRECATED: use the 'blendin' property - Returns the number of interpolation animation frames to be generated when this actuator is triggered. - - @rtype: float - """ - def getPriority(): - """ - DEPRECATED: use the 'priority' property - Returns the priority for this actuator. Actuators with lower Priority numbers will - override actuators with higher numbers. - - @rtype: integer - """ - def getFrame(): - """ - DEPRECATED: use the 'frame' property - Returns the current frame number. - - @rtype: float - """ - def getProperty(): - """ - DEPRECATED: use the 'property' property - Returns the name of the property to be used in FromProp mode. - - @rtype: string - """ - def setFrameProperty(prop): - """ - DEPRECATED: use the 'frameProperty' property - @param prop: A string specifying the property of the object that will be updated with the action frame number. - @type prop: string - """ - def getFrameProperty(): - """ - DEPRECATED: use the 'frameProperty' property - Returns the name of the property that is set to the current frame number. - - @rtype: string - """ diff --git a/source/gameengine/PyDoc/CListValue.py b/source/gameengine/PyDoc/CListValue.py deleted file mode 100644 index 1f60e8a7bc2..00000000000 --- a/source/gameengine/PyDoc/CListValue.py +++ /dev/null @@ -1,61 +0,0 @@ -from CPropValue import * - -class CListValue(CPropValue): - """ - CListValue - - This is a list like object used in the game engine internally that behaves similar to a python list in most ways. - - As well as the normal index lookup. - C{val= clist[i]} - - CListValue supports string lookups. - C{val= scene.objects["OBCube"]} - - Other operations such as C{len(clist), list(clist), clist[0:10]} are also supported. - """ - def append(val): - """ - Add an item to the list (like pythons append) - - Warning: Appending values to the list can cause crashes when the list is used internally by the game engine. - """ - - def count(val): - """ - Count the number of instances of a value in the list. - - @rtype: integer - @return: number of instances - """ - def index(val): - """ - Return the index of a value in the list. - - @rtype: integer - @return: The index of the value in the list. - """ - def reverse(): - """ - Reverse the order of the list. - """ - def from_id(id): - """ - This is a funtion especially for the game engine to return a value with a spesific id. - - Since object names are not always unique, the id of an object can be used to get an object from the CValueList. - - Example. - - C{myObID = id(gameObject)} - - C{...} - - C{ob= scene.objects.from_id(myObID)} - - Where myObID is an int or long from the id function. - - This has the advantage that you can store the id in places you could not store a gameObject. - - Warning: the id is derived from a memory location and will be different each time the game engine starts. - """ \ No newline at end of file diff --git a/source/gameengine/PyDoc/CPropValue.py b/source/gameengine/PyDoc/CPropValue.py deleted file mode 100644 index 498b47ab013..00000000000 --- a/source/gameengine/PyDoc/CPropValue.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Documentation for CValue class -from CValue import * -class CPropValue(CValue): - """ - This class has no python functions - """ - pass diff --git a/source/gameengine/PyDoc/CValue.py b/source/gameengine/PyDoc/CValue.py deleted file mode 100644 index e9b0563955b..00000000000 --- a/source/gameengine/PyDoc/CValue.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Documentation for CValue class -from PyObjectPlus import * -class CValue(PyObjectPlus): - """ - This class has no python functions - """ - pass diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index d16c00ca272..a0be06e8830 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -17,7 +17,7 @@ Documentation for the GameLogic Module. All the other modules are accessible through the methods in GameLogic. - See L{WhatsNew} for updates, changes and new functionality in the Game Engine Python API. + See U{release notes} for updates, changes and new functionality in the Game Engine Python API. Examples:: # To get the controller thats running this python script: @@ -38,18 +38,18 @@ Documentation for the GameLogic Module. sensors = co.getSensors() See the sensor's reference for available methods: - - L{DelaySensor} - - L{JoystickSensor} - - L{KeyboardSensor} - - L{MouseFocusSensor} - - L{MouseSensor} - - L{NearSensor} - - L{NetworkMessageSensor} - - L{PropertySensor} - - L{RadarSensor} - - L{RandomSensor} - - L{RaySensor} - - L{TouchSensor} + - L{DelaySensor} + - L{JoystickSensor} + - L{KeyboardSensor} + - L{MouseFocusSensor} + - L{MouseSensor} + - L{NearSensor} + - L{NetworkMessageSensor} + - L{PropertySensor} + - L{RadarSensor} + - L{RandomSensor} + - L{RaySensor} + - L{TouchSensor} You can also access actuators linked to the controller:: # To get an actuator attached to the controller: @@ -62,28 +62,28 @@ Documentation for the GameLogic Module. controller.activate(actuator) See the actuator's reference for available methods: - - L{2DFilterActuator} - - L{ActionActuator} - - L{AddObjectActuator} - - L{CameraActuator} - - L{CDActuator} - - L{ConstraintActuator} - - L{DynamicActuator} - - L{EndObjectActuator} - - L{GameActuator} - - L{IpoActuator} - - L{NetworkMessageActuator} - - L{ObjectActuator} - - L{ParentActuator} - - L{PropertyActuator} - - L{RandomActuator} - - L{ReplaceMeshActuator} - - L{SceneActuator} - - L{ShapeActionActuator} - - L{SoundActuator} - - L{StateActuator} - - L{TrackToActuator} - - L{VisibilityActuator} + - L{2DFilterActuator} + - L{ActionActuator} + - L{AddObjectActuator} + - L{CameraActuator} + - L{CDActuator} + - L{ConstraintActuator} + - L{DynamicActuator} + - L{EndObjectActuator} + - L{GameActuator} + - L{IpoActuator} + - L{NetworkMessageActuator} + - L{ObjectActuator} + - L{ParentActuator} + - L{PropertyActuator} + - L{RandomActuator} + - L{ReplaceMeshActuator} + - L{SceneActuator} + - L{ShapeActionActuator} + - L{SoundActuator} + - L{StateActuator} + - L{TrackToActuator} + - L{VisibilityActuator} Most logic brick's methods are accessors for the properties available in the logic buttons. Consult the logic bricks documentation for more information on how each logic brick works. diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 2b07a18247c..a22f63854ea 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -1,75 +1,5401 @@ -# $Id$ """ -GameEngine Types -================ -@var BL_ActionActuator: L{BL_ActionActuator} -@var BL_Shader: L{BL_Shader} -@var BL_ShapeActionActuator: L{BL_ShapeActionActuator} -@var CListValue: L{CListValue} -@var CValue: L{CValue} -@var KX_BlenderMaterial: L{KX_BlenderMaterial} -@var KX_CDActuator: L{KX_CDActuator} -@var KX_Camera: L{KX_Camera} -@var KX_CameraActuator: L{KX_CameraActuator} -@var KX_ConstraintActuator: L{KX_ConstraintActuator} -@var KX_ConstraintWrapper: L{KX_ConstraintWrapper} -@var KX_GameActuator: L{KX_GameActuator} -@var KX_GameObject: L{KX_GameObject} -@var KX_IpoActuator: L{KX_IpoActuator} -@var KX_LightObject: L{KX_LightObject} -@var KX_MeshProxy: L{KX_MeshProxy} -@var KX_MouseFocusSensor: L{KX_MouseFocusSensor} -@var KX_NearSensor: L{KX_NearSensor} -@var KX_NetworkMessageActuator: L{KX_NetworkMessageActuator} -@var KX_NetworkMessageSensor: L{KX_NetworkMessageSensor} -@var KX_ObjectActuator: L{KX_ObjectActuator} -@var KX_ParentActuator: L{KX_ParentActuator} -@var KX_PhysicsObjectWrapper: L{KX_PhysicsObjectWrapper} -@var KX_PolyProxy: L{KX_PolyProxy} -@var KX_PolygonMaterial: L{KX_PolygonMaterial} -@var KX_RadarSensor: L{KX_RadarSensor} -@var KX_RaySensor: L{KX_RaySensor} -@var KX_SCA_AddObjectActuator: L{KX_SCA_AddObjectActuator} -@var KX_SCA_DynamicActuator: L{KX_SCA_DynamicActuator} -@var KX_SCA_EndObjectActuator: L{KX_SCA_EndObjectActuator} -@var KX_SCA_ReplaceMeshActuator: L{KX_SCA_ReplaceMeshActuator} -@var KX_Scene: L{KX_Scene} -@var KX_SceneActuator: L{KX_SceneActuator} -@var KX_SoundActuator: L{KX_SoundActuator} -@var KX_StateActuator: L{KX_StateActuator} -@var KX_TouchSensor: L{KX_TouchSensor} -@var KX_TrackToActuator: L{KX_TrackToActuator} -@var KX_VehicleWrapper: L{KX_VehicleWrapper} -@var KX_VertexProxy: L{KX_VertexProxy} -@var KX_VisibilityActuator: L{KX_VisibilityActuator} -@var PyObjectPlus: L{PyObjectPlus} -@var SCA_2DFilterActuator: L{SCA_2DFilterActuator} -@var SCA_ANDController: L{SCA_ANDController} -@var SCA_ActuatorSensor: L{SCA_ActuatorSensor} -@var SCA_AlwaysSensor: L{SCA_AlwaysSensor} -@var SCA_DelaySensor: L{SCA_DelaySensor} -@var SCA_ILogicBrick: L{SCA_ILogicBrick} -@var SCA_IObject: L{SCA_IObject} -@var SCA_ISensor: L{SCA_ISensor} -@var SCA_JoystickSensor: L{SCA_JoystickSensor} -@var SCA_KeyboardSensor: L{SCA_KeyboardSensor} -@var SCA_MouseSensor: L{SCA_MouseSensor} -@var SCA_NANDController: L{SCA_NANDController} -@var SCA_NORController: L{SCA_NORController} -@var SCA_ORController: L{SCA_ORController} -@var SCA_PropertyActuator: L{SCA_PropertyActuator} -@var SCA_PropertySensor: L{SCA_PropertySensor} -@var SCA_PythonController: L{SCA_PythonController} -@var SCA_RandomActuator: L{SCA_RandomActuator} -@var SCA_RandomSensor: L{SCA_RandomSensor} -@var SCA_XNORController: L{SCA_XNORController} -@var SCA_XORController: L{SCA_XORController} +Documentation for the GameTypes Module. +======================================= + +@group Base: PyObjectPlus, CValue, CPropValue, SCA_ILogicBrick, SCA_IObject, SCA_ISensor, SCA_IController, SCA_IActuator + +@group Object: KX_GameObject, KX_LightObject, KX_Camera + +@group Mesh: KX_MeshProxy, KX_PolyProxy, KX_VertexProxy + +@group Shading: KX_PolygonMaterial, KX_BlenderMaterial, BL_Shader + +@group Sensors: SCA_ActuatorSensor, SCA_AlwaysSensor, SCA_DelaySensor, SCA_JoystickSensor, SCA_KeyboardSensor, KX_MouseFocusSensor, SCA_MouseSensor, KX_NearSensor, KX_NetworkMessageSensor, SCA_PropertySensor, KX_RadarSensor, SCA_RandomSensor, KX_RaySensor, KX_TouchSensor + +@group Actuators: SCA_2DFilterActuator, BL_ActionActuator, KX_SCA_AddObjectActuator, KX_CameraActuator, KX_CDActuator, KX_ConstraintActuator, KX_SCA_DynamicActuator, KX_SCA_EndObjectActuator, KX_GameActuator, KX_IpoActuator, KX_NetworkMessageActuator, KX_ObjectActuator, KX_ParentActuator, SCA_PropertyActuator, SCA_RandomActuator, KX_SCA_ReplaceMeshActuator, KX_SceneActuator, BL_ShapeActionActuator, KX_SoundActuator, KX_StateActuator, KX_TrackToActuator, KX_VisibilityActuator + +@group Controllers: SCA_ANDController, SCA_NANDController, SCA_NORController, SCA_ORController, SCA_PythonController, SCA_XNORController, SCA_XORController """ +import GameLogic -if 0: - # Use to print out all the links - for i in a.split('\n'): - if i.startswith('@var'): - var = i.split(' ')[1].split(':')[0] - print '@var %s: L{%s<%s.%s>}' % (var, var, var, var) +class PyObjectPlus: + """ + PyObjectPlus base class of most other types in the Game Engine. + + @ivar invalid: Test if the object has been freed by the game engine and is no longer valid. + + Normally this is not a problem but when storing game engine data in the GameLogic module, + KX_Scenes or other KX_GameObjects its possible to hold a reference to invalid data. + Calling an attribute or method on an invalid object will raise a SystemError. + + The invalid attribute allows testing for this case without exception handling. + @type invalid: bool + """ + + def isA(game_type): + """ + Check if this is a type or a subtype game_type. + @param game_type: the name of the type or the type its self from the L{GameTypes} module. + @type game_type: string or type + @return: True if this object is a type or a subtype of game_type. + @rtype: bool + """ + +class CValue(PyObjectPlus): + """ + This class has no python functions + """ + pass + +class CPropValue(CValue): + """ + This class has no python functions + """ + pass + +class SCA_ILogicBrick(CValue): + """ + Base class for all logic bricks. + + @ivar executePriority: This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first). + @type executePriority: int + @ivar owner: The game object this logic brick is attached to (read only). + @type owner: L{KX_GameObject} or None in exceptional cases. + @ivar name: The name of this logic brick (read only). + @type name: string + @group Deprecated: getOwner, setExecutePriority, getExecutePriority + """ + + def getOwner(): + """ + Gets the game object associated with this logic brick. + + Deprecated: Use the "owner" property instead. + + @rtype: L{KX_GameObject} + """ + + #--The following methods are deprecated-- + def setExecutePriority(priority): + """ + Sets the priority of this logic brick. + + This determines the order controllers are evaluated, and actuators are activated. + Bricks with lower priority will be executed first. + + Deprecated: Use the "executePriority" property instead. + + @type priority: integer + @param priority: the priority of this logic brick. + """ + def getExecutePriority(): + """ + Gets the execution priority of this logic brick. + + Deprecated: Use the "executePriority" property instead. + + @rtype: integer + @return: this logic bricks current priority. + """ + + +class SCA_IObject(CValue): + """ + This class has no python functions + """ + pass + +class SCA_ISensor(SCA_ILogicBrick): + """ + Base class for all sensor logic bricks. + + @ivar usePosPulseMode: Flag to turn positive pulse mode on and off. + @type usePosPulseMode: boolean + @ivar useNegPulseMode: Flag to turn negative pulse mode on and off. + @type useNegPulseMode: boolean + @ivar frequency: The frequency for pulse mode sensors. + @type frequency: int + @ivar level: Flag to set whether to detect level or edge transition when entering a state. + It makes a difference only in case of logic state transition (state actuator). + A level detector will immediately generate a pulse, negative or positive + depending on the sensor condition, as soon as the state is activated. + A edge detector will wait for a state change before generating a pulse. + @type level: boolean + @ivar invert: Flag to set if this sensor activates on positive or negative events. + @type invert: boolean + @ivar triggered: True if this sensor brick is in a positive state. (Read only) + @type triggered: boolean + @ivar positive: True if this sensor brick is in a positive state. (Read only) + @type positive: boolean + @group Deprecated: isPositive, isTriggered, getUsePosPulseMode, setUsePosPulseMode, getFrequency, setFrequency, getUseNegPulseMode, setUseNegPulseMode, getInvert, setInvert, getLevel, setLevel + """ + + def reset(): + """ + Reset sensor internal state, effect depends on the type of sensor and settings. + + The sensor is put in its initial state as if it was just activated. + """ + + #--The following methods are deprecated-- + def isPositive(): + """ + True if this sensor brick is in a positive state. + """ + + def isTriggered(): + """ + True if this sensor brick has triggered the current controller. + """ + + def getUsePosPulseMode(): + """ + True if the sensor is in positive pulse mode. + """ + def setUsePosPulseMode(pulse): + """ + Sets positive pulse mode. + + @type pulse: boolean + @param pulse: If True, will activate positive pulse mode for this sensor. + """ + def getFrequency(): + """ + The frequency for pulse mode sensors. + + @rtype: integer + @return: the pulse frequency in 1/50 sec. + """ + def setFrequency(freq): + """ + Sets the frequency for pulse mode sensors. + + @type freq: integer + @return: the pulse frequency in 1/50 sec. + """ + def getUseNegPulseMode(): + """ + True if the sensor is in negative pulse mode. + """ + def setUseNegPulseMode(pulse): + """ + Sets negative pulse mode. + + @type pulse: boolean + @param pulse: If True, will activate negative pulse mode for this sensor. + """ + def getInvert(): + """ + True if this sensor activates on negative events. + """ + def setInvert(invert): + """ + Sets if this sensor activates on positive or negative events. + + @type invert: boolean + @param invert: true if activates on negative events; false if activates on positive events. + """ + def getLevel(): + """ + Returns whether this sensor is a level detector or a edge detector. + It makes a difference only in case of logic state transition (state actuator). + A level detector will immediately generate a pulse, negative or positive + depending on the sensor condition, as soon as the state is activated. + A edge detector will wait for a state change before generating a pulse. + + @rtype: boolean + @return: true if sensor is level sensitive, false if it is edge sensitive + """ + def setLevel(level): + """ + Set whether to detect level or edge transition when entering a state. + + @param level: Detect level instead of edge? (KX_TRUE, KX_FALSE) + @type level: boolean + """ + +class SCA_IController(SCA_ILogicBrick): + """ + Base class for all controller logic bricks. + + @ivar state: the controllers state bitmask. + This can be used with the GameObject's state to test if the controller is active. + @type state: int bitmask + @ivar sensors: a list of sensors linked to this controller + - note: the sensors are not necessarily owned by the same object. + - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. + @type sensors: sequence supporting index/string lookups and iteration. + @ivar actuators: a list of actuators linked to this controller. + - note: the sensors are not necessarily owned by the same object. + - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. + @type actuators: sequence supporting index/string lookups and iteration. + + @group Deprecated: getState, getSensors, getActuators, getSensor, getActuator + """ + + def getState(): + """ + DEPRECATED: use the state property + Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. + This for instance will always be true however you could compare with a previous state to see when the state was activated. + GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState() + + @rtype: int + """ + def getSensors(): + """ + DEPRECATED: use the sensors property + Gets a list of all sensors attached to this controller. + + @rtype: list [L{SCA_ISensor}] + """ + def getSensor(name): + """ + DEPRECATED: use the sensors[name] property + Gets the named linked sensor. + + @type name: string + @rtype: L{SCA_ISensor} + """ + def getActuators(): + """ + DEPRECATED: use the actuators property + Gets a list of all actuators linked to this controller. + + @rtype: list [L{SCA_IActuator}] + """ + def getActuator(name): + """ + DEPRECATED: use the actuators[name] property + Gets the named linked actuator. + + @type name: string + @rtype: L{SCA_IActuator} + """ + +class SCA_IActuator(SCA_ILogicBrick): + """ + Base class for all actuator logic bricks. + """ + +class BL_ActionActuator(SCA_IActuator): + """ + Action Actuators apply an action to an actor. + + @ivar action: The name of the action to set as the current action. + @type action: string + @ivar start: Specifies the starting frame of the animation. + @type start: float + @ivar end: Specifies the ending frame of the animation. + @type end: float + @ivar blendin: Specifies the number of frames of animation to generate when making transitions between actions. + @type blendin: float + @ivar priority: Sets the priority of this actuator. Actuators will lower + priority numbers will override actuators with higher + numbers. + @type priority: integer + @ivar frame: Sets the current frame for the animation. + @type frame: float + @ivar property: Sets the property to be used in FromProp playback mode. + @type property: string + @ivar blendTime: Sets the internal frame timer. This property must be in + the range from 0.0 to blendin. + @type blendTime: float + @ivar type: The operation mode of the actuator. KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + @type type: integer + @ivar useContinue: The actions continue option, True or False. + When True, the action will always play from where last left off, + otherwise negative events to this actuator will reset it to its start frame. + @type: boolean + @ivar frameProperty: The name of the property that is set to the current frame number. + @type frameProperty: string + """ + def setChannel(channel, matrix, mode = False): + """ + @param channel: A string specifying the name of the bone channel. + @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 + """ + + #--The following methods are deprecated-- + def setAction(action, reset = True): + """ + DEPRECATED: use the 'action' property + Sets the current action. + + @param action: The name of the action to set as the current action. + @type action: string + @param reset: Optional parameter indicating whether to reset the + blend timer or not. A value of 1 indicates that the + timer should be reset. A value of 0 will leave it + unchanged. If reset is not specified, the timer will + be reset. + """ + + def setStart(start): + """ + DEPRECATED: use the 'start' property + Specifies the starting frame of the animation. + + @param start: the starting frame of the animation + @type start: float + """ + + def setEnd(end): + """ + DEPRECATED: use the 'end' property + Specifies the ending frame of the animation. + + @param end: the ending frame of the animation + @type end: float + """ + def setBlendin(blendin): + """ + DEPRECATED: use the 'blendin' property + Specifies the number of frames of animation to generate + when making transitions between actions. + + @param blendin: the number of frames in transition. + @type blendin: float + """ + + def setPriority(priority): + """ + DEPRECATED: use the 'priority' property + Sets the priority of this actuator. + + @param priority: Specifies the new priority. Actuators will lower + priority numbers will override actuators with higher + numbers. + @type priority: integer + """ + def setFrame(frame): + """ + DEPRECATED: use the 'frame' property + Sets the current frame for the animation. + + @param frame: Specifies the new current frame for the animation + @type frame: float + """ + + def setProperty(prop): + """ + DEPRECATED: use the 'property' property + Sets the property to be used in FromProp playback mode. + + @param prop: the name of the property to use. + @type prop: string. + """ + + def setBlendtime(blendtime): + """ + DEPRECATED: use the 'blendTime' property + Sets the internal frame timer. + + Allows the script to directly modify the internal timer + used when generating transitions between actions. + + @param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0. + @type blendtime: float + """ + + def setType(mode): + """ + DEPRECATED: use the 'type' property + Sets the operation mode of the actuator + + @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + @type mode: integer + """ + + def setContinue(cont): + """ + DEPRECATED: use the 'continue' property + Set the actions continue option True or False. see getContinue. + + @param cont: The continue option. + @type cont: bool + """ + + def getType(): + """ + DEPRECATED: use the 'type' property + Returns the operation mode of the actuator + + @rtype: integer + @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + """ + + def getContinue(): + """ + DEPRECATED: use the 'continue' property + When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. + + @rtype: bool + """ + + def getAction(): + """ + DEPRECATED: use the 'action' property + getAction() returns the name of the action associated with this actuator. + + @rtype: string + """ + + def getStart(): + """ + DEPRECATED: use the 'start' property + Returns the starting frame of the action. + + @rtype: float + """ + def getEnd(): + """ + DEPRECATED: use the 'end' property + Returns the last frame of the action. + + @rtype: float + """ + def getBlendin(): + """ + DEPRECATED: use the 'blendin' property + Returns the number of interpolation animation frames to be generated when this actuator is triggered. + + @rtype: float + """ + def getPriority(): + """ + DEPRECATED: use the 'priority' property + Returns the priority for this actuator. Actuators with lower Priority numbers will + override actuators with higher numbers. + + @rtype: integer + """ + def getFrame(): + """ + DEPRECATED: use the 'frame' property + Returns the current frame number. + + @rtype: float + """ + def getProperty(): + """ + DEPRECATED: use the 'property' property + Returns the name of the property to be used in FromProp mode. + + @rtype: string + """ + def setFrameProperty(prop): + """ + DEPRECATED: use the 'frameProperty' property + @param prop: A string specifying the property of the object that will be updated with the action frame number. + @type prop: string + """ + def getFrameProperty(): + """ + DEPRECATED: use the 'frameProperty' property + Returns the name of the property that is set to the current frame number. + + @rtype: string + """ + +class BL_Shader(PyObjectPlus): + """ + BL_Shader GLSL shaders. + + TODO - Description + """ + + def setUniformfv(name, fList): + """ + Set a uniform with a list of float values + + @param name: the uniform name + @type name: string + + @param fList: a list (2, 3 or 4 elements) of float values + @type fList: list[float] + """ + + def delSource(): + """ + TODO - Description + + """ + def getFragmentProg(): + """ + Returns the fragment program. + + @rtype: string + @return: The fragment program. + """ + def getVertexProg(): + """ + Get the vertex program. + + @rtype: string + @return: The vertex program. + """ + def isValid(): + """ + Check if the shader is valid. + + @rtype: bool + @return: True if the shader is valid + """ + def setAttrib(enum): + """ + Set attribute location. (The parameter is ignored a.t.m. and the value of "tangent" is always used.) + + @param enum: attribute location value + @type enum: integer + """ + def setNumberOfPasses( max_pass ): + """ + Set the maximum number of passes. Not used a.t.m. + + @param max_pass: the maximum number of passes + @type max_pass: integer + """ + def setSampler(name, index): + """ + Set uniform texture sample index. + + @param name: Uniform name + @type name: string + + @param index: Texture sample index. + @type index: integer + """ + def setSource(vertexProgram, fragmentProgram): + """ + Set the vertex and fragment programs + + @param vertexProgram: Vertex program + @type vertexProgram: string + + @param fragmentProgram: Fragment program + @type fragmentProgram: string + """ + def setUniform1f(name, fx): + """ + Set a uniform with 1 float value. + + @param name: the uniform name + @type name: string + + @param fx: Uniform value + @type fx: float + """ + def setUniform1i(name, ix): + """ + Set a uniform with an integer value. + + @param name: the uniform name + @type name: string + + @param ix: the uniform value + @type ix: integer + """ + def setUniform2f(name, fx, fy): + """ + Set a uniform with 2 float values + + @param name: the uniform name + @type name: string + + @param fx: first float value + @type fx: float + + @param fy: second float value + @type fy: float + """ + def setUniform2i(name, ix, iy): + """ + Set a uniform with 2 integer values + + @param name: the uniform name + @type name: string + + @param ix: first integer value + @type ix: integer + + @param iy: second integer value + @type iy: integer + """ + def setUniform3f(name, fx,fy,fz): + """ + Set a uniform with 3 float values. + + @param name: the uniform name + @type name: string + + @param fx: first float value + @type fx: float + + @param fy: second float value + @type fy: float + + @param fz: third float value + @type fz: float + """ + def setUniform3i(name, ix,iy,iz): + """ + Set a uniform with 3 integer values + + @param name: the uniform name + @type name: string + + @param ix: first integer value + @type ix: integer + + @param iy: second integer value + @type iy: integer + + @param iz: third integer value + @type iz: integer + """ + def setUniform4f(name, fx,fy,fz,fw): + """ + Set a uniform with 4 float values. + + @param name: the uniform name + @type name: string + + @param fx: first float value + @type fx: float + + @param fy: second float value + @type fy: float + + @param fz: third float value + @type fz: float + + @param fw: fourth float value + @type fw: float + """ + def setUniform4i(name, ix,iy,iz, iw): + """ + Set a uniform with 4 integer values + + @param name: the uniform name + @type name: string + + @param ix: first integer value + @type ix: integer + + @param iy: second integer value + @type iy: integer + + @param iz: third integer value + @type iz: integer + + @param iw: fourth integer value + @type iw: integer + """ + def setUniformDef(name, type): + """ + Define a new uniform + + @param name: the uniform name + @type name: string + + @param type: uniform type + @type type: UNI_NONE, UNI_INT, UNI_FLOAT, UNI_INT2, UNI_FLOAT2, UNI_INT3, UNI_FLOAT3, UNI_INT4, UNI_FLOAT4, UNI_MAT3, UNI_MAT4, UNI_MAX + """ + def setUniformMatrix3(name, mat, transpose): + """ + Set a uniform with a 3x3 matrix value + + @param name: the uniform name + @type name: string + + @param mat: A 3x3 matrix [[f,f,f], [f,f,f], [f,f,f]] + @type mat: 3x3 matrix + + @param transpose: set to True to transpose the matrix + @type transpose: bool + """ + def setUniformMatrix4(name, mat, transpose): + """ + Set a uniform with a 4x4 matrix value + + @param name: the uniform name + @type name: string + + @param mat: A 4x4 matrix [[f,f,f,f], [f,f,f,f], [f,f,f,f], [f,f,f,f]] + @type mat: 4x4 matrix + + @param transpose: set to True to transpose the matrix + @type transpose: bool + """ + def setUniformiv(name, iList): + """ + Set a uniform with a list of integer values + + @param name: the uniform name + @type name: string + + @param iList: a list (2, 3 or 4 elements) of integer values + @type iList: list[integer] + """ + def validate(): + """ + Validate the shader object. + + """ + +class BL_ShapeActionActuator(SCA_IActuator): + """ + ShapeAction Actuators apply an shape action to an mesh object.\ + + @ivar action: The name of the action to set as the current shape action. + @type action: string + @ivar start: Specifies the starting frame of the shape animation. + @type start: float + @ivar end: Specifies the ending frame of the shape animation. + @type end: float + @ivar blendin: Specifies the number of frames of animation to generate when making transitions between actions. + @type blendin: float + @ivar priority: Sets the priority of this actuator. Actuators will lower + priority numbers will override actuators with higher + numbers. + @type priority: integer + @ivar frame: Sets the current frame for the animation. + @type frame: float + @ivar property: Sets the property to be used in FromProp playback mode. + @type property: string + @ivar blendTime: Sets the internal frame timer. This property must be in + the range from 0.0 to blendin. + @type blendTime: float + @ivar type: The operation mode of the actuator. + KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, + KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + @type type: integer + @ivar frameProperty: The name of the property that is set to the current frame number. + @type frameProperty: string + + """ + def setAction(action, reset = True): + """ + DEPRECATED: use the 'action' property + Sets the current action. + + @param action: The name of the action to set as the current action. + @type action: string + @param reset: Optional parameter indicating whether to reset the + blend timer or not. A value of 1 indicates that the + timer should be reset. A value of 0 will leave it + unchanged. If reset is not specified, the timer will + be reset. + """ + + def setStart(start): + """ + DEPRECATED: use the 'start' property + Specifies the starting frame of the animation. + + @param start: the starting frame of the animation + @type start: float + """ + + def setEnd(end): + """ + DEPRECATED: use the 'end' property + Specifies the ending frame of the animation. + + @param end: the ending frame of the animation + @type end: float + """ + def setBlendin(blendin): + """ + DEPRECATED: use the 'blendin' property + Specifies the number of frames of animation to generate + when making transitions between actions. + + @param blendin: the number of frames in transition. + @type blendin: float + """ + + def setPriority(priority): + """ + DEPRECATED: use the 'priority' property + Sets the priority of this actuator. + + @param priority: Specifies the new priority. Actuators will lower + priority numbers will override actuators with higher + numbers. + @type priority: integer + """ + def setFrame(frame): + """ + DEPRECATED: use the 'frame' property + Sets the current frame for the animation. + + @param frame: Specifies the new current frame for the animation + @type frame: float + """ + + def setProperty(prop): + """ + DEPRECATED: use the 'property' property + Sets the property to be used in FromProp playback mode. + + @param prop: the name of the property to use. + @type prop: string. + """ + + def setBlendtime(blendtime): + """ + DEPRECATED: use the 'blendTime' property + Sets the internal frame timer. + + Allows the script to directly modify the internal timer + used when generating transitions between actions. + + @param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0. + @type blendtime: float + """ + + def setType(mode): + """ + DEPRECATED: use the 'type' property + Sets the operation mode of the actuator + + @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + @type mode: integer + """ + + def getType(): + """ + DEPRECATED: use the 'type' property + Returns the operation mode of the actuator + + @rtype: integer + @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + """ + + def getAction(): + """ + DEPRECATED: use the 'action' property + getAction() returns the name of the action associated with this actuator. + + @rtype: string + """ + + def getStart(): + """ + DEPRECATED: use the 'start' property + Returns the starting frame of the action. + + @rtype: float + """ + def getEnd(): + """ + DEPRECATED: use the 'end' property + Returns the last frame of the action. + + @rtype: float + """ + def getBlendin(): + """ + DEPRECATED: use the 'blendin' property + Returns the number of interpolation animation frames to be generated when this actuator is triggered. + + @rtype: float + """ + def getPriority(): + """ + DEPRECATED: use the 'priority' property + Returns the priority for this actuator. Actuators with lower Priority numbers will + override actuators with higher numbers. + + @rtype: integer + """ + def getFrame(): + """ + DEPRECATED: use the 'frame' property + Returns the current frame number. + + @rtype: float + """ + def getProperty(): + """ + DEPRECATED: use the 'property' property + Returns the name of the property to be used in FromProp mode. + + @rtype: string + """ + def setFrameProperty(prop): + """ + DEPRECATED: use the 'frameProperty' property + @param prop: A string specifying the property of the object that will be updated with the action frame number. + @type prop: string + """ + def getFrameProperty(): + """ + DEPRECATED: use the 'frameProperty' property + Returns the name of the property that is set to the current frame number. + + @rtype: string + """ + +class CListValue(CPropValue): + """ + CListValue + + This is a list like object used in the game engine internally that behaves similar to a python list in most ways. + + As well as the normal index lookup. + C{val= clist[i]} + + CListValue supports string lookups. + C{val= scene.objects["OBCube"]} + + Other operations such as C{len(clist), list(clist), clist[0:10]} are also supported. + """ + def append(val): + """ + Add an item to the list (like pythons append) + + Warning: Appending values to the list can cause crashes when the list is used internally by the game engine. + """ + + def count(val): + """ + Count the number of instances of a value in the list. + + @rtype: integer + @return: number of instances + """ + def index(val): + """ + Return the index of a value in the list. + + @rtype: integer + @return: The index of the value in the list. + """ + def reverse(): + """ + Reverse the order of the list. + """ + def from_id(id): + """ + This is a funtion especially for the game engine to return a value with a spesific id. + + Since object names are not always unique, the id of an object can be used to get an object from the CValueList. + + Example. + + C{myObID = id(gameObject)} + + C{...} + + C{ob= scene.objects.from_id(myObID)} + + Where myObID is an int or long from the id function. + + This has the advantage that you can store the id in places you could not store a gameObject. + + Warning: the id is derived from a memory location and will be different each time the game engine starts. + """# + +class KX_BlenderMaterial(PyObjectPlus): # , RAS_IPolyMaterial) + """ + KX_BlenderMaterial + + All placeholders have a __ prefix + """ + + def __getShader(val): + """ + TODO - Description + + @param val: the starting frame of the animation + @type val: float + + @rtype: integer + @return: TODO Description + """ + + def __setBlending(val): + """ + TODO - Description + + @param val: the starting frame of the animation + @type val: float + + @rtype: integer + @return: TODO Description + """ + def __getMaterialIndex(val): + """ + TODO - Description + + @param val: the starting frame of the animation + @type val: float + + @rtype: integer + @return: TODO Description + """ + +class KX_CDActuator(SCA_IActuator): + """ + CD Controller actuator. + @ivar volume: controls the volume to set the CD to. 0.0 = silent, 1.0 = max volume. + @type volume: float + @ivar track: the track selected to be played + @type track: integer + @ivar gain: the gain (volume) of the CD between 0.0 and 1.0. + @type gain: float + """ + def startCD(): + """ + Starts the CD playing. + """ + def stopCD(): + """ + Stops the CD playing. + """ + def pauseCD(): + """ + Pauses the CD. + """ + def resumeCD(): + """ + Resumes the CD after a pause. + """ + def playAll(): + """ + Plays the CD from the beginning. + """ + def playTrack(trackNumber): + """ + Plays the track selected. + """ + def setGain(gain): + """ + DEPRECATED: Use the volume property. + Sets the gain (volume) of the CD. + + @type gain: float + @param gain: the gain to set the CD to. 0.0 = silent, 1.0 = max volume. + """ + def getGain(): + """ + DEPRECATED: Use the volume property. + Gets the current gain (volume) of the CD. + + @rtype: float + @return: Between 0.0 (silent) and 1.0 (max volume) + """ + +class KX_CameraActuator(SCA_IActuator): + """ + Applies changes to a camera. + + @ivar min: minimum distance to the target object maintained by the actuator + @type min: float + @ivar max: maximum distance to stay from the target object + @type max: float + @ivar height: height to stay above the target object + @type height: float + @ivar xy: axis this actuator is tracking, true=X, false=Y + @type xy: boolean + @ivar object: the object this actuator tracks. + @type object: KX_GameObject or None + @author: snail + """ + def getObject(name_only = 1): + """ + Returns the name of the object this actuator tracks. + + @type name_only: bool + @param name_only: optional argument, when 0 return a KX_GameObject + @rtype: string, KX_GameObject or None if no object is set + """ + + def setObject(target): + """ + Sets the object this actuator tracks. + + @param target: the object to track. + @type target: L{KX_GameObject}, string or None + """ + + def getMin(): + """ + Returns the minimum distance to target maintained by the actuator. + + @rtype: float + """ + + def setMin(distance): + """ + Sets the minimum distance to the target object maintained by the + actuator. + + @param distance: The minimum distance to maintain. + @type distance: float + """ + + def getMax(): + """ + Gets the maximum distance to stay from the target object. + + @rtype: float + """ + + def setMax(distance): + """ + Sets the maximum distance to stay from the target object. + + @param distance: The maximum distance to maintain. + @type distance: float + """ + + def getHeight(): + """ + Returns the height to stay above the target object. + + @rtype: float + """ + + def setHeight(height): + """ + Sets the height to stay above the target object. + + @type height: float + @param height: The height to stay above the target object. + """ + + def setXY(xaxis): + """ + Sets the axis to get behind. + + @param xaxis: False to track Y axis, True to track X axis. + @type xaxis: boolean + """ + + def getXY(): + """ + Returns the axis this actuator is tracking. + + @return: True if tracking X axis, False if tracking Y axis. + @rtype: boolean + """ + +class KX_ConstraintActuator(SCA_IActuator): + """ + A constraint actuator limits the position, rotation, distance or orientation of an object. + + Properties: + + @ivar damp: time constant of the constraint expressed in frame (not use by Force field constraint) + @type damp: integer + + @ivar rotDamp: time constant for the rotation expressed in frame (only for the distance constraint) + 0 = use damp for rotation as well + @type rotDamp: integer + + @ivar direction: the reference direction in world coordinate for the orientation constraint + @type direction: 3-tuple of float: [x,y,z] + + @ivar option: Binary combination of the following values: + Applicable to Distance constraint: + - KX_ACT_CONSTRAINT_NORMAL ( 64) : Activate alignment to surface + - KX_ACT_CONSTRAINT_DISTANCE ( 512) : Activate distance control + - KX_ACT_CONSTRAINT_LOCAL (1024) : direction of the ray is along the local axis + Applicable to Force field constraint: + - KX_ACT_CONSTRAINT_DOROTFH (2048) : Force field act on rotation as well + Applicable to both: + - KX_ACT_CONSTRAINT_MATERIAL ( 128) : Detect material rather than property + - KX_ACT_CONSTRAINT_PERMANENT ( 256) : No deactivation if ray does not hit target + @type option: integer + + @ivar time: activation time of the actuator. The actuator disables itself after this many frame. + If set to 0, the actuator is not limited in time. + @type time: integer + + @ivar property: the name of the property or material for the ray detection of the distance constraint. + @type property: string + + @ivar min: The lower bound of the constraint + For the rotation and orientation constraint, it represents radiant + @type min: float + + @ivar distance: the target distance of the distance constraint + @type distance: float + + @ivar max: the upper bound of the constraint. + For rotation and orientation constraints, it represents radiant. + @type max: float + + @ivar rayLength: the length of the ray of the distance constraint. + @type rayLength: float + + @ivar limit: type of constraint, use one of the following constant: + KX_ACT_CONSTRAINT_LOCX ( 1) : limit X coord + KX_ACT_CONSTRAINT_LOCY ( 2) : limit Y coord + KX_ACT_CONSTRAINT_LOCZ ( 3) : limit Z coord + KX_ACT_CONSTRAINT_ROTX ( 4) : limit X rotation + KX_ACT_CONSTRAINT_ROTY ( 5) : limit Y rotation + KX_ACT_CONSTRAINT_ROTZ ( 6) : limit Z rotation + KX_ACT_CONSTRAINT_DIRPX ( 7) : set distance along positive X axis + KX_ACT_CONSTRAINT_DIRPY ( 8) : set distance along positive Y axis + KX_ACT_CONSTRAINT_DIRPZ ( 9) : set distance along positive Z axis + KX_ACT_CONSTRAINT_DIRNX (10) : set distance along negative X axis + KX_ACT_CONSTRAINT_DIRNY (11) : set distance along negative Y axis + KX_ACT_CONSTRAINT_DIRNZ (12) : set distance along negative Z axis + KX_ACT_CONSTRAINT_ORIX (13) : set orientation of X axis + KX_ACT_CONSTRAINT_ORIY (14) : set orientation of Y axis + KX_ACT_CONSTRAINT_ORIZ (15) : set orientation of Z axis + KX_ACT_CONSTRAINT_FHPX (16) : set force field along positive X axis + KX_ACT_CONSTRAINT_FHPY (17) : set force field along positive Y axis + KX_ACT_CONSTRAINT_FHPZ (18) : set force field along positive Z axis + KX_ACT_CONSTRAINT_FHNX (19) : set force field along negative X axis + KX_ACT_CONSTRAINT_FHNY (20) : set force field along negative Y axis + KX_ACT_CONSTRAINT_FHNZ (21) : set force field along negative Z axis + @type limit: integer + """ + def setDamp(time): + """ + Sets the time this constraint is delayed. + + @param time: The number of frames to delay. + Negative values are ignored. + @type time: integer + """ + def getDamp(): + """ + Returns the damping time of the constraint. + + @rtype: integer + """ + def setMin(lower): + """ + Sets the lower bound of the constraint. + + For rotational and orientation constraints, lower is specified in degrees. + + @type lower: float + """ + def getMin(): + """ + Gets the lower bound of the constraint. + + For rotational and orientation constraints, the lower bound is returned in radians. + + @rtype: float + """ + def setMax(upper): + """ + Sets the upper bound of the constraint. + + For rotational and orientation constraints, upper is specified in degrees. + + @type upper: float + """ + def getMax(): + """ + Gets the upper bound of the constraint. + + For rotational and orientation constraints, the upper bound is returned in radians. + + @rtype: float + """ + def setLimit(limit): + """ + Sets the type of constraint. + + See module L{GameLogic} for valid constraint types. + + @param limit: + Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ + Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY or KX_CONSTRAINTACT_ROTZ + Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ + Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ + """ + def getLimit(): + """ + Gets the type of constraint. + + See module L{GameLogic} for valid constraints. + + @return: + Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, + Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ, + Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ, + Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ + """ + def setRotDamp(duration): + """ + Sets the time constant of the orientation constraint. + + @param duration: If the duration is negative, it is set to 0. + @type duration: integer + """ + def getRotDamp(): + """ + Returns the damping time for application of the constraint. + + @rtype: integer + """ + def setDirection(vector): + """ + Sets the reference direction in world coordinate for the orientation constraint + + @type vector: 3-tuple + """ + def getDirection(): + """ + Returns the reference direction of the orientation constraint in world coordinate. + + @rtype: 3-tuple + """ + def setOption(option): + """ + Sets several options of the distance constraint. + + @type option: integer + @param option: Binary combination of the following values: + 64 : Activate alignment to surface + 128 : Detect material rather than property + 256 : No deactivation if ray does not hit target + 512 : Activate distance control + """ + def getOption(): + """ + Returns the option parameter. + + @rtype: integer + """ + def setTime(duration): + """ + Sets the activation time of the actuator. + + @type duration: integer + @param duration: The actuator disables itself after this many frame. + If set to 0 or negative, the actuator is not limited in time. + """ + def getTime(): + """ + Returns the time parameter. + + @rtype: integer + """ + def setProperty(property): + """ + Sets the name of the property or material for the ray detection of the distance constraint. + + @type property: string + @param property: If empty, the ray will detect any collisioning object. + """ + def getProperty(): + """ + Returns the property parameter. + + @rtype: string + """ + def setDistance(distance): + """ + Sets the target distance in distance constraint. + + @type distance: float + """ + def getDistance(): + """ + Returns the distance parameter. + + @rtype: float + """ + def setRayLength(length): + """ + Sets the maximum ray length of the distance constraint. + + @type length: float + """ + def getRayLength(): + """ + Returns the length of the ray + + @rtype: float + """ + +class KX_ConstraintWrapper(PyObjectPlus): + """ + KX_ConstraintWrapper + + All placeholders have a __ prefix + """ + def __getConstraintId(val): + """ + TODO - Description + + @param val: the starting frame of the animation + @type val: float + + @rtype: integer + @return: TODO Description + """ + + def __testMethod(val): + """ + TODO - Description + + @param val: the starting frame of the animation + @type val: float + + @rtype: integer + @return: TODO Description + """ + +class KX_GameActuator(SCA_IActuator): + """ + The game actuator loads a new .blend file, restarts the current .blend file or quits the game. + + Properties: + + @ivar file: the new .blend file to load + @type file: string. + @ivar mode: The mode of this actuator + @type mode: int from 0 to 5 L{GameLogic.Game Actuator} + """ + def getFile(): + """ + DEPRECATED: use the file property + Returns the filename of the new .blend file to load. + + @rtype: string + """ + def setFile(filename): + """ + DEPRECATED: use the file property + Sets the new .blend file to load. + + @param filename: The file name this actuator will load. + @type filename: string + """ + +class KX_GameObject(SCA_IObject): + """ + All game objects are derived from this class. + + Properties assigned to game objects are accessible as attributes of this class. + - note: Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the L{invalid} attribute to check. + + @ivar name: The object's name. (Read only) + - note: Currently (Blender 2.49) the prefix "OB" is added to all objects name. This may change in blender 2.5. + @type name: string. + @ivar mass: The object's mass + - note: The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0 + @type mass: float + @ivar linVelocityMin: Enforces the object keeps moving at a minimum velocity. + - note: Applies to dynamic and rigid body objects only. + - note: A value of 0.0 disables this option. + - note: While objects are stationary the minimum velocity will not be applied. + @type linVelocityMin: float + @ivar linVelocityMax: Clamp the maximum linear velocity to prevent objects moving beyond a set speed. + - note: Applies to dynamic and rigid body objects only. + - note: A value of 0.0 disables this option (rather then setting it stationary). + @type linVelocityMax: float + @ivar localInertia: the object's inertia vector in local coordinates. Read only. + @type localInertia: list [ix, iy, iz] + @ivar parent: The object's parent object. (Read only) + @type parent: L{KX_GameObject} or None + @ivar visible: visibility flag. + - note: Game logic will still run for invisible objects. + @type visible: boolean + @ivar occlusion: occlusion capability flag. + @type occlusion: boolean + @ivar position: The object's position. + DEPRECATED: use localPosition and worldPosition + @type position: list [x, y, z] On write: local position, on read: world position + @ivar orientation: The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. + DEPRECATED: use localOrientation and worldOrientation + @type orientation: 3x3 Matrix [[float]] On write: local orientation, on read: world orientation + @ivar scaling: The object's scaling factor. list [sx, sy, sz] + DEPRECATED: use localScaling and worldScaling + @type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling + @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. + @type localOrientation: 3x3 Matrix [[float]] + @ivar worldOrientation: The object's world orientation. + @type worldOrientation: 3x3 Matrix [[float]] + @ivar localScaling: The object's local scaling factor. + @type localScaling: list [sx, sy, sz] + @ivar worldScaling: The object's world scaling factor. Read-only + @type worldScaling: list [sx, sy, sz] + @ivar localPosition: The object's local position. + @type localPosition: list [x, y, z] + @ivar worldPosition: The object's world position. + @type worldPosition: list [x, y, z] + @ivar timeOffset: adjust the slowparent delay at runtime. + @type timeOffset: float + @ivar state: the game object's state bitmask, using the first 30 bits, one bit must always be set. + @type state: int + @ivar meshes: a list meshes for this object. + - note: Most objects use only 1 mesh. + - note: Changes to this list will not update the KX_GameObject. + @type meshes: list of L{KX_MeshProxy} + @ivar sensors: a sequence of L{SCA_ISensor} objects with string/index lookups and iterator support. + - note: This attribute is experemental and may be removed (but probably wont be). + - note: Changes to this list will not update the KX_GameObject. + @type sensors: list + @ivar controllers: a sequence of L{SCA_IController} objects with string/index lookups and iterator support. + - note: This attribute is experemental and may be removed (but probably wont be). + - note: Changes to this list will not update the KX_GameObject. + @type controllers: list of L{SCA_ISensor}. + @ivar actuators: a list of L{SCA_IActuator} with string/index lookups and iterator support. + - note: This attribute is experemental and may be removed (but probably wont be). + - note: Changes to this list will not update the KX_GameObject. + @type actuators: list + @ivar attrDict: get the objects internal python attribute dictionary for direct (faster) access. + @type attrDict: dict + @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh + """ + def endObject(): + """ + Delete this object, can be used inpace of the EndObject Actuator. + The actual removal of the object from the scene is delayed. + """ + def replaceMesh(mesh): + """ + Replace the mesh of this object with a new mesh. This works the same was as the actuator. + @type mesh: L{KX_MeshProxy} or mesh name + """ + def getVisible(): + """ + Gets the game object's visible flag. (B{deprecated}) + + @rtype: boolean + """ + def setVisible(visible, recursive): + """ + Sets the game object's visible flag. + + @type visible: boolean + @type recursive: boolean + @param recursive: optional argument to set all childrens visibility flag too. + """ + def setOcclusion(occlusion, recursive): + """ + Sets the game object's occlusion capability. + + @type occlusion: boolean + @type recursive: boolean + @param recursive: optional argument to set all childrens occlusion flag too. + """ + def getState(): + """ + Gets the game object's state bitmask. (B{deprecated}) + + @rtype: int + @return: the objects state. + """ + def setState(state): + """ + Sets the game object's state flag. (B{deprecated}). + The bitmasks for states from 1 to 30 can be set with (1<<0, 1<<1, 1<<2 ... 1<<29) + + @type state: integer + """ + def setPosition(pos): + """ + Sets the game object's position. (B{deprecated}) + Global coordinates for root object, local for child objects. + + + @type pos: [x, y, z] + @param pos: the new position, in local coordinates. + """ + def setWorldPosition(pos): + """ + Sets the game object's position in world coordinates regardless if the object is root or child. + + @type pos: [x, y, z] + @param pos: the new position, in world coordinates. + """ + def getPosition(): + """ + Gets the game object's position. (B{deprecated}) + + @rtype: list [x, y, z] + @return: the object's position in world coordinates. + """ + def setOrientation(orn): + """ + Sets the game object's orientation. (B{deprecated}) + + @type orn: 3x3 rotation matrix, or Quaternion. + @param orn: a rotation matrix specifying the new rotation. + @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. + """ + def alignAxisToVect(vect, axis, factor): + """ + Aligns any of the game object's axis along the given vector. + + @type vect: 3d vector. + @param vect: a vector to align the axis. + @type axis: integer. + @param axis:The axis you want to align + - 0: X axis + - 1: Y axis + - 2: Z axis (default) + @type factor: float + @param factor: Only rotate a feaction of the distance to the target vector (0.0 - 1.0) + """ + def getAxisVect(vect): + """ + Returns the axis vector rotates by the objects worldspace orientation. + This is the equivalent if multiplying the vector by the orientation matrix. + + @type vect: 3d vector. + @param vect: a vector to align the axis. + @rtype: 3d vector. + @return: The vector in relation to the objects rotation. + + """ + def getOrientation(): + """ + Gets the game object's orientation. (B{deprecated}) + + @rtype: 3x3 rotation matrix + @return: The game object's rotation matrix + @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. + """ + def applyMovement(movement, local = 0): + """ + Sets the game object's movement. + + @type movement: 3d vector. + @param movement: movement vector. + @type local: boolean + @param local: - False: you get the "global" movement ie: relative to world orientation (default). + - True: you get the "local" movement ie: relative to object orientation. + """ + def applyRotation(rotation, local = 0): + """ + Sets the game object's rotation. + + @type rotation: 3d vector. + @param rotation: rotation vector. + @type local: boolean + @param local: - False: you get the "global" rotation ie: relative to world orientation (default). + - True: you get the "local" rotation ie: relative to object orientation. + """ + def applyForce(force, local = 0): + """ + Sets the game object's force. + + This requires a dynamic object. + + @type force: 3d vector. + @param force: force vector. + @type local: boolean + @param local: - False: you get the "global" force ie: relative to world orientation (default). + - True: you get the "local" force ie: relative to object orientation. + """ + def applyTorque(torque, local = 0): + """ + Sets the game object's torque. + + This requires a dynamic object. + + @type torque: 3d vector. + @param torque: torque vector. + @type local: boolean + @param local: - False: you get the "global" torque ie: relative to world orientation (default). + - True: you get the "local" torque ie: relative to object orientation. + """ + def getLinearVelocity(local = 0): + """ + Gets the game object's linear velocity. + + This method returns the game object's velocity through it's centre of mass, + ie no angular velocity component. + + @type local: boolean + @param local: - False: you get the "global" velocity ie: relative to world orientation (default). + - True: you get the "local" velocity ie: relative to object orientation. + @rtype: list [vx, vy, vz] + @return: the object's linear velocity. + """ + def setLinearVelocity(velocity, local = 0): + """ + Sets the game object's linear velocity. + + This method sets game object's velocity through it's centre of mass, + ie no angular velocity component. + + This requires a dynamic object. + + @type velocity: 3d vector. + @param velocity: linear velocity vector. + @type local: boolean + @param local: - False: you get the "global" velocity ie: relative to world orientation (default). + - True: you get the "local" velocity ie: relative to object orientation. + """ + def getAngularVelocity(local = 0): + """ + Gets the game object's angular velocity. + + @type local: boolean + @param local: - False: you get the "global" velocity ie: relative to world orientation (default). + - True: you get the "local" velocity ie: relative to object orientation. + @rtype: list [vx, vy, vz] + @return: the object's angular velocity. + """ + def setAngularVelocity(velocity, local = 0): + """ + Sets the game object's angular velocity. + + This requires a dynamic object. + + @type velocity: 3d vector. + @param velocity: angular velocity vector. + @type local: boolean + @param local: - False: you get the "global" velocity ie: relative to world orientation (default). + - True: you get the "local" velocity ie: relative to object orientation. + """ + def getVelocity(point): + """ + Gets the game object's velocity at the specified point. + + Gets the game object's velocity at the specified point, including angular + components. + + @type point: list [x, y, z] + @param point: the point to return the velocity for, in local coordinates. (optional: default = [0, 0, 0]) + @rtype: list [vx, vy, vz] + @return: the velocity at the specified point. + """ + def getMass(): + """ + Gets the game object's mass. (B{deprecated}) + + @rtype: float + @return: the object's mass. + """ + def getReactionForce(): + """ + Gets the game object's reaction force. + + The reaction force is the force applied to this object over the last simulation timestep. + This also includes impulses, eg from collisions. + + (B{This is not implimented for bullet physics at the moment}) + + @rtype: list [fx, fy, fz] + @return: the reaction force of this object. + """ + def applyImpulse(point, impulse): + """ + Applies an impulse to the game object. + + This will apply the specified impulse to the game object at the specified point. + If point != getPosition(), applyImpulse will also change the object's angular momentum. + Otherwise, only linear momentum will change. + + @type point: list [x, y, z] + @param point: the point to apply the impulse to (in world coordinates) + """ + def suspendDynamics(): + """ + Suspends physics for this object. + """ + def restoreDynamics(): + """ + Resumes physics for this object. + @Note: The objects linear velocity will be applied from when the dynamics were suspended. + """ + def enableRigidBody(): + """ + Enables rigid body physics for this object. + + Rigid body physics allows the object to roll on collisions. + @Note: This is not working with bullet physics yet. + """ + def disableRigidBody(): + """ + Disables rigid body physics for this object. + @Note: This is not working with bullet physics yet. The angular is removed but rigid body physics can still rotate it later. + """ + def getParent(): + """ + Gets this object's parent. (B{deprecated}) + + @rtype: L{KX_GameObject} + @return: this object's parent object, or None if this object has no parent. + """ + def setParent(parent): + """ + Sets this object's parent. + + @type parent: L{KX_GameObject} + @param parent: new parent object. + """ + def removeParent(): + """ + Removes this objects parent. + """ + def getChildren(): + """ + Return a list of immediate children of this object. + @rtype: L{CListValue} of L{KX_GameObject} + @return: a list of all this objects children. + """ + def getChildrenRecursive(): + """ + Return a list of children of this object, including all their childrens children. + @rtype: L{CListValue} of L{KX_GameObject} + @return: a list of all this objects children recursivly. + """ + def getMesh(mesh): + """ + Gets the mesh object for this object. + + @type mesh: integer + @param mesh: the mesh object to return (optional: default mesh = 0) + @rtype: L{KX_MeshProxy} + @return: the first mesh object associated with this game object, or None if this object has no meshs. + """ + def getPhysicsId(): + """ + Returns the user data object associated with this game object's physics controller. + """ + def getPropertyNames(): + """ + Gets a list of all property names. + @rtype: list + @return: All property names for this object. + """ + def getDistanceTo(other): + """ + Returns the distance to another object or point. + + @param other: a point or another L{KX_GameObject} to measure the distance to. + @type other: L{KX_GameObject} or list [x, y, z] + @rtype: float + """ + def getVectTo(other): + """ + Returns the vector and the distance to another object or point. + The vector is normalized unless the distance is 0, in which a NULL vector is returned. + + @param other: a point or another L{KX_GameObject} to get the vector and distance to. + @type other: L{KX_GameObject} or list [x, y, z] + @rtype: 3-tuple (float, 3-tuple (x,y,z), 3-tuple (x,y,z)) + @return: (distance, globalVector(3), localVector(3)) + """ + def rayCastTo(other,dist,prop): + """ + Look towards another point/object and find first object hit within dist that matches prop. + + The ray is always casted from the center of the object, ignoring the object itself. + The ray is casted towards the center of another object or an explicit [x,y,z] point. + Use rayCast() if you need to retrieve the hit point + + @param other: [x,y,z] or object towards which the ray is casted + @type other: L{KX_GameObject} or 3-tuple + @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other + @type dist: float + @param prop: property name that object must have; can be omitted => detect any object + @type prop: string + @rtype: L{KX_GameObject} + @return: the first object hit or None if no object or object does not match prop + """ + def rayCast(objto,objfrom,dist,prop,face,xray,poly): + """ + Look from a point/object to another point/object and find first object hit within dist that matches prop. + if poly is 0, returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no hit. + if poly is 1, returns a 4-tuple with in addition a L{KX_PolyProxy} as 4th element. + + Ex:: + # shoot along the axis gun-gunAim (gunAim should be collision-free) + ob,point,normal = gun.rayCast(gunAim,None,50) + if ob: + # hit something + + Notes: + The ray ignores the object on which the method is called. + It is casted from/to object center or explicit [x,y,z] points. + + The face paremeter determines the orientation of the normal:: + 0 => hit normal is always oriented towards the ray origin (as if you casted the ray from outside) + 1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect) + + The ray has X-Ray capability if xray parameter is 1, otherwise the first object hit (other than self object) stops the ray. + The prop and xray parameters interact as follow:: + prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray. + prop off, xray on : idem. + prop on, xray off: return closest hit if it matches prop, no hit otherwise. + prop on, xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray. + The L{KX_PolyProxy} 4th element of the return tuple when poly=1 allows to retrieve information on the polygon hit by the ray. + If there is no hit or the hit object is not a static mesh, None is returned as 4th element. + + The ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects. + + @param objto: [x,y,z] or object to which the ray is casted + @type objto: L{KX_GameObject} or 3-tuple + @param objfrom: [x,y,z] or object from which the ray is casted; None or omitted => use self object center + @type objfrom: L{KX_GameObject} or 3-tuple or None + @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to + @type dist: float + @param prop: property name that object must have; can be omitted or "" => detect any object + @type prop: string + @param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin + @type face: int + @param xray: X-ray option: 1=>skip objects that don't match prop; 0 or omitted => stop on first object + @type xray: int + @param poly: polygon option: 1=>return value is a 4-tuple and the 4th element is a L{KX_PolyProxy} + @type poly: int + @rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz)) + or 4-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz), L{KX_PolyProxy}) + @return: (object,hitpoint,hitnormal) or (object,hitpoint,hitnormal,polygon) + If no hit, returns (None,None,None) or (None,None,None,None) + If the object hit is not a static mesh, polygon is None + """ + def setCollisionMargin(margin): + """ + Set the objects collision margin. + + note: If this object has no physics controller (a physics ID of zero), this function will raise RuntimeError. + + @type margin: float + @param margin: the collision margin distance in blender units. + """ + def sendMessage(subject, body="", to=""): + """ + Sends a message. + + @param subject: The subject of the message + @type subject: string + @param body: The body of the message (optional) + @type body: string + @param to: The name of the object to send the message to (optional) + @type to: string + """ + +class KX_IpoActuator(SCA_IActuator): + """ + IPO actuator activates an animation. + + @ivar startFrame: Start frame. + @type startFrame: float + @ivar endFrame: End frame. + @type endFrame: float + @ivar propName: Use this property to define the Ipo position + @type propName: string + @ivar framePropName: Assign this property this action current frame number + @type framePropName: string + @ivar type: Play mode for the ipo. (In GameLogic.KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND, KX_IPOACT_FROM_PROP) + @type type: int + @ivar useIpoAsForce: Apply Ipo as a global or local force depending on the local option (dynamic objects only) + @type useIpoAsForce: bool + @ivar useIpoAdd: Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag + @type useIpoAdd: bool + @ivar useIpoLocal: Let the ipo acts in local coordinates, used in Force and Add mode. + @type useIpoLocal: bool + @ivar useChildren: Update IPO on all children Objects as well + @type useChildren: bool + """ + def set(mode, startframe, endframe, force): + """ + Sets the properties of the actuator. (B{deprecated}) + + @param mode: "Play", "PingPong", "Flipper", "LoopStop", "LoopEnd" or "FromProp" + @type mode: string + @param startframe: first frame to use + @type startframe: integer + @param endframe: last frame to use + @type endframe: integer + @param force: special mode + @type force: integer (0=normal, 1=interpret location as force, 2=additive) + """ + def setProperty(property): + """ + Sets the name of the property to be used in FromProp mode. (B{deprecated}) + + @type property: string + """ + def setStart(startframe): + """ + Sets the frame from which the IPO starts playing. (B{deprecated}) + + @type startframe: integer + """ + def getStart(): + """ + Returns the frame from which the IPO starts playing. (B{deprecated}) + + @rtype: integer + """ + def setEnd(endframe): + """ + Sets the frame at which the IPO stops playing. (B{deprecated}) + + @type endframe: integer + """ + def getEnd(): + """ + Returns the frame at which the IPO stops playing. (B{deprecated}) + + @rtype: integer + """ + def setIpoAsForce(force): + """ + Set whether to interpret the ipo as a force rather than a displacement. (B{deprecated}) + + @type force: boolean + @param force: KX_TRUE or KX_FALSE + """ + def getIpoAsForce(): + """ + Returns whether to interpret the ipo as a force rather than a displacement. (B{deprecated}) + + @rtype: boolean + """ + def setIpoAdd(add): + """ + Set whether to interpret the ipo as additive rather than absolute. (B{deprecated}) + + @type add: boolean + @param add: KX_TRUE or KX_FALSE + """ + def getIpoAdd(): + """ + Returns whether to interpret the ipo as additive rather than absolute. (B{deprecated}) + + @rtype: boolean + """ + def setType(mode): + """ + Sets the operation mode of the actuator. (B{deprecated}) + + @param mode: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND + @type mode: string + """ + def getType(): + """ + Returns the operation mode of the actuator. (B{deprecated}) + + @rtype: integer + @return: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND + """ + def setForceIpoActsLocal(local): + """ + Set whether to apply the force in the object's local + coordinates rather than the world global coordinates. (B{deprecated}) + + @param local: Apply the ipo-as-force in the object's local + coordinates? (KX_TRUE, KX_FALSE) + @type local: boolean + """ + def getForceIpoActsLocal(): + """ + Return whether to apply the force in the object's local + coordinates rather than the world global coordinates. (B{deprecated}) + """ + +class KX_LightObject(KX_GameObject): + """ + A Light object. + + Example: + + # Turn on a red alert light. + import GameLogic + + co = GameLogic.getCurrentController() + light = co.getOwner() + + light.energy = 1.0 + light.colour = [1.0, 0.0, 0.0] + + @group Constants: NORMAL, SPOT, SUN + @ivar SPOT: A spot light source. See attribute 'type' + @ivar SUN: A point light source with no attenuation. See attribute 'type' + @ivar NORMAL: A point light source. See attribute 'type' + + @ivar type: The type of light - must be SPOT, SUN or NORMAL + @ivar layer: The layer mask that this light affects object on. + @type layer: bitfield + @ivar energy: The brightness of this light. + @type energy: float + @ivar distance: The maximum distance this light can illuminate. (SPOT and NORMAL lights only) + @type distance: float + @ivar colour: The colour of this light. Black = [0.0, 0.0, 0.0], White = [1.0, 1.0, 1.0] + @type colour: list [r, g, b] + @ivar color: Synonym for colour. + @ivar lin_attenuation: The linear component of this light's attenuation. (SPOT and NORMAL lights only) + @type lin_attenuation: float + @ivar quad_attenuation: The quadratic component of this light's attenuation (SPOT and NORMAL lights only) + @type quad_attenuation: float + @ivar spotsize: The cone angle of the spot light, in degrees. (float) (SPOT lights only) + 0.0 <= spotsize <= 180.0. Spotsize = 360.0 is also accepted. + @ivar spotblend: Specifies the intensity distribution of the spot light. (float) (SPOT lights only) + Higher values result in a more focused light source. + 0.0 <= spotblend <= 1.0. + + """ + +class KX_MeshProxy(SCA_IObject): + """ + A mesh object. + + You can only change the vertex properties of a mesh object, not the mesh topology. + + To use mesh objects effectively, you should know a bit about how the game engine handles them. + 1. Mesh Objects are converted from Blender at scene load. + 2. The Converter groups polygons by Material. This means they can be sent to the + renderer efficiently. A material holds: + 1. The texture. + 2. The Blender material. + 3. The Tile properties + 4. The face properties - (From the "Texture Face" panel) + 5. Transparency & z sorting + 6. Light layer + 7. Polygon shape (triangle/quad) + 8. Game Object + 3. Verticies will be split by face if necessary. Verticies can only be shared between + faces if: + 1. They are at the same position + 2. UV coordinates are the same + 3. Their normals are the same (both polygons are "Set Smooth") + 4. They are the same colour + For example: a cube has 24 verticies: 6 faces with 4 verticies per face. + + The correct method of iterating over every L{KX_VertexProxy} in a game object:: + import GameLogic + + co = GameLogic.getcurrentController() + obj = co.getOwner() + + m_i = 0 + mesh = obj.getMesh(m_i) # There can be more than one mesh... + while mesh != None: + for mat in range(mesh.getNumMaterials()): + for v_index in range(mesh.getVertexArrayLength(mat)): + vertex = mesh.getVertex(mat, v_index) + # Do something with vertex here... + # ... eg: colour the vertex red. + vertex.colour = [1.0, 0.0, 0.0, 1.0] + m_i += 1 + mesh = obj.getMesh(m_i) + + @ivar materials: + @type materials: list of L{KX_BlenderMaterial} or L{KX_PolygonMaterial} types + + @ivar numPolygons: + @type numPolygons: integer + + @ivar numMaterials: + @type numMaterials: integer + """ + + def getNumMaterials(): + """ + Gets the number of materials associated with this object. + + @rtype: integer + """ + + def getMaterialName(matid): + """ + Gets the name of the specified material. + + @type matid: integer + @param matid: the specified material. + @rtype: string + @return: the attached material name. + """ + def getTextureName(matid): + """ + Gets the name of the specified material's texture. + + @type matid: integer + @param matid: the specified material + @rtype: string + @return: the attached material's texture name. + """ + def getVertexArrayLength(matid): + """ + Gets the length of the vertex array associated with the specified material. + + There is one vertex array for each material. + + @type matid: integer + @param matid: the specified material + @rtype: integer + @return: the number of verticies in the vertex array. + """ + def getVertex(matid, index): + """ + Gets the specified vertex from the mesh object. + + @type matid: integer + @param matid: the specified material + @type index: integer + @param index: the index into the vertex array. + @rtype: L{KX_VertexProxy} + @return: a vertex object. + """ + def getNumPolygons(): + """ + Returns the number of polygon in the mesh. + + @rtype: integer + """ + def getPolygon(index): + """ + Gets the specified polygon from the mesh. + + @type index: integer + @param index: polygon number + @rtype: L{KX_PolyProxy} + @return: a polygon object. + """ + def reinstancePhysicsMesh(): + """ + Updates the physics system with the changed mesh. + + A mesh must have only one material with collision flags, + and have all collision primitives in one vertex array (ie. < 65535 verts) and + be either a polytope or polyheder mesh. If you don't get a warning in the + console when the collision type is polytope, the mesh is suitable for reinstance. + + @rtype: boolean + @return: True if reinstance succeeded, False if it failed. + """ + +class SCA_MouseSensor(SCA_ISensor): + """ + Mouse Sensor logic brick. + + Properties: + + @ivar position: current [x,y] coordinates of the mouse, in frame coordinates (pixels) + @type position: [integer,interger] + @ivar mode: sensor mode: 1=KX_MOUSESENSORMODE_LEFTBUTTON 2=KX_MOUSESENSORMODE_MIDDLEBUTTON + 3=KX_MOUSESENSORMODE_RIGHTBUTTON 4=KX_MOUSESENSORMODE_WHEELUP + 5=KX_MOUSESENSORMODE_WHEELDOWN 9=KX_MOUSESENSORMODE_MOVEMENT + @type mode: integer + """ + + def getXPosition(): + """ + DEPRECATED: use the position property + Gets the x coordinate of the mouse. + + @rtype: integer + @return: the current x coordinate of the mouse, in frame coordinates (pixels) + """ + def getYPosition(): + """ + DEPRECATED: use the position property + Gets the y coordinate of the mouse. + + @rtype: integer + @return: the current y coordinate of the mouse, in frame coordinates (pixels). + """ + def getButtonStatus(button): + """ + Get the mouse button status. + + @type button: int + @param button: value in GameLogic members KX_MOUSE_BUT_LEFT, KX_MOUSE_BUT_MIDDLE, KX_MOUSE_BUT_RIGHT + + @rtype: integer + @return: value in GameLogic members KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED + """ + +class KX_MouseFocusSensor(SCA_MouseSensor): + """ + The mouse focus sensor detects when the mouse is over the current game object. + + The mouse focus sensor works by transforming the mouse coordinates from 2d device + space to 3d space then raycasting away from the camera. + + @ivar raySource: The worldspace source of the ray (the view position) + @type raySource: list (vector of 3 floats) + @ivar rayTarget: The worldspace target of the ray. + @type rayTarget: list (vector of 3 floats) + @ivar rayDirection: The L{rayTarget} - L{raySource} normalized. + @type rayDirection: list (normalized vector of 3 floats) + @ivar hitObject: the last object the mouse was over. + @type hitObject: L{KX_GameObject} or None + @ivar hitPosition: The worldspace position of the ray intersecton. + @type hitPosition: list (vector of 3 floats) + @ivar hitNormal: the worldspace normal from the face at point of intersection. + @type hitNormal: list (normalized vector of 3 floats) + """ + + def getHitNormal(): + """ + Returns the normal (in worldcoordinates) at the point of collision where the object was hit by this ray. (B{deprecated}) + + @rtype: list [x, y, z] + @return: the ray collision normal. + """ + def getHitObject(): + """ + Returns the object that was hit by this ray or None. (B{deprecated}) + + @rtype: L{KX_GameObject} or None + @return: the collision object. + """ + def getHitPosition(): + """ + Returns the position (in worldcoordinates) at the point of collision where the object was hit by this ray. (B{deprecated}) + + @rtype: list [x, y, z] + @return: the ray collision position. + """ + def getRayDirection(): + """ + Returns the normalized direction (in worldcoordinates) of the ray cast by the mouse. (B{deprecated}) + + @rtype: list [x, y, z] + @return: the ray direction. + """ + def getRaySource(): + """ + Returns the position (in worldcoordinates) the ray was cast from by the mouse. (B{deprecated}) + + @rtype: list [x, y, z] + @return: the ray source. + """ + def getRayTarget(): + """ + Returns the target of the ray (in worldcoordinates) that seeks the focus object. (B{deprecated}) + + @rtype: list [x, y, z] + @return: the ray target. + """ + +class KX_TouchSensor(SCA_ISensor): + """ + Touch sensor detects collisions between objects. + + @ivar property: The property or material to collide with. + @type property: string + @ivar useMaterial: Determines if the sensor is looking for a property or material. + KX_True = Find material; KX_False = Find property + @type useMaterial: boolean + @ivar pulseCollisions: The last collided object. + @type pulseCollisions: bool + @ivar objectHit: The last collided object. (Read Only) + @type objectHit: L{KX_GameObject} or None + @ivar objectHitList: A list of colliding objects. (Read Only) + @type objectHitList: L{CListValue} of L{KX_GameObject} + """ + + #--The following methods are deprecated, please use properties instead. + def setProperty(name): + """ + DEPRECATED: use the property property + Set the property or material to collide with. Use + setTouchMaterial() to switch between properties and + materials. + @type name: string + """ + + def getProperty(): + """ + DEPRECATED: use the property property + Returns the property or material to collide with. Use + getTouchMaterial() to find out whether this sensor + looks for properties or materials. (B{deprecated}) + + @rtype: string + """ + def getHitObject(): + """ + DEPRECATED: use the objectHit property + Returns the last object hit by this touch sensor. (B{deprecated}) + + @rtype: L{KX_GameObject} + """ + def getHitObjectList(): + """ + DEPRECATED: use the objectHitList property + Returns a list of all objects hit in the last frame. (B{deprecated}) + + Only objects that have the requisite material/property are listed. + + @rtype: L{CListValue} of L{KX_GameObject} + """ + def getTouchMaterial(): + """ + DEPRECATED: use the useMaterial property + Returns KX_TRUE if this sensor looks for a specific material, + KX_FALSE if it looks for a specific property. (B{deprecated}) + """ + +class KX_NearSensor(KX_TouchSensor): + """ + A near sensor is a specialised form of touch sensor. + + @ivar distance: The near sensor activates when an object is within this distance. + @type distance: float + @ivar resetDistance: The near sensor deactivates when the object exceeds this distance. + @type resetDistance: float + """ + +class KX_NetworkMessageActuator(SCA_IActuator): + """ + Message Actuator + + @ivar propName: Messages will only be sent to objects with the given property name. + @type propName: string + @ivar subject: The subject field of the message. + @type subject: string + @ivar body: The body of the message. + @type body: string + @ivar usePropBody: Send a property instead of a regular body message. + @type usePropBody: boolean + """ + def setToPropName(name): + """ + DEPRECATED: Use the propName property instead. + Messages will only be sent to objects with the given property name. + + @type name: string + """ + def setSubject(subject): + """ + DEPRECATED: Use the subject property instead. + Sets the subject field of the message. + + @type subject: string + """ + def setBodyType(bodytype): + """ + DEPRECATED: Use the usePropBody property instead. + Sets the type of body to send. + + @type bodytype: boolean + @param bodytype: True to send the value of a property, False to send the body text. + """ + def setBody(body): + """ + DEPRECATED: Use the body property instead. + Sets the message body. + + @type body: string + @param body: if the body type is True, this is the name of the property to send. + if the body type is False, this is the text to send. + """ + +class KX_NetworkMessageSensor(SCA_ISensor): + """ + The Message Sensor logic brick. + + Currently only loopback (local) networks are supported. + + @ivar subject: The subject the sensor is looking for. + @type subject: string + @ivar frameMessageCount: The number of messages received since the last frame. + (Read-only) + @type framemessageCount: int + @ivar subjects: The list of message subjects received. (Read-only) + @type subjects: list of strings + @ivar bodies: The list of message bodies received. (Read-only) + @type bodies: list of strings + """ + + + def setSubjectFilterText(subject): + """ + DEPRECATED: Use the subject property instead. + Change the message subject text that this sensor is listening to. + + @type subject: string + @param subject: the new message subject to listen for. + """ + + def getFrameMessageCount(): + """ + DEPRECATED: Use the frameMessageCount property instead. + Get the number of messages received since the last frame. + + @rtype: integer + """ + def getBodies(): + """ + DEPRECATED: Use the bodies property instead. + Gets the list of message bodies. + + @rtype: list + """ + def getSubject(): + """ + DEPRECATED: Use the subject property instead. + Gets the message subject this sensor is listening for from the Subject: field. + + @rtype: string + """ + def getSubjects(): + """ + DEPRECATED: Use the subjects property instead. + Gets the list of message subjects received. + + @rtype: list + """ + +class KX_ObjectActuator(SCA_IActuator): + """ + The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement, + velocity, or angular velocity to an object. + Servo control allows to regulate force to achieve a certain speed target. + """ + def getForce(): + """ + Returns the force applied by the actuator. + + @rtype: list [fx, fy, fz, local] + @return: A four item list, containing the vector force, and a flag specifying whether the force is local. + """ + def setForce(fx, fy, fz, local): + """ + Sets the force applied by the actuator. + + @type fx: float + @param fx: the x component of the force. + @type fy: float + @param fy: the z component of the force. + @type fz: float + @param fz: the z component of the force. + @type local: boolean + @param local: - False: the force is applied in world coordinates. + - True: the force is applied in local coordinates. + """ + def getTorque(): + """ + Returns the torque applied by the actuator. + + @rtype: list [S{Tau}x, S{Tau}y, S{Tau}z, local] + @return: A four item list, containing the vector torque, and a flag specifying whether + the torque is applied in local coordinates (True) or world coordinates (False) + """ + def setTorque(tx, ty, tz, local): + """ + Sets the torque applied by the actuator. + + @type tx: float + @param tx: the x component of the torque. + @type ty: float + @param ty: the z component of the torque. + @type tz: float + @param tz: the z component of the torque. + @type local: boolean + @param local: - False: the torque is applied in world coordinates. + - True: the torque is applied in local coordinates. + """ + def getDLoc(): + """ + Returns the displacement vector applied by the actuator. + + @rtype: list [dx, dy, dz, local] + @return: A four item list, containing the vector displacement, and whether + the displacement is applied in local coordinates (True) or world + coordinates (False) + """ + def setDLoc(dx, dy, dz, local): + """ + Sets the displacement vector applied by the actuator. + + Since the displacement is applied every frame, you must adjust the displacement + based on the frame rate, or you game experience will depend on the player's computer + speed. + + @type dx: float + @param dx: the x component of the displacement vector. + @type dy: float + @param dy: the z component of the displacement vector. + @type dz: float + @param dz: the z component of the displacement vector. + @type local: boolean + @param local: - False: the displacement vector is applied in world coordinates. + - True: the displacement vector is applied in local coordinates. + """ + def getDRot(): + """ + Returns the angular displacement vector applied by the actuator. + + @rtype: list [dx, dy, dz, local] + @return: A four item list, containing the angular displacement vector, and whether + the displacement is applied in local coordinates (True) or world + coordinates (False) + """ + def setDRot(dx, dy, dz, local): + """ + Sets the angular displacement vector applied by the actuator. + + Since the displacement is applied every frame, you must adjust the displacement + based on the frame rate, or you game experience will depend on the player's computer + speed. + + @type dx: float + @param dx: the x component of the angular displacement vector. + @type dy: float + @param dy: the z component of the angular displacement vector. + @type dz: float + @param dz: the z component of the angular displacement vector. + @type local: boolean + @param local: - False: the angular displacement vector is applied in world coordinates. + - True: the angular displacement vector is applied in local coordinates. + """ + def getLinearVelocity(): + """ + Returns the linear velocity applied by the actuator. + For the servo control actuator, this is the target speed. + + @rtype: list [vx, vy, vz, local] + @return: A four item list, containing the vector velocity, and whether the velocity is applied in local coordinates (True) or world coordinates (False) + """ + def setLinearVelocity(vx, vy, vz, local): + """ + Sets the linear velocity applied by the actuator. + For the servo control actuator, sets the target speed. + + @type vx: float + @param vx: the x component of the velocity vector. + @type vy: float + @param vy: the z component of the velocity vector. + @type vz: float + @param vz: the z component of the velocity vector. + @type local: boolean + @param local: - False: the velocity vector is in world coordinates. + - True: the velocity vector is in local coordinates. + """ + def getAngularVelocity(): + """ + Returns the angular velocity applied by the actuator. + + @rtype: list [S{omega}x, S{omega}y, S{omega}z, local] + @return: A four item list, containing the vector velocity, and whether + the velocity is applied in local coordinates (True) or world + coordinates (False) + """ + def setAngularVelocity(wx, wy, wz, local): + """ + Sets the angular velocity applied by the actuator. + + @type wx: float + @param wx: the x component of the velocity vector. + @type wy: float + @param wy: the z component of the velocity vector. + @type wz: float + @param wz: the z component of the velocity vector. + @type local: boolean + @param local: - False: the velocity vector is applied in world coordinates. + - True: the velocity vector is applied in local coordinates. + """ + def getDamping(): + """ + Returns the damping parameter of the servo controller. + + @rtype: integer + @return: the time constant of the servo controller in frame unit. + """ + def setDamping(damp): + """ + Sets the damping parameter of the servo controller. + + @type damp: integer + @param damp: the damping parameter in frame unit. + """ + def getForceLimitX(): + """ + Returns the min/max force limit along the X axis used by the servo controller. + + @rtype: list [min, max, enabled] + @return: A three item list, containing the min and max limits of the force as float + and whether the limits are active(true) or inactive(true) + """ + def setForceLimitX(min, max, enable): + """ + Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller. + + @type min: float + @param min: the minimum value of the force along the X axis. + @type max: float + @param max: the maximum value of the force along the X axis. + @type enable: boolean + @param enable: - True: the force will be limited to the min/max + - False: the force will not be limited + """ + def getForceLimitY(): + """ + Returns the min/max force limit along the Y axis used by the servo controller. + + @rtype: list [min, max, enabled] + @return: A three item list, containing the min and max limits of the force as float + and whether the limits are active(true) or inactive(true) + """ + def setForceLimitY(min, max, enable): + """ + Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller. + + @type min: float + @param min: the minimum value of the force along the Y axis. + @type max: float + @param max: the maximum value of the force along the Y axis. + @type enable: boolean + @param enable: - True: the force will be limited to the min/max + - False: the force will not be limited + """ + def getForceLimitZ(): + """ + Returns the min/max force limit along the Z axis used by the servo controller. + + @rtype: list [min, max, enabled] + @return: A three item list, containing the min and max limits of the force as float + and whether the limits are active(true) or inactive(true) + """ + def setForceLimitZ(min, max, enable): + """ + Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller. + + @type min: float + @param min: the minimum value of the force along the Z axis. + @type max: float + @param max: the maximum value of the force along the Z axis. + @type enable: boolean + @param enable: - True: the force will be limited to the min/max + - False: the force will not be limited + """ + def getPID(): + """ + Returns the PID coefficient of the servo controller. + + @rtype: list [P, I, D] + @return: A three item list, containing the PID coefficient as floats: + P : proportional coefficient + I : Integral coefficient + D : Derivate coefficient + """ + def setPID(P, I, D): + """ + Sets the PID coefficients of the servo controller. + + @type P: flat + @param P: proportional coefficient + @type I: float + @param I: Integral coefficient + @type D: float + @param D: Derivate coefficient + """ + +class KX_ParentActuator(SCA_IActuator): + """ + The parent actuator can set or remove an objects parent object. + @ivar object: the object this actuator sets the parent too. + @type object: KX_GameObject or None + @ivar mode: The mode of this actuator + @type mode: int from 0 to 1 L{GameLogic.Parent Actuator} + """ + def setObject(object): + """ + DEPRECATED: Use the object property. + Sets the object to set as parent. + + Object can be either a L{KX_GameObject} or the name of the object. + + @type object: L{KX_GameObject}, string or None + """ + def getObject(name_only = 1): + """ + DEPRECATED: Use the object property. + Returns the name of the object to change to. + @type name_only: bool + @param name_only: optional argument, when 0 return a KX_GameObject + @rtype: string, KX_GameObject or None if no object is set + """ + +class KX_PhysicsObjectWrapper(PyObjectPlus): + """ + KX_PhysicsObjectWrapper + + """ + def setActive(active): + """ + Set the object to be active. + + @param active: set to True to be active + @type active: bool + """ + + def setAngularVelocity(x, y, z, local): + """ + Set the angular velocity of the object. + + @param x: angular velocity for the x-axis + @type x: float + + @param y: angular velocity for the y-axis + @type y: float + + @param z: angular velocity for the z-axis + @type z: float + + @param local: set to True for local axis + @type local: bool + """ + def setLinearVelocity(x, y, z, local): + """ + Set the linear velocity of the object. + + @param x: linear velocity for the x-axis + @type x: float + + @param y: linear velocity for the y-axis + @type y: float + + @param z: linear velocity for the z-axis + @type z: float + + @param local: set to True for local axis + @type local: bool + """ + def setPosition(x, y, z): + """ + Set the position of the object + + @param x: x coordinate + @type x: float + + @param y: y coordinate + @type y: float + + @param z: z coordinate + @type z: float + """ + +class KX_PolyProxy(SCA_IObject): + """ + A polygon holds the index of the vertex forming the poylgon. + + Note: + The polygon attributes are read-only, you need to retrieve the vertex proxy if you want + to change the vertex settings. + + @ivar matname: The name of polygon material, empty if no material. + @type matname: string + @ivar material: The material of the polygon + @type material: L{KX_PolygonMaterial} or KX_BlenderMaterial + @ivar texture: The texture name of the polygon. + @type texture: string + @ivar matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy + @type matid: integer + @ivar v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy + @type v1: integer + @ivar v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy + @type v2: integer + @ivar v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy + @type v3: integer + @ivar v4: vertex index of the fourth vertex of the polygon, 0 if polygon has only 3 vertex + use this to retrieve vertex proxy from mesh proxy + @type v4: integer + @ivar visible: visible state of the polygon: 1=visible, 0=invisible + @type visible: integer + @ivar collide: collide state of the polygon: 1=receives collision, 0=collision free. + @type collide: integer + """ + + def getMaterialName(): + """ + Returns the polygon material name with MA prefix + + @rtype: string + @return: material name + """ + def getMaterial(): + """ + Returns the polygon material + + @rtype: L{KX_PolygonMaterial} or KX_BlenderMaterial + """ + def getTextureName(): + """ + Returns the polygon texture name + + @rtype: string + @return: texture name + """ + def getMaterialIndex(): + """ + Returns the material bucket index of the polygon. + This index and the ones returned by getVertexIndex() are needed to retrieve the vertex proxy from L{KX_MeshProxy}. + + @rtype: integer + @return: the material index in the mesh + """ + def getNumVertex(): + """ + Returns the number of vertex of the polygon. + + @rtype: integer + @return: number of vertex, 3 or 4. + """ + def isVisible(): + """ + Returns whether the polygon is visible or not + + @rtype: integer + @return: 0=invisible, 1=visible + """ + def isCollider(): + """ + Returns whether the polygon is receives collision or not + + @rtype: integer + @return: 0=collision free, 1=receives collision + """ + def getVertexIndex(vertex): + """ + Returns the mesh vertex index of a polygon vertex + This index and the one returned by getMaterialIndex() are needed to retrieve the vertex proxy from L{KX_MeshProxy}. + + @type vertex: integer + @param vertex: index of the vertex in the polygon: 0->3 + @rtype: integer + @return: mesh vertex index + """ + def getMesh(): + """ + Returns a mesh proxy + + @rtype: L{KX_MeshProxy} + @return: mesh proxy + """ + +class KX_PolygonMaterial: + """ + This is the interface to materials in the game engine. + + Materials define the render state to be applied to mesh objects. + + Warning: Some of the methods/variables are CObjects. If you mix these up, + you will crash blender. + + This example requires: + - PyOpenGL http://pyopengl.sourceforge.net/ + - GLEWPy http://glewpy.sourceforge.net/ + Example:: + + import GameLogic + import OpenGL + from OpenGL.GL import * + from OpenGL.GLU import * + import glew + from glew import * + + glewInit() + + vertex_shader = \"\"\" + + void main(void) + { + gl_Position = ftransform(); + } + \"\"\" + + fragment_shader =\"\"\" + + void main(void) + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + \"\"\" + + class MyMaterial: + def __init__(self): + self.pass_no = 0 + # Create a shader + self.m_program = glCreateProgramObjectARB() + # Compile the vertex shader + self.shader(GL_VERTEX_SHADER_ARB, (vertex_shader)) + # Compile the fragment shader + self.shader(GL_FRAGMENT_SHADER_ARB, (fragment_shader)) + # Link the shaders together + self.link() + + def PrintInfoLog(self, tag, object): + \"\"\" + PrintInfoLog prints the GLSL compiler log + \"\"\" + print "Tag: def PrintGLError(self, tag = ""): + + def PrintGLError(self, tag = ""): + \"\"\" + Prints the current GL error status + \"\"\" + if len(tag): + print tag + err = glGetError() + if err != GL_NO_ERROR: + print "GL Error: %s\\n"%(gluErrorString(err)) + + def shader(self, type, shaders): + \"\"\" + shader compiles a GLSL shader and attaches it to the current + program. + + type should be either GL_VERTEX_SHADER_ARB or GL_FRAGMENT_SHADER_ARB + shaders should be a sequence of shader source to compile. + \"\"\" + # Create a shader object + shader_object = glCreateShaderObjectARB(type) + + # Add the source code + glShaderSourceARB(shader_object, len(shaders), shaders) + + # Compile the shader + glCompileShaderARB(shader_object) + + # Print the compiler log + self.PrintInfoLog("vertex shader", shader_object) + + # Check if compiled, and attach if it did + compiled = glGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB) + if compiled: + glAttachObjectARB(self.m_program, shader_object) + + # Delete the object (glAttachObjectARB makes a copy) + glDeleteObjectARB(shader_object) + + # print the gl error log + self.PrintGLError() + + def link(self): + \"\"\" + Links the shaders together. + \"\"\" + # clear error indicator + glGetError() + + glLinkProgramARB(self.m_program) + + self.PrintInfoLog("link", self.m_program) + + linked = glGetObjectParameterivARB(self.m_program, GL_OBJECT_LINK_STATUS_ARB) + if not linked: + print "Shader failed to link" + return + + glValidateProgramARB(self.m_program) + valid = glGetObjectParameterivARB(self.m_program, GL_OBJECT_VALIDATE_STATUS_ARB) + if not valid: + print "Shader failed to validate" + return + + def activate(self, rasty, cachingInfo, mat): + self.pass_no+=1 + if (self.pass_no == 1): + glDisable(GL_COLOR_MATERIAL) + glUseProgramObjectARB(self.m_program) + return True + + glEnable(GL_COLOR_MATERIAL) + glUseProgramObjectARB(0) + self.pass_no = 0 + return False + + obj = GameLogic.getCurrentController().getOwner() + + mesh = obj.getMesh(0) + + for mat in mesh.materials: + mat.setCustomMaterial(MyMaterial()) + print mat.texture + + @ivar texture: Texture name + @type texture: string (read only) + + @ivar gl_texture: OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture) + @type gl_texture: integer (read only) + + @ivar material: Material name + @type material: string (read only) + + @ivar tface: Texture face properties + @type tface: CObject (read only) + + @ivar tile: Texture is tiling + @type tile: boolean + @ivar tilexrep: Number of tile repetitions in x direction. + @type tilexrep: integer + @ivar tileyrep: Number of tile repetitions in y direction. + @type tileyrep: integer + + @ivar drawingmode: Drawing mode for the material. + - 2 (drawingmode & 4) Textured + - 4 (drawingmode & 16) Light + - 14 (drawingmode & 16384) 3d Polygon Text + @type drawingmode: bitfield + + @ivar transparent: This material is transparent. All meshes with this + material will be rendered after non transparent meshes from back + to front. + @type transparent: boolean + + @ivar zsort: Transparent polygons in meshes with this material will be sorted back to + front before rendering. + Non-Transparent polygons will be sorted front to back before rendering. + @type zsort: boolean + + @ivar lightlayer: Light layers this material affects. + @type lightlayer: bitfield. + + @ivar triangle: Mesh data with this material is triangles. It's probably not safe to change this. + @type triangle: boolean + + @ivar diffuse: The diffuse colour of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0] + @type diffuse: list [r, g, b] + @ivar specular: The specular colour of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0] + @type specular: list [r, g, b] + @ivar shininess: The shininess (specular exponent) of the material. 0.0 <= shininess <= 128.0 + @type shininess: float + @ivar specularity: The amount of specular of the material. 0.0 <= specularity <= 1.0 + @type specularity: float + """ + def updateTexture(tface, rasty): + """ + Updates a realtime animation. + + @param tface: Texture face (eg mat.tface) + @type tface: CObject + @param rasty: Rasterizer + @type rasty: CObject + """ + def setTexture(tface): + """ + Sets texture render state. + + Example:: + mat.setTexture(mat.tface) + + @param tface: Texture face + @type tface: CObject + """ + def activate(rasty, cachingInfo): + """ + Sets material parameters for this object for rendering. + + Material Parameters set: + 1. Texture + 2. Backface culling + 3. Line drawing + 4. Specular Colour + 5. Shininess + 6. Diffuse Colour + 7. Polygon Offset. + + @param rasty: Rasterizer instance. + @type rasty: CObject + @param cachingInfo: Material cache instance. + @type cachingInfo: CObject + """ + def setCustomMaterial(material): + """ + Sets the material state setup object. + + Using this method, you can extend or completely replace the gameengine material + to do your own advanced multipass effects. + + Use this method to register your material class. Instead of the normal material, + your class's activate method will be called just before rendering the mesh. + This should setup the texture, material, and any other state you would like. + It should return True to render the mesh, or False if you are finished. You should + clean up any state Blender does not set before returning False. + + Activate Method Definition:: + def activate(self, rasty, cachingInfo, material): + + Example:: + class PyMaterial: + def __init__(self): + self.pass_no = -1 + + def activate(self, rasty, cachingInfo, material): + # Activate the material here. + # + # The activate method will be called until it returns False. + # Every time the activate method returns True the mesh will + # be rendered. + # + # rasty is a CObject for passing to material.updateTexture() + # and material.activate() + # cachingInfo is a CObject for passing to material.activate() + # material is the KX_PolygonMaterial instance this material + # was added to + + # default material properties: + self.pass_no += 1 + if self.pass_no == 0: + material.activate(rasty, cachingInfo) + # Return True to do this pass + return True + + # clean up and return False to finish. + self.pass_no = -1 + return False + + # Create a new Python Material and pass it to the renderer. + mat.setCustomMaterial(PyMaterial()) + + @param material: The material object. + @type material: instance + """ + +class KX_RadarSensor(KX_NearSensor): + """ + Radar sensor is a near sensor with a conical sensor object. + + @ivar coneOrigin: The origin of the cone with which to test. The origin + is in the middle of the cone. + (Read only) + @type coneOrigin: list of floats [x, y, z] + @ivar coneTarget: The center of the bottom face of the cone with which to test. + (Read only) + @type coneTarget: list of floats [x, y, z] + @ivar distance: The height of the cone with which to test. + @type distance: float + @ivar angle: The angle of the cone (in degrees) with which to test. + @type angle: float from 0 to 360 + @ivar axis: The axis on which the radar cone is cast + @type axis: int from 0 to 5 + KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, + KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z + """ + + + #--The following methods are deprecated, please use properties instead. + def getConeOrigin(): + """ + Returns the origin of the cone with which to test. The origin + is in the middle of the cone. + + @rtype: list [x, y, z] + """ + + def getConeTarget(): + """ + Returns the center of the bottom face of the cone with which to test. + + @rtype: list [x, y, z] + """ + + def getConeHeight(): + """ + Returns the height of the cone with which to test. + + @rtype: float + """ + +class KX_RaySensor(SCA_ISensor): + """ + A ray sensor detects the first object in a given direction. + + @ivar property: The property the ray is looking for. + @type property: string + @ivar range: The distance of the ray. + @type range: float + @ivar useMaterial: Whether or not to look for a material (false = property) + @type useMaterial: boolean + @ivar useXRay: Whether or not to use XRay. + @type useXRay: boolean + @ivar hitObject: The game object that was hit by the ray. (Read-only) + @type hitObject: KX_GameObject + @ivar hitPosition: The position (in worldcoordinates) where the object was hit by the ray. (Read-only) + @type hitPosition: list [x, y, z] + @ivar hitNormal: The normal (in worldcoordinates) of the object at the location where the object was hit by the ray. (Read-only) + @type hitNormal: list [x, y, z] + @ivar rayDirection: The direction from the ray (in worldcoordinates). (Read-only) + @type rayDirection: list [x, y, z] + @ivar axis: The axis the ray is pointing on. + @type axis: int from 0 to 5 + KX_RAY_AXIS_POS_X, KX_RAY_AXIS_POS_Y, KX_RAY_AXIS_POS_Z, + KX_RAY_AXIS_NEG_X, KX_RAY_AXIS_NEG_Y, KX_RAY_AXIS_NEG_Z + """ + + def getHitObject(): + """ + DEPRECATED: Use the hitObject property instead. + Returns the game object that was hit by this ray. + + @rtype: KX_GameObject + """ + def getHitPosition(): + """ + DEPRECATED: Use the hitPosition property instead. + Returns the position (in worldcoordinates) where the object was hit by this ray. + + @rtype: list [x, y, z] + """ + def getHitNormal(): + """ + DEPRECATED: Use the hitNormal property instead. + Returns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray. + + @rtype: list [nx, ny, nz] + """ + def getRayDirection(): + """ + DEPRECATED: Use the rayDirection property instead. + Returns the direction from the ray (in worldcoordinates) + + @rtype: list [dx, dy, dz] + """ + +class KX_SCA_AddObjectActuator(SCA_IActuator): + """ + Edit Object Actuator (in Add Object Mode) + @ivar object: the object this actuator adds. + @type object: KX_GameObject or None + @ivar objectLastCreated: the last added object from this actuator (read only). + @type objectLastCreated: KX_GameObject or None + @ivar time: the lifetime of added objects, in frames. + @type time: integer + @ivar linearVelocity: the initial linear velocity of added objects. + @type linearVelocity: list [vx, vy, vz] + @ivar angularVelocity: the initial angular velocity of added objects. + @type angularVelocity: list [vx, vy, vz] + + @warning: An Add Object actuator will be ignored if at game start, the linked object doesn't exist + (or is empty) or the linked object is in an active layer. + + This will genereate a warning in the console: + + C{ERROR: GameObject I{OBName} has a AddObjectActuator I{ActuatorName} without object (in 'nonactive' layer)} + """ + def setObject(object): + """ + DEPRECATED: use the object property + Sets the game object to add. + + A copy of the object will be added to the scene when the actuator is activated. + + If the object does not exist, this function is ignored. + + object can either be a L{KX_GameObject} or the name of an object or None. + + @type object: L{KX_GameObject}, string or None + """ + def getObject(name_only = 0): + """ + DEPRECATED: use the object property + Returns the name of the game object to be added. + + Returns None if no game object has been assigned to be added. + @type name_only: bool + @param name_only: optional argument, when 0 return a KX_GameObject + @rtype: string, KX_GameObject or None if no object is set + """ + def setTime(time): + """ + DEPRECATED: use the time property + Sets the lifetime of added objects, in frames. + + If time == 0, the object will last forever. + + @type time: integer + @param time: The minimum value for time is 0. + """ + def getTime(): + """ + DEPRECATED: use the time property + Returns the lifetime of the added object, in frames. + + @rtype: integer + """ + def setLinearVelocity(vx, vy, vz): + """ + DEPRECATED: use the linearVelocity property + Sets the initial linear velocity of added objects. + + @type vx: float + @param vx: the x component of the initial linear velocity. + @type vy: float + @param vy: the y component of the initial linear velocity. + @type vz: float + @param vz: the z component of the initial linear velocity. + """ + def getLinearVelocity(): + """ + DEPRECATED: use the linearVelocity property + Returns the initial linear velocity of added objects. + + @rtype: list [vx, vy, vz] + """ + def setAngularVelocity(vx, vy, vz): + """ + DEPRECATED: use the angularVelocity property + Sets the initial angular velocity of added objects. + + @type vx: float + @param vx: the x component of the initial angular velocity. + @type vy: float + @param vy: the y component of the initial angular velocity. + @type vz: float + @param vz: the z component of the initial angular velocity. + """ + def getAngularVelocity(): + """ + DEPRECATED: use the angularVelocity property + Returns the initial angular velocity of added objects. + + @rtype: list [vx, vy, vz] + """ + def getLastCreatedObject(): + """ + DEPRECATED: use the objectLastCreated property + Returns the last object created by this actuator. + + @rtype: L{KX_GameObject} + @return: A L{KX_GameObject} or None if no object has been created. + """ + def instantAddObject(): + """ + Returns the last object created by this actuator. The object can then be accessed from L{objectLastCreated}. + + @rtype: None + """ + +class KX_SCA_DynamicActuator(SCA_IActuator): + """ + Dynamic Actuator. + @ivar operation: the type of operation of the actuator, 0-4 + KX_DYN_RESTORE_DYNAMICS, KX_DYN_DISABLE_DYNAMICS, + KX_DYN_ENABLE_RIGID_BODY, KX_DYN_DISABLE_RIGID_BODY, KX_DYN_SET_MASS + @type operation: integer + @ivar mass: the mass value for the KX_DYN_SET_MASS operation + @type mass: float + """ + def setOperation(operation): + """ + DEPRECATED: Use the operation property instead. + Set the type of operation when the actuator is activated: + - 0 = restore dynamics + - 1 = disable dynamics + - 2 = enable rigid body + - 3 = disable rigid body + - 4 = set mass + """ + def getOperation(): + """ + DEPRECATED: Use the operation property instead. + return the type of operation + """ + +class KX_SCA_EndObjectActuator(SCA_IActuator): + """ + Edit Object Actuator (in End Object mode) + + This actuator has no python methods. + """ + +class KX_SCA_ReplaceMeshActuator(SCA_IActuator): + """ + Edit Object actuator, in Replace Mesh mode. + + Example:: + # Level-of-detail + # Switch a game object's mesh based on its depth in the camera view. + # +----------+ +-----------+ +-------------------------------------+ + # | Always +-----+ Python +-----+ Edit Object (Replace Mesh) LOD.Mesh | + # +----------+ +-----------+ +-------------------------------------+ + import GameLogic + + # List detail meshes here + # Mesh (name, near, far) + # Meshes overlap so that they don't 'pop' when on the edge of the distance. + meshes = ((".Hi", 0.0, -20.0), + (".Med", -15.0, -50.0), + (".Lo", -40.0, -100.0) + ) + + co = GameLogic.getCurrentController() + obj = co.getOwner() + act = co.getActuator("LOD." + obj.name) + cam = GameLogic.getCurrentScene().active_camera + + def Depth(pos, plane): + return pos[0]*plane[0] + pos[1]*plane[1] + pos[2]*plane[2] + plane[3] + + # Depth is negative and decreasing further from the camera + depth = Depth(obj.position, cam.world_to_camera[2]) + + newmesh = None + curmesh = None + # Find the lowest detail mesh for depth + for mesh in meshes: + if depth < mesh[1] and depth > mesh[2]: + newmesh = mesh + if "ME" + obj.name + mesh[0] == act.getMesh(): + curmesh = mesh + + if newmesh != None and "ME" + obj.name + newmesh[0] != act.getMesh(): + # The mesh is a different mesh - switch it. + # Check the current mesh is not a better fit. + if curmesh == None or curmesh[1] < depth or curmesh[2] > depth: + act.setMesh(obj.getName() + newmesh[0]) + GameLogic.addActiveActuator(act, True) + + @warning: Replace mesh actuators will be ignored if at game start, the + named mesh doesn't exist. + + This will generate a warning in the console: + + C{ERROR: GameObject I{OBName} ReplaceMeshActuator I{ActuatorName} without object} + + @ivar mesh: L{KX_MeshProxy} or the name of the mesh that will replace the current one + Set to None to disable actuator + @type mesh: L{KX_MeshProxy} or None if no mesh is set + """ + def setMesh(name): + """ + DEPRECATED: Use the mesh property instead. + Sets the name of the mesh that will replace the current one. + When the name is None it will unset the mesh value so no action is taken. + + @type name: string or None + """ + def getMesh(): + """ + DEPRECATED: Use the mesh property instead. + Returns the name of the mesh that will replace the current one. + + Returns None if no mesh has been scheduled to be added. + + @rtype: string or None + """ + def instantReplaceMesh(): + """ + Immediately replace mesh without delay. + @rtype: None + """ + +class KX_Scene(PyObjectPlus): + """ + An active scene that gives access to objects, cameras, lights and scene attributes. + + The activity culling stuff is supposed to disable logic bricks when their owner gets too far + from the active camera. It was taken from some code lurking at the back of KX_Scene - who knows + what it does! + + Example:: + import GameLogic + + # get the scene + scene = GameLogic.getCurrentScene() + + # print all the objects in the scene + for obj in scene.objects: + print obj.name + + # get an object named 'Cube' + obj = scene.objects["OBCube"] + + # get the first object in the scene. + obj = scene.objects[0] + + Example:: + # Get the depth of an object in the camera view. + import GameLogic + + obj = GameLogic.getCurrentController().getOwner() + cam = GameLogic.getCurrentScene().active_camera + + # Depth is negative and decreasing further from the camera + depth = obj.position[0]*cam.world_to_camera[2][0] + obj.position[1]*cam.world_to_camera[2][1] + obj.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3] + + @bug: All attributes are read only at the moment. + + @ivar name: The scene's name + @type name: string + @ivar objects: A list of objects in the scene. + @type objects: L{CListValue} of L{KX_GameObject} + @ivar objects_inactive: A list of objects on background layers (used for the addObject actuator). + @type objects_inactive: L{CListValue} of L{KX_GameObject} + @ivar lights: A list of lights in the scene. + @type lights: L{CListValue} of L{KX_LightObject} + @ivar cameras: A list of cameras in the scene. + @type cameras: L{CListValue} of L{KX_Camera} + @ivar active_camera: The current active camera + @type active_camera: L{KX_Camera} + @ivar suspended: True if the scene is suspended. + @type suspended: boolean + @ivar activity_culling: True if the scene is activity culling + @type activity_culling: boolean + @ivar activity_culling_radius: The distance outside which to do activity culling. Measured in manhattan distance. + @type activity_culling_radius: float + @group Deprecated: getLightList, getObjectList, getName + """ + + def getLightList(): + """ + DEPRECATED: use the 'lights' property. + Returns the list of lights in the scene. + + @rtype: list [L{KX_LightObject}] + """ + def getObjectList(): + """ + DEPRECATED: use the 'objects' property. + Returns the list of objects in the scene. + + @rtype: list [L{KX_GameObject}] + """ + def getName(): + """ + DEPRECATED: use the 'name' property. + Returns the name of the scene. + + @rtype: string + """ + + def addObject(object, other, time=0): + """ + Adds an object to the scene like the Add Object Actuator would, and returns the created object. + + @param object: The object to add + @type object: L{KX_GameObject} or string + @param other: The object's center to use when adding the object + @type other: L{KX_GameObject} or string + @param time: The lifetime of the added object, in frames. A time of 0 means the object will last forever. + @type time: int + + @rtype: L{KX_GameObject} + """ + +class KX_SceneActuator(SCA_IActuator): + """ + Scene Actuator logic brick. + + @warning: Scene actuators that use a scene name will be ignored if at game start, the + named scene doesn't exist or is empty + + This will generate a warning in the console: + + C{ERROR: GameObject I{OBName} has a SceneActuator I{ActuatorName} (SetScene) without scene} + + @ivar scene: the name of the scene to change to/overlay/underlay/remove/suspend/resume + @type scene: string. + @ivar camera: the camera to change to. + When setting the attribute, you can use either a L{KX_Camera} or the name of the camera. + @type camera: L{KX_Camera} on read, string or L{KX_Camera} on write + @ivar useRestart: Set flag to True to restart the sene + @type useRestart: bool + @ivar mode: The mode of the actuator + @type mode: int from 0 to 5 L{GameLogic.Scene Actuator} + """ + def setUseRestart(flag): + """ + DEPRECATED: use the useRestart property instead + Set flag to True to restart the scene. + + @type flag: boolean + """ + def setScene(scene): + """ + DEPRECATED: use the scene property instead + Sets the name of the scene to change to/overlay/underlay/remove/suspend/resume. + + @type scene: string + """ + def setCamera(camera): + """ + DEPRECATED: use the camera property instead + Sets the camera to change to. + + Camera can be either a L{KX_Camera} or the name of the camera. + + @type camera: L{KX_Camera} or string + """ + def getUseRestart(): + """ + DEPRECATED: use the useRestart property instead + Returns True if the scene will be restarted. + + @rtype: boolean + """ + def getScene(): + """ + DEPRECATED: use the scene property instead + Returns the name of the scene to change to/overlay/underlay/remove/suspend/resume. + + Returns an empty string ("") if no scene has been set. + + @rtype: string + """ + def getCamera(): + """ + DEPRECATED: use the camera property instead + Returns the name of the camera to change to. + + @rtype: string + """ + +class KX_SoundActuator(SCA_IActuator): + """ + Sound Actuator. + + The L{startSound()}, L{pauseSound()} and L{stopSound()} do not require + the actuator to be activated - they act instantly provided that the actuator has + been activated once at least. + + @ivar filename: Sets the filename of the sound this actuator plays. + @type filename: string + + @ivar volume: Sets the volume (gain) of the sound. + @type volume: float + + @ivar pitch: Sets the pitch of the sound. + @type pitch: float + + @ivar rollOffFactor: Sets the roll off factor. Rolloff defines the rate of attenuation as the sound gets further away. + @type rollOffFactor: float + + @ivar looping: Sets the loop mode of the actuator. + @type looping: integer + + @ivar position: Sets the position of the sound. + @type position: float array + + @ivar velocity: Sets the speed of the sound; The speed of the sound alter the pitch. + @type velocity: float array + + @ivar orientation: Sets the orientation of the sound. When setting the orientation you can + also use quaternion [float,float,float,float] or euler angles [float,float,float] + @type orientation: 3x3 matrix [[float]] + + @ivar type: Sets the operation mode of the actuator. You can use one of the following constant: + - KX_SOUNDACT_PLAYSTOP (1) + - KX_SOUNDACT_PLAYEND (2) + - KX_SOUNDACT_LOOPSTOP (3) + - KX_SOUNDACT_LOOPEND (4) + - KX_SOUNDACT_LOOPBIDIRECTIONAL (5) + - KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP (6) + @type type: integer + + @group Play Methods: startSound, pauseSound, stopSound + """ + def setFilename(filename): + """ + DEPRECATED: Use the filename property instead. + Sets the filename of the sound this actuator plays. + + @type filename: string + """ + def getFilename(): + """ + DEPRECATED: Use the filename property instead. + Returns the filename of the sound this actuator plays. + + @rtype: string + """ + def startSound(): + """ + Starts the sound. + """ + def pauseSound(): + """ + Pauses the sound. + """ + def stopSound(): + """ + Stops the sound. + """ + def setGain(gain): + """ + DEPRECATED: Use the volume property instead + Sets the gain (volume) of the sound + + @type gain: float + @param gain: 0.0 (quiet) <= gain <= 1.0 (loud) + """ + def getGain(): + """ + DEPRECATED: Use the volume property instead. + Gets the gain (volume) of the sound. + + @rtype: float + """ + def setPitch(pitch): + """ + DEPRECATED: Use the pitch property instead. + Sets the pitch of the sound. + + @type pitch: float + """ + def getPitch(): + """ + DEPRECATED: Use the pitch property instead. + Returns the pitch of the sound. + + @rtype: float + """ + def setRollOffFactor(rolloff): + """ + DEPRECATED: Use the rollOffFactor property instead. + Sets the rolloff factor for the sounds. + + Rolloff defines the rate of attenuation as the sound gets further away. + Higher rolloff factors shorten the distance at which the sound can be heard. + + @type rolloff: float + """ + def getRollOffFactor(): + """ + DEPRECATED: Use the rollOffFactor property instead. + Returns the rolloff factor for the sound. + + @rtype: float + """ + def setLooping(loop): + """ + DEPRECATED: Use the looping property instead. + Sets the loop mode of the actuator. + + @bug: There are no constants defined for this method! + @param loop: - Play Stop 1 + - Play End 2 + - Loop Stop 3 + - Loop End 4 + - Bidirection Stop 5 + - Bidirection End 6 + @type loop: integer + """ + def getLooping(): + """ + DEPRECATED: Use the looping property instead. + Returns the current loop mode of the actuator. + + @rtype: integer + """ + def setPosition(x, y, z): + """ + DEPRECATED: Use the position property instead. + Sets the position this sound will come from. + + @type x: float + @param x: The x coordinate of the sound. + @type y: float + @param y: The y coordinate of the sound. + @type z: float + @param z: The z coordinate of the sound. + """ + def setVelocity(vx, vy, vz): + """ + DEPRECATED: Use the velocity property instead. + Sets the velocity this sound is moving at. + + The sound's pitch is determined from the velocity. + + @type vx: float + @param vx: The vx coordinate of the sound. + @type vy: float + @param vy: The vy coordinate of the sound. + @type vz: float + @param vz: The vz coordinate of the sound. + """ + def setOrientation(o11, o12, o13, o21, o22, o23, o31, o32, o33): + """ + DEPRECATED: Use the orientation property instead. + Sets the orientation of the sound. + + The nine parameters specify a rotation matrix:: + | o11, o12, o13 | + | o21, o22, o23 | + | o31, o32, o33 | + """ + + def setType(mode): + """ + DEPRECATED: Use the type property instead. + Sets the operation mode of the actuator. + + @param mode: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP + @type mode: integer + """ + + def getType(): + """ + DEPRECATED: Use the type property instead. + Returns the operation mode of the actuator. + + @rtype: integer + @return: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP + """ + +class KX_StateActuator(SCA_IActuator): + """ + State actuator changes the state mask of parent object. + + Property: + + @ivar operation: type of bit operation to be applied on object state mask. + You can use one of the following constant: + - KX_STATE_OP_CPY (0) : Copy state mask + - KX_STATE_OP_SET (1) : Add bits to state mask + - KX_STATE_OP_CLR (2) : Substract bits to state mask + - KX_STATE_OP_NEG (3) : Invert bits to state mask + @type operation: integer + + @ivar mask: value that defines the bits that will be modified by the operation. + The bits that are 1 in the mask will be updated in the object state, + the bits that are 0 are will be left unmodified expect for the Copy operation + which copies the mask to the object state + @type mask: integer + """ + def setOperation(op): + """ + DEPRECATED: Use the operation property instead. + Set the type of bit operation to be applied on object state mask. + Use setMask() to specify the bits that will be modified. + + @param op: bit operation (0=Copy, 1=Add, 2=Substract, 3=Invert) + @type op: integer + """ + def setMask(mask): + """ + DEPRECATED: Use the mask property instead. + Set the value that defines the bits that will be modified by the operation. + The bits that are 1 in the value will be updated in the object state, + the bits that are 0 are will be left unmodified expect for the Copy operation + which copies the value to the object state. + + @param mask: bits that will be modified + @type mask: integer + """ + +class KX_TrackToActuator(SCA_IActuator): + """ + Edit Object actuator in Track To mode. + + @warning: Track To Actuators will be ignored if at game start, the + object to track to is invalid. + + This will generate a warning in the console: + + C{ERROR: GameObject I{OBName} no object in EditObjectActuator I{ActuatorName}} + + @ivar object: the object this actuator tracks. + @type object: KX_GameObject or None + @ivar time: the time in frames with which to delay the tracking motion + @type time: integer + @ivar use3D: the tracking motion to use 3D + @type use3D: boolean + + """ + def setObject(object): + """ + DEPRECATED: Use the object property. + Sets the object to track. + + @type object: L{KX_GameObject}, string or None + @param object: Either a reference to a game object or the name of the object to track. + """ + def getObject(name_only): + """ + DEPRECATED: Use the object property. + Returns the name of the object to track. + + @type name_only: bool + @param name_only: optional argument, when 0 return a KX_GameObject + @rtype: string, KX_GameObject or None if no object is set + """ + def setTime(time): + """ + DEPRECATED: Use the time property. + Sets the time in frames with which to delay the tracking motion. + + @type time: integer + """ + def getTime(): + """ + DEPRECATED: Use the time property. + Returns the time in frames with which the tracking motion is delayed. + + @rtype: integer + """ + def setUse3D(use3d): + """ + DEPRECATED: Use the use3D property. + Sets the tracking motion to use 3D. + + @type use3d: boolean + @param use3d: - True: allow the tracking motion to extend in the z-direction. + - False: lock the tracking motion to the x-y plane. + """ + def getUse3D(): + """ + DEPRECATED: Use the use3D property. + Returns True if the tracking motion will track in the z direction. + + @rtype: boolean + """ + +class KX_VehicleWrapper(PyObjectPlus): + """ + KX_VehicleWrapper + + TODO - description + """ + + def addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering): + + """ + Add a wheel to the vehicle + + @param wheel: The object to use as a wheel. + @type wheel: L{KX_GameObject} or a KX_GameObject name + @param attachPos: The position that this wheel will attach to. + @type attachPos: vector of 3 floats + @param attachDir: The direction this wheel points. + @type attachDir: vector of 3 floats + @param axleDir: The direction of this wheels axle. + @type axleDir: vector of 3 floats + @param suspensionRestLength: TODO - Description + @type suspensionRestLength: float + @param wheelRadius: The size of the wheel. + @type wheelRadius: float + """ + + def applyBraking(force, wheelIndex): + """ + Apply a braking force to the specified wheel + + @param force: the brake force + @type force: float + + @param wheelIndex: index of the wheel where the force needs to be applied + @type wheelIndex: integer + """ + def applyEngineForce(force, wheelIndex): + """ + Apply an engine force to the specified wheel + + @param force: the engine force + @type force: float + + @param wheelIndex: index of the wheel where the force needs to be applied + @type wheelIndex: integer + """ + def getConstraintId(): + """ + Get the constraint ID + + @rtype: integer + @return: the constraint id + """ + def getConstraintType(): + """ + Returns the constraint type. + + @rtype: integer + @return: constraint type + """ + def getNumWheels(): + """ + Returns the number of wheels. + + @rtype: integer + @return: the number of wheels for this vehicle + """ + def getWheelOrientationQuaternion(wheelIndex): + """ + Returns the wheel orientation as a quaternion. + + @param wheelIndex: the wheel index + @type wheelIndex: integer + + @rtype: TODO - type should be quat as per method name but from the code it looks like a matrix + @return: TODO Description + """ + def getWheelPosition(wheelIndex): + """ + Returns the position of the specified wheel + + @param wheelIndex: the wheel index + @type wheelIndex: integer + + @rtype: list[x, y, z] + @return: position vector + """ + def getWheelRotation(wheelIndex): + """ + Returns the rotation of the specified wheel + + @param wheelIndex: the wheel index + @type wheelIndex: integer + + @rtype: float + @return: the wheel rotation + """ + def setRollInfluence(rollInfluece, wheelIndex): + """ + Set the specified wheel's roll influence. + The higher the roll influence the more the vehicle will tend to roll over in corners. + + @param rollInfluece: the wheel roll influence + @type rollInfluece: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer + """ + def setSteeringValue(steering, wheelIndex): + """ + Set the specified wheel's steering + + @param steering: the wheel steering + @type steering: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer + """ + def setSuspensionCompression(compression, wheelIndex): + """ + Set the specified wheel's compression + + @param compression: the wheel compression + @type compression: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer + """ + def setSuspensionDamping(damping, wheelIndex): + """ + Set the specified wheel's damping + + @param damping: the wheel damping + @type damping: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer + """ + def setSuspensionStiffness(stiffness, wheelIndex): + """ + Set the specified wheel's stiffness + + @param stiffness: the wheel stiffness + @type stiffness: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer + """ + def setTyreFriction(friction, wheelIndex): + """ + Set the specified wheel's tyre friction + + @param friction: the tyre friction + @type friction: float + + @param wheelIndex: the wheel index + @type wheelIndex: integer + """ + +class KX_VertexProxy(SCA_IObject): + """ + A vertex holds position, UV, colour and normal information. + + Note: + The physics simulation is NOT currently updated - physics will not respond + to changes in the vertex position. + + @ivar XYZ: The position of the vertex. + @type XYZ: list [x, y, z] + @ivar UV: The texture coordinates of the vertex. + @type UV: list [u, v] + @ivar normal: The normal of the vertex + @type normal: list [nx, ny, nz] + @ivar colour: The colour of the vertex. + Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0] + @type colour: list [r, g, b, a] + @ivar color: Synonym for colour. + + @group Position: x, y, z + @ivar x: The x coordinate of the vertex. + @type x: float + @ivar y: The y coordinate of the vertex. + @type y: float + @ivar z: The z coordinate of the vertex. + @type z: float + + @group Texture Coordinates: u, v + @ivar u: The u texture coordinate of the vertex. + @type u: float + @ivar v: The v texture coordinate of the vertex. + @type v: float + + @ivar u2: The second u texture coordinate of the vertex. + @type u2: float + @ivar v2: The second v texture coordinate of the vertex. + @type v2: float + + @group Colour: r, g, b, a + @ivar r: The red component of the vertex colour. 0.0 <= r <= 1.0 + @type r: float + @ivar g: The green component of the vertex colour. 0.0 <= g <= 1.0 + @type g: float + @ivar b: The blue component of the vertex colour. 0.0 <= b <= 1.0 + @type b: float + @ivar a: The alpha component of the vertex colour. 0.0 <= a <= 1.0 + @type a: float + """ + + def getXYZ(): + """ + Gets the position of this vertex. + + @rtype: list [x, y, z] + @return: this vertexes position in local coordinates. + """ + def setXYZ(pos): + """ + Sets the position of this vertex. + + @type pos: list [x, y, z] + @param pos: the new position for this vertex in local coordinates. + """ + def getUV(): + """ + Gets the UV (texture) coordinates of this vertex. + + @rtype: list [u, v] + @return: this vertexes UV (texture) coordinates. + """ + def setUV(uv): + """ + Sets the UV (texture) coordinates of this vertex. + + @type uv: list [u, v] + """ + def getUV2(): + """ + Gets the 2nd UV (texture) coordinates of this vertex. + + @rtype: list [u, v] + @return: this vertexes UV (texture) coordinates. + """ + def setUV2(uv, unit): + """ + Sets the 2nd UV (texture) coordinates of this vertex. + + @type uv: list [u, v] + @param unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV + @param unit: int + """ + def getRGBA(): + """ + Gets the colour of this vertex. + + The colour is represented as four bytes packed into an integer value. The colour is + packed as RGBA. + + Since Python offers no way to get each byte without shifting, you must use the struct module to + access colour in an machine independent way. + + Because of this, it is suggested you use the r, g, b and a attributes or the colour attribute instead. + + Example:: + import struct; + col = struct.unpack('4B', struct.pack('I', v.getRGBA())) + # col = (r, g, b, a) + # black = ( 0, 0, 0, 255) + # white = (255, 255, 255, 255) + + @rtype: integer + @return: packed colour. 4 byte integer with one byte per colour channel in RGBA format. + """ + def setRGBA(col): + """ + Sets the colour of this vertex. + + See getRGBA() for the format of col, and its relevant problems. Use the r, g, b and a attributes + or the colour attribute instead. + + setRGBA() also accepts a four component list as argument col. The list represents the colour as [r, g, b, a] + with black = [0.0, 0.0, 0.0, 1.0] and white = [1.0, 1.0, 1.0, 1.0] + + Example:: + v.setRGBA(0xff0000ff) # Red + v.setRGBA(0xff00ff00) # Green on little endian, transparent purple on big endian + v.setRGBA([1.0, 0.0, 0.0, 1.0]) # Red + v.setRGBA([0.0, 1.0, 0.0, 1.0]) # Green on all platforms. + + @type col: integer or list [r, g, b, a] + @param col: the new colour of this vertex in packed RGBA format. + """ + def getNormal(): + """ + Gets the normal vector of this vertex. + + @rtype: list [nx, ny, nz] + @return: normalised normal vector. + """ + def setNormal(normal): + """ + Sets the normal vector of this vertex. + + @type normal: sequence of floats [r, g, b] + @param normal: the new normal of this vertex. + """ + +class KX_VisibilityActuator(SCA_IActuator): + """ + Visibility Actuator. + @ivar visibility: whether the actuator makes its parent object visible or invisible + @type visibility: boolean + @ivar occlusion: whether the actuator makes its parent object an occluder or not + @type occlusion: boolean + @ivar recursion: whether the visibility/occlusion should be propagated to all children of the object + @type recursion: boolean + """ + def set(visible): + """ + DEPRECATED: Use the visibility property instead. + Sets whether the actuator makes its parent object visible or invisible. + + @param visible: - True: Makes its parent visible. + - False: Makes its parent invisible. + """ +# +# Documentation for PyObjectPlus base class + +class SCA_2DFilterActuator(SCA_IActuator): + """ + Create, enable and disable 2D filters + + Properties: + + The following properties don't have an immediate effect. + You must active the actuator to get the result. + The actuator is not persistent: it automatically stops itself after setting up the filter + but the filter remains active. To stop a filter you must activate the actuator with 'type' + set to RAS_2DFILTER_DISABLED or RAS_2DFILTER_NOFILTER. + + @ivar shaderText: shader source code for custom shader + @type shaderText: string + @ivar disableMotionBlur: action on motion blur: 0=enable, 1=disable + @type disableMotionBlur: integer + @ivar type: type of 2D filter, use one of the following constants: + RAS_2DFILTER_ENABLED (-2) : enable the filter that was previously disabled + RAS_2DFILTER_DISABLED (-1) : disable the filter that is currently active + RAS_2DFILTER_NOFILTER (0) : disable and destroy the filter that is currently active + RAS_2DFILTER_MOTIONBLUR (1) : create and enable preset filters + RAS_2DFILTER_BLUR (2) + RAS_2DFILTER_SHARPEN (3) + RAS_2DFILTER_DILATION (4) + RAS_2DFILTER_EROSION (5) + RAS_2DFILTER_LAPLACIAN (6) + RAS_2DFILTER_SOBEL (7) + RAS_2DFILTER_PREWITT (8) + RAS_2DFILTER_GRAYSCALE (9) + RAS_2DFILTER_SEPIA (10) + RAS_2DFILTER_INVERT (11) + RAS_2DFILTER_CUSTOMFILTER (12) : customer filter, the code code is set via shaderText property + @type type: integer + @ivar passNb: order number of filter in the stack of 2D filters. Filters are executed in increasing order of passNb. + Only be one filter can be defined per passNb. + @type passNb: integer (0-100) + @ivar value: argument for motion blur filter + @type value: float (0.0-100.0) + """ + +class SCA_ANDController(SCA_IController): + """ + An AND controller activates only when all linked sensors are activated. + + There are no special python methods for this controller. + """ + +class SCA_ActuatorSensor(SCA_ISensor): + """ + Actuator sensor detect change in actuator state of the parent object. + It generates a positive pulse if the corresponding actuator is activated + and a negative pulse if the actuator is deactivated. + + Properties: + + @ivar actuator: the name of the actuator that the sensor is monitoring. + @type actuator: string + """ + def getActuator(): + """ + DEPRECATED: use the actuator property + Return the Actuator with which the sensor operates. + + @rtype: string + """ + def setActuator(name): + """ + DEPRECATED: use the actuator property + Sets the Actuator with which to operate. If there is no Actuator + of this name, the function has no effect. + + @param name: actuator name + @type name: string + """ + +class SCA_AlwaysSensor(SCA_ISensor): + """ + This sensor is always activated. + """ + +class SCA_DelaySensor(SCA_ISensor): + """ + The Delay sensor generates positive and negative triggers at precise time, + expressed in number of frames. The delay parameter defines the length + of the initial OFF period. A positive trigger is generated at the end of this period. + The duration parameter defines the length of the ON period following the OFF period. + There is a negative trigger at the end of the ON period. If duration is 0, the sensor + stays ON and there is no negative trigger. + The sensor runs the OFF-ON cycle once unless the repeat option is set: the + OFF-ON cycle repeats indefinately (or the OFF cycle if duration is 0). + Use SCA_ISensor::reset() at any time to restart sensor. + + Properties: + + @ivar delay: length of the initial OFF period as number of frame, 0 for immediate trigger. + @type delay: integer. + @ivar duration: length of the ON period in number of frame after the initial OFF period. + If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. + @type duration: integer + @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. + @type repeat: integer + """ + def setDelay(delay): + """ + DEPRECATED: use the delay property + Set the initial delay before the positive trigger. + + @param delay: length of the initial OFF period as number of frame, 0 for immediate trigger + @type delay: integer + """ + def setDuration(duration): + """ + DEPRECATED: use the duration property + Set the duration of the ON pulse after initial delay and the generation of the positive trigger. + If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. + + @param duration: length of the ON period in number of frame after the initial OFF period + @type duration: integer + """ + def setRepeat(repeat): + """ + DEPRECATED: use the repeat property + Set if the sensor repeat mode. + + @param repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. + @type repeat: integer + """ + def getDelay(): + """ + DEPRECATED: use the delay property + Return the delay parameter value. + + @rtype: integer + """ + def getDuration(): + """ + DEPRECATED: use the duration property + Return the duration parameter value + + @rtype: integer + """ + def getRepeat(): + """ + DEPRECATED: use the repeat property + Return the repeat parameter value + + @rtype: KX_TRUE or KX_FALSE + """ + +class SCA_JoystickSensor(SCA_ISensor): + """ + This sensor detects player joystick events. + + Properties: + + @ivar axisValues: (read-only) The state of the joysticks axis as a list of values L{numAxis} long. + each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. + The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls. + left:[-32767, 0, ...], right:[32767, 0, ...], up:[0, -32767, ...], down:[0, 32767, ...] + @type axisValues: list of ints + + @ivar axisSingle: (read-only) like L{axisValues} but returns a single axis value that is set by the sensor. + Only use this for "Single Axis" type sensors otherwise it will raise an error. + @type axisSingle: int + + @ivar numAxis: (read-only) The number of axes for the joystick at this index. + @type numAxis: integer + @ivar numButtons: (read-only) The number of buttons for the joystick at this index. + @type numButtons: integer + @ivar numHats: (read-only) The number of hats for the joystick at this index. + @type numHats: integer + @ivar connected: (read-only) True if a joystick is connected at this joysticks index. + @type connected: boolean + @ivar index: The joystick index to use (from 0 to 7). The first joystick is always 0. + @type index: integer + @ivar threshold: Axis threshold. Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. + @type threshold: integer + @ivar button: The button index the sensor reacts to (first button = 0). When the "All Events" toggle is set, this option has no effect. + @type button: integer + @ivar axis: The axis this sensor reacts to, as a list of two values [axisIndex, axisDirection] + axisIndex: the axis index to use when detecting axis movement, 1=primary directional control, 2=secondary directional control. + axisDirection: 0=right, 1=up, 2=left, 3=down + @type axis: [integer, integer] + @ivar hat: The hat the sensor reacts to, as a list of two values: [hatIndex, hatDirection] + hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat. + hatDirection: 0-11 + @type hat: [integer, integer] + """ + + def getButtonActiveList(): + """ + Returns a list containing the indicies of the currently pressed buttons. + @rtype: list + """ + def getButtonStatus(buttonIndex): + """ + Returns a bool of the current pressed state of the specified button. + @param buttonIndex: the button index, 0=first button + @type buttonIndex: integer + @rtype: bool + """ + def getIndex(): + """ + DEPRECATED: use the 'index' property. + Returns the joystick index to use (from 1 to 8). + @rtype: integer + """ + def setIndex(index): + """ + DEPRECATED: use the 'index' property. + Sets the joystick index to use. + @param index: The index of this joystick sensor, Clamped between 1 and 8. + @type index: integer + @note: This is only useful when you have more then 1 joystick connected to your computer - multiplayer games. + """ + def getAxis(): + """ + DEPRECATED: use the 'axis' property. + Returns the current axis this sensor reacts to. See L{getAxisValue()} for the current axis state. + @rtype: list + @return: 2 values returned are [axisIndex, axisDirection] - see L{setAxis()} for their purpose. + @note: When the "All Events" toggle is set, this option has no effect. + """ + def setAxis(axisIndex, axisDirection): + """ + DEPRECATED: use the 'axis' property. + @param axisIndex: Set the axis index to use when detecting axis movement. + @type axisIndex: integer from 1 to 2 + @param axisDirection: Set the axis direction used for detecting motion. 0:right, 1:up, 2:left, 3:down. + @type axisDirection: integer from 0 to 3 + @note: When the "All Events" toggle is set, this option has no effect. + """ + def getAxisValue(): + """ + DEPRECATED: use the 'axisPosition' property. + Returns the state of the joysticks axis. See differs to L{getAxis()} returning the current state of the joystick. + @rtype: list + @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. + + The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls. + + left:[-32767, 0, ...], right:[32767, 0, ...], up:[0, -32767, ...], down:[0, 32767, ...] + @note: Some gamepads only set the axis on and off like a button. + """ + def getThreshold(): + """ + DEPRECATED: use the 'threshold' property. + Get the axis threshold. See L{setThreshold()} for details. + @rtype: integer + """ + def setThreshold(threshold): + """ + DEPRECATED: use the 'threshold' property. + Set the axis threshold. + @param threshold: Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. + @type threshold: integer + """ + def getButton(): + """ + DEPRECATED: use the 'button' property. + Returns the button index the sensor reacts to. See L{getButtonValue()} for a list of pressed buttons. + @rtype: integer + @note: When the "All Events" toggle is set, this option has no effect. + """ + def setButton(index): + """ + DEPRECATED: use the 'button' property. + Sets the button index the sensor reacts to when the "All Events" option is not set. + @note: When the "All Events" toggle is set, this option has no effect. + """ + def getButtonValue(): + """ + DEPRECATED: use the 'getButtonActiveList' method. + Returns a list containing the indicies of the currently pressed buttons. + @rtype: list + """ + def getHat(): + """ + DEPRECATED: use the 'hat' property. + Returns the current hat direction this sensor is set to. + [hatNumber, hatDirection]. + @rtype: list + @note: When the "All Events" toggle is set, this option has no effect. + """ + def setHat(index,direction): + """ + DEPRECATED: use the 'hat' property. + Sets the hat index the sensor reacts to when the "All Events" option is not set. + @type index: integer + """ + def getNumAxes(): + """ + DEPRECATED: use the 'numAxis' property. + Returns the number of axes for the joystick at this index. + @rtype: integer + """ + def getNumButtons(): + """ + DEPRECATED: use the 'numButtons' property. + Returns the number of buttons for the joystick at this index. + @rtype: integer + """ + def getNumHats(): + """ + DEPRECATED: use the 'numHats' property. + Returns the number of hats for the joystick at this index. + @rtype: integer + """ + def isConnected(): + """ + DEPRECATED: use the 'connected' property. + Returns True if a joystick is detected at this joysticks index. + @rtype: bool + """ + +class SCA_KeyboardSensor(SCA_ISensor): + """ + A keyboard sensor detects player key presses. + + See module L{GameKeys} for keycode values. + + @ivar key: The key code this sensor is looking for. + @type key: keycode from L{GameKeys} module + @ivar hold1: The key code for the first modifier this sensor is looking for. + @type hold1: keycode from L{GameKeys} module + @ivar hold2: The key code for the second modifier this sensor is looking for. + @type hold2: keycode from L{GameKeys} module + @ivar toggleProperty: The name of the property that indicates whether or not to log keystrokes as a string. + @type toggleProperty: string + @ivar targetProperty: The name of the property that receives keystrokes in case in case a string is logged. + @type targetProperty: string + @ivar useAllKeys: Flag to determine whether or not to accept all keys. + @type useAllKeys: boolean + @ivar events: a list of pressed keys that have either been pressed, or just released, or are active this frame. (read only). + + - 'keycode' matches the values in L{GameKeys}. + - 'status' uses... + - L{GameLogic.KX_INPUT_NONE} + - L{GameLogic.KX_INPUT_JUST_ACTIVATED} + - L{GameLogic.KX_INPUT_ACTIVE} + - L{GameLogic.KX_INPUT_JUST_RELEASED} + + @type events: list [[keycode, status], ...] + """ + + def getKeyStatus(keycode): + """ + Get the status of a key. + + @rtype: key state L{GameLogic} members (KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED) + @return: The state of the given key + @type keycode: integer + @param keycode: The code that represents the key you want to get the state of + """ + + #--The following methods are DEPRECATED-- + def getKey(): + """ + Returns the key code this sensor is looking for. + + B{DEPRECATED: Use the "key" property instead}. + + @rtype: keycode from L{GameKeys} module + """ + + def setKey(keycode): + """ + Set the key this sensor should listen for. + + B{DEPRECATED: Use the "key" property instead}. + + @type keycode: keycode from L{GameKeys} module + """ + + def getHold1(): + """ + Returns the key code for the first modifier this sensor is looking for. + + B{DEPRECATED: Use the "hold1" property instead}. + + @rtype: keycode from L{GameKeys} module + """ + + def setHold1(keycode): + """ + Sets the key code for the first modifier this sensor should look for. + + B{DEPRECATED: Use the "hold1" property instead}. + + @type keycode: keycode from L{GameKeys} module + """ + + def getHold2(): + """ + Returns the key code for the second modifier this sensor is looking for. + + B{DEPRECATED: Use the "hold2" property instead}. + + @rtype: keycode from L{GameKeys} module + """ + + def setHold2(keycode): + """ + Sets the key code for the second modifier this sensor should look for. + + B{DEPRECATED: Use the "hold2" property instead.} + + @type keycode: keycode from L{GameKeys} module + """ + + def getPressedKeys(): + """ + Get a list of keys that have either been pressed, or just released this frame. + + B{DEPRECATED: Use "events" instead.} + + @rtype: list of key status. [[keycode, status]] + """ + + def getCurrentlyPressedKeys(): + """ + Get a list of currently pressed keys that have either been pressed, or just released + + B{DEPRECATED: Use "events" instead.} + + @rtype: list of key status. [[keycode, status]] + """ + +class SCA_NANDController(SCA_IController): + """ + An NAND controller activates when all linked sensors are not active. + + There are no special python methods for this controller. + """ + +class SCA_NORController(SCA_IController): + """ + An NOR controller activates only when all linked sensors are de-activated. + + There are no special python methods for this controller. + """ + +class SCA_ORController(SCA_IController): + """ + An OR controller activates when any connected sensor activates. + + There are no special python methods for this controller. + """ + +class SCA_PropertyActuator(SCA_IActuator): + """ + Property Actuator + + Properties: + + @ivar property: the property on which to operate. + @type property: string + @ivar value: the value with which the actuator operates. + @type value: string + """ + def setProperty(prop): + """ + DEPRECATED: use the 'property' property + Set the property on which to operate. + + If there is no property of this name, the call is ignored. + + @type prop: string + @param prop: The name of the property to set. + """ + def getProperty(): + """ + DEPRECATED: use the 'property' property + Returns the name of the property on which to operate. + + @rtype: string + """ + def setValue(value): + """ + DEPRECATED: use the 'value' property + Set the value with which the actuator operates. + + If the value is not compatible with the type of the + property, the subsequent action is ignored. + + @type value: string + """ + def getValue(): + """ + DEPRECATED: use the 'value' property + Gets the value with which this actuator operates. + + @rtype: string + """ + +class SCA_PropertySensor(SCA_ISensor): + """ + Activates when the game object property matches. + + Properties: + + @ivar type: type of check on the property: + KX_PROPSENSOR_EQUAL(1), KX_PROPSENSOR_NOTEQUAL(2), KX_PROPSENSOR_INTERVAL(3), + KX_PROPSENSOR_CHANGED(4), KX_PROPSENSOR_EXPRESSION(5) + @type type: integer + @ivar property: the property with which the sensor operates. + @type property: string + @ivar value: the value with which the sensor compares to the value of the property. + @type value: string + """ + + def getType(): + """ + DEPRECATED: use the type property + Gets when to activate this sensor. + + @return: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, + KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, + or KX_PROPSENSOR_EXPRESSION. + """ + + def setType(checktype): + """ + DEPRECATED: use the type property + Set the type of check to perform. + + @type checktype: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, + KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, + or KX_PROPSENSOR_EXPRESSION. + """ + + def getProperty(): + """ + DEPRECATED: use the property property + Return the property with which the sensor operates. + + @rtype: string + @return: the name of the property this sensor is watching. + """ + def setProperty(name): + """ + DEPRECATED: use the property property + Sets the property with which to operate. If there is no property + of that name, this call is ignored. + + @type name: string. + """ + def getValue(): + """ + DEPRECATED: use the value property + Return the value with which the sensor compares to the value of the property. + + @rtype: string + @return: the value of the property this sensor is watching. + """ + def setValue(value): + """ + DEPRECATED: use the value property + Set the value with which the sensor operates. If the value + is not compatible with the type of the property, the subsequent + action is ignored. + + @type value: string + """ + +class SCA_PythonController(SCA_IController): + """ + A Python controller uses a Python script to activate it's actuators, + based on it's sensors. + + Properties: + + @ivar script: the Python script this controller executes + @type script: string, read-only + + @group Deprecated: getScript, setScript + """ + def activate(actuator): + """ + Activates an actuator attached to this controller. + @type actuator: actuator or the actuator name as a string + """ + def deactivate(actuator): + """ + Deactivates an actuator attached to this controller. + @type actuator: actuator or the actuator name as a string + """ + def getScript(): + """ + DEPRECATED: use the script property + Gets the Python script this controller executes. + + @rtype: string + """ + def setScript(script): + """ + DEPRECATED: use the script property + Sets the Python script this controller executes. + + @type script: string. + """ + +class SCA_RandomActuator(SCA_IActuator): + """ + Random Actuator + + Properties: + + @ivar seed: Seed of the random number generator. + Equal seeds produce equal series. If the seed is 0, + the generator will produce the same value on every call. + @type seed: integer + @ivar para1: the first parameter of the active distribution. + Refer to the documentation of the generator types for the meaning + of this value. + @type para1: float, read-only + @ivar para2: the second parameter of the active distribution. + Refer to the documentation of the generator types for the meaning + of this value. + @type para2: float, read-only + @ivar distribution: distribution type: + KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, + KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, + KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, + KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL + @type distribution: integer, read-only + @ivar property: the name of the property to set with the random value. + If the generator and property types do not match, the assignment is ignored. + @type property: string + + """ + def setSeed(seed): + """ + DEPRECATED: use the seed property + Sets the seed of the random number generator. + + Equal seeds produce equal series. If the seed is 0, + the generator will produce the same value on every call. + + @type seed: integer + """ + def getSeed(): + """ + DEPRECATED: use the seed property + Returns the initial seed of the generator. + + @rtype: integer + """ + def getPara1(): + """ + DEPRECATED: use the para1 property + Returns the first parameter of the active distribution. + + Refer to the documentation of the generator types for the meaning + of this value. + + @rtype: float + """ + def getPara2(): + """ + DEPRECATED: use the para2 property + Returns the second parameter of the active distribution. + + Refer to the documentation of the generator types for the meaning + of this value. + + @rtype: float + """ + def getDistribution(): + """ + DEPRECATED: use the distribution property + Returns the type of random distribution. + + @rtype: distribution type + @return: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, + KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, + KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, + KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL + """ + def setProperty(property): + """ + DEPRECATED: use the property property + Set the property to which the random value is assigned. + + If the generator and property types do not match, the assignment is ignored. + + @type property: string + @param property: The name of the property to set. + """ + def getProperty(): + """ + DEPRECATED: use the property property + Returns the name of the property to set. + + @rtype: string + """ + def setBoolConst(value): + """ + Sets this generator to produce a constant boolean value. + + @param value: The value to return. + @type value: boolean + """ + def setBoolUniform(): + """ + Sets this generator to produce a uniform boolean distribution. + + The generator will generate True or False with 50% chance. + """ + def setBoolBernouilli(value): + """ + Sets this generator to produce a Bernouilli distribution. + + @param value: Specifies the proportion of False values to produce. + - 0.0: Always generate True + - 1.0: Always generate False + @type value: float + """ + def setIntConst(value): + """ + Sets this generator to always produce the given value. + + @param value: the value this generator produces. + @type value: integer + """ + def setIntUniform(lower_bound, upper_bound): + """ + Sets this generator to produce a random value between the given lower and + upper bounds (inclusive). + + @type lower_bound: integer + @type upper_bound: integer + """ + def setIntPoisson(value): + """ + Generate a Poisson-distributed number. + + This performs a series of Bernouilli tests with parameter value. + It returns the number of tries needed to achieve succes. + + @type value: float + """ + def setFloatConst(value): + """ + Always generate the given value. + + @type value: float + """ + def setFloatUniform(lower_bound, upper_bound): + """ + Generates a random float between lower_bound and upper_bound with a + uniform distribution. + + @type lower_bound: float + @type upper_bound: float + """ + def setFloatNormal(mean, standard_deviation): + """ + Generates a random float from the given normal distribution. + + @type mean: float + @param mean: The mean (average) value of the generated numbers + @type standard_deviation: float + @param standard_deviation: The standard deviation of the generated numbers. + """ + def setFloatNegativeExponential(half_life): + """ + Generate negative-exponentially distributed numbers. + + The half-life 'time' is characterized by half_life. + + @type half_life: float + """ + +class SCA_RandomSensor(SCA_ISensor): + """ + This sensor activates randomly. + + @ivar lastDraw: The seed of the random number generator. + @type lastDraw: int + @ivar seed: The seed of the random number generator. + @type seed: int + """ + + def setSeed(seed): + """ + Sets the seed of the random number generator. + + If the seed is 0, the generator will produce the same value on every call. + + @type seed: integer. + """ + def getSeed(): + """ + Returns the initial seed of the generator. Equal seeds produce equal random + series. + + @rtype: integer + """ + def getLastDraw(): + """ + Returns the last random number generated. + + @rtype: integer + """ + +class SCA_XNORController(SCA_IController): + """ + An XNOR controller activates when all linked sensors are the same (activated or inative). + + There are no special python methods for this controller. + """ + +class SCA_XORController(SCA_IController): + """ + An XOR controller activates when there is the input is mixed, but not when all are on or off. + + There are no special python methods for this controller. + """ + +class KX_Camera(KX_GameObject): + """ + A Camera object. + + @group Constants: INSIDE, INTERSECT, OUTSIDE + @ivar INSIDE: see sphereInsideFrustum() and boxInsideFrustum() + @ivar INTERSECT: see sphereInsideFrustum() and boxInsideFrustum() + @ivar OUTSIDE: see sphereInsideFrustum() and boxInsideFrustum() + + @ivar lens: The camera's lens value. + @type lens: float + @ivar near: The camera's near clip distance. + @type near: float + @ivar far: The camera's far clip distance. + @type far: float + @ivar perspective: True if this camera has a perspective transform. + + If perspective is False, this camera has an orthographic transform. + + Note that the orthographic transform is faked by multiplying the lens attribute + by 100.0 and translating the camera 100.0 along the z axis. + + This is the same as Blender. If you want a true orthographic transform, see L{setProjectionMatrix}. + @type perspective: boolean + @ivar frustum_culling: True if this camera is frustum culling. + @type frustum_culling: boolean + @ivar projection_matrix: This camera's 4x4 projection matrix. + @type projection_matrix: 4x4 Matrix [[float]] + @ivar modelview_matrix: This camera's 4x4 model view matrix. (read only) + Regenerated every frame from the camera's position and orientation. + @type modelview_matrix: 4x4 Matrix [[float]] + @ivar camera_to_world: This camera's camera to world transform. (read only) + Regenerated every frame from the camera's position and orientation. + @type camera_to_world: 4x4 Matrix [[float]] + @ivar world_to_camera: This camera's world to camera transform. (read only) + Regenerated every frame from the camera's position and orientation. + This is camera_to_world inverted. + @type world_to_camera: 4x4 Matrix [[float]] + + @group Deprecated: enableViewport + """ + + def sphereInsideFrustum(centre, radius): + """ + Tests the given sphere against the view frustum. + + @param centre: The centre of the sphere (in world coordinates.) + @type centre: list [x, y, z] + @param radius: the radius of the sphere + @type radius: float + @return: INSIDE, OUTSIDE or INTERSECT + + Example:: + import GameLogic + co = GameLogic.getCurrentController() + cam = co.GetOwner() + + # A sphere of radius 4.0 located at [x, y, z] = [1.0, 1.0, 1.0] + if (cam.sphereInsideFrustum([1.0, 1.0, 1.0], 4) != cam.OUTSIDE): + # Sphere is inside frustum ! + # Do something useful ! + else: + # Sphere is outside frustum + """ + def boxInsideFrustum(box): + """ + Tests the given box against the view frustum. + + Example:: + import GameLogic + co = GameLogic.getCurrentController() + cam = co.GetOwner() + + # Box to test... + box = [] + box.append([-1.0, -1.0, -1.0]) + box.append([-1.0, -1.0, 1.0]) + box.append([-1.0, 1.0, -1.0]) + box.append([-1.0, 1.0, 1.0]) + box.append([ 1.0, -1.0, -1.0]) + box.append([ 1.0, -1.0, 1.0]) + box.append([ 1.0, 1.0, -1.0]) + box.append([ 1.0, 1.0, 1.0]) + + if (cam.boxInsideFrustum(box) != cam.OUTSIDE): + # Box is inside/intersects frustum ! + # Do something useful ! + else: + # Box is outside the frustum ! + + @return: INSIDE, OUTSIDE or INTERSECT + @type box: list + @param box: Eight (8) corner points of the box (in world coordinates.) + """ + def pointInsideFrustum(point): + """ + Tests the given point against the view frustum. + + Example:: + import GameLogic + co = GameLogic.getCurrentController() + cam = co.GetOwner() + + # Test point [0.0, 0.0, 0.0] + if (cam.pointInsideFrustum([0.0, 0.0, 0.0])): + # Point is inside frustum ! + # Do something useful ! + else: + # Box is outside the frustum ! + + @rtype: boolean + @return: True if the given point is inside this camera's viewing frustum. + @type point: [x, y, z] + @param point: The point to test (in world coordinates.) + """ + def getCameraToWorld(): + """ + Returns the camera-to-world transform. + + @rtype: matrix (4x4 list) + @return: the camera-to-world transform matrix. + """ + def getWorldToCamera(): + """ + Returns the world-to-camera transform. + + This returns the inverse matrix of getCameraToWorld(). + + @rtype: matrix (4x4 list) + @return: the world-to-camera transform matrix. + """ + def getProjectionMatrix(): + """ + Returns the camera's projection matrix. + + @rtype: matrix (4x4 list) + @return: the camera's projection matrix. + """ + def setProjectionMatrix(matrix): + """ + Sets the camera's projection matrix. + + You should use normalised device coordinates for the clipping planes: + left = -1.0, right = 1.0, top = 1.0, bottom = -1.0, near = cam.near, far = cam.far + + Example:: + import GameLogic + + def Scale(matrix, size): + for y in range(4): + for x in range(4): + matrix[y][x] = matrix[y][x] * size[y] + return matrix + + # Generate a perspective projection matrix + def Perspective(cam): + return [[cam.near, 0.0 , 0.0 , 0.0 ], + [0.0 , cam.near, 0.0 , 0.0 ], + [0.0 , 0.0 , -(cam.far+cam.near)/(cam.far-cam.near), -2.0*cam.far*cam.near/(cam.far - cam.near)], + [0.0 , 0.0 , -1.0 , 0.0 ]] + + # Generate an orthographic projection matrix + # You will need to scale the camera + def Orthographic(cam): + return [[1.0/cam.scaling[0], 0.0 , 0.0 , 0.0 ], + [0.0 , 1.0/cam.scaling[1], 0.0 , 0.0 ], + [0.0 , 0.0 , -2.0/(cam.far-cam.near), -(cam.far+cam.near)/(cam.far-cam.near)], + [0.0 , 0.0 , 0.0 , 1.0 ]] + + # Generate an isometric projection matrix + def Isometric(cam): + return Scale([[0.707, 0.0 , 0.707, 0.0], + [0.408, 0.816,-0.408, 0.0], + [0.0 , 0.0 , 0.0 , 0.0], + [0.0 , 0.0 , 0.0 , 1.0]], + [1.0/cam.scaling[0], 1.0/cam.scaling[1], 1.0/cam.scaling[2], 1.0]) + + co = GameLogic.getCurrentController() + cam = co.getOwner() + cam.setProjectionMatrix(Perspective(cam))) + + @type matrix: 4x4 matrix. + @param matrix: The new projection matrix for this camera. + """ + + def enableViewport(viewport): + """ + DEPRECATED: use the isViewport property + Use this camera to draw a viewport on the screen (for split screen games or overlay scenes). The viewport region is defined with L{setViewport}. + + @type viewport: bool + @param viewport: the new viewport status + """ + def setOnTop(): + """ + Set this cameras viewport ontop of all other viewport. + """ + def setViewport(left, bottom, right, top): + """ + Sets the region of this viewport on the screen in pixels. + + Use L{Rasterizer.getWindowHeight} L{Rasterizer.getWindowWidth} to calculate values relative to the entire display. + + @type left: int + @type bottom: int + @type right: int + @type top: int + """ diff --git a/source/gameengine/PyDoc/KX_BlenderMaterial.py b/source/gameengine/PyDoc/KX_BlenderMaterial.py deleted file mode 100644 index c70a7dddcca..00000000000 --- a/source/gameengine/PyDoc/KX_BlenderMaterial.py +++ /dev/null @@ -1,41 +0,0 @@ - -from PyObjectPlus import * - -class KX_BlenderMaterial(PyObjectPlus): # , RAS_IPolyMaterial) - """ - KX_BlenderMaterial - - All placeholders have a __ prefix - """ - - def __getShader(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - - def __setBlending(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - def __getMaterialIndex(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ diff --git a/source/gameengine/PyDoc/KX_CDActuator.py b/source/gameengine/PyDoc/KX_CDActuator.py deleted file mode 100644 index e1067674e7e..00000000000 --- a/source/gameengine/PyDoc/KX_CDActuator.py +++ /dev/null @@ -1,55 +0,0 @@ -# $Id$ -# Documentation for CD Actuator -from SCA_IActuator import * - -class KX_CDActuator(SCA_IActuator): - """ - CD Controller actuator. - @ivar volume: controls the volume to set the CD to. 0.0 = silent, 1.0 = max volume. - @type volume: float - @ivar track: the track selected to be played - @type track: integer - @ivar gain: the gain (volume) of the CD between 0.0 and 1.0. - @type gain: float - """ - def startCD(): - """ - Starts the CD playing. - """ - def stopCD(): - """ - Stops the CD playing. - """ - def pauseCD(): - """ - Pauses the CD. - """ - def resumeCD(): - """ - Resumes the CD after a pause. - """ - def playAll(): - """ - Plays the CD from the beginning. - """ - def playTrack(trackNumber): - """ - Plays the track selected. - """ - def setGain(gain): - """ - DEPRECATED: Use the volume property. - Sets the gain (volume) of the CD. - - @type gain: float - @param gain: the gain to set the CD to. 0.0 = silent, 1.0 = max volume. - """ - def getGain(): - """ - DEPRECATED: Use the volume property. - Gets the current gain (volume) of the CD. - - @rtype: float - @return: Between 0.0 (silent) and 1.0 (max volume) - """ - diff --git a/source/gameengine/PyDoc/KX_Camera.py b/source/gameengine/PyDoc/KX_Camera.py deleted file mode 100644 index 5c54935192a..00000000000 --- a/source/gameengine/PyDoc/KX_Camera.py +++ /dev/null @@ -1,212 +0,0 @@ -# $Id$ -# Documentation for Camera game objects. -from KX_GameObject import * - -class KX_Camera(KX_GameObject): - """ - A Camera object. - - @group Constants: INSIDE, INTERSECT, OUTSIDE - @ivar INSIDE: see sphereInsideFrustum() and boxInsideFrustum() - @ivar INTERSECT: see sphereInsideFrustum() and boxInsideFrustum() - @ivar OUTSIDE: see sphereInsideFrustum() and boxInsideFrustum() - - @ivar lens: The camera's lens value. - @type lens: float - @ivar near: The camera's near clip distance. - @type near: float - @ivar far: The camera's far clip distance. - @type far: float - @ivar perspective: True if this camera has a perspective transform. - - If perspective is False, this camera has an orthographic transform. - - Note that the orthographic transform is faked by multiplying the lens attribute - by 100.0 and translating the camera 100.0 along the z axis. - - This is the same as Blender. If you want a true orthographic transform, see L{setProjectionMatrix}. - @type perspective: boolean - @ivar frustum_culling: True if this camera is frustum culling. - @type frustum_culling: boolean - @ivar projection_matrix: This camera's 4x4 projection matrix. - @type projection_matrix: 4x4 Matrix [[float]] - @ivar modelview_matrix: This camera's 4x4 model view matrix. (read only) - Regenerated every frame from the camera's position and orientation. - @type modelview_matrix: 4x4 Matrix [[float]] - @ivar camera_to_world: This camera's camera to world transform. (read only) - Regenerated every frame from the camera's position and orientation. - @type camera_to_world: 4x4 Matrix [[float]] - @ivar world_to_camera: This camera's world to camera transform. (read only) - Regenerated every frame from the camera's position and orientation. - This is camera_to_world inverted. - @type world_to_camera: 4x4 Matrix [[float]] - - @group Deprecated: enableViewport - """ - - def sphereInsideFrustum(centre, radius): - """ - Tests the given sphere against the view frustum. - - @param centre: The centre of the sphere (in world coordinates.) - @type centre: list [x, y, z] - @param radius: the radius of the sphere - @type radius: float - @return: INSIDE, OUTSIDE or INTERSECT - - Example:: - import GameLogic - co = GameLogic.getCurrentController() - cam = co.GetOwner() - - # A sphere of radius 4.0 located at [x, y, z] = [1.0, 1.0, 1.0] - if (cam.sphereInsideFrustum([1.0, 1.0, 1.0], 4) != cam.OUTSIDE): - # Sphere is inside frustum ! - # Do something useful ! - else: - # Sphere is outside frustum - """ - def boxInsideFrustum(box): - """ - Tests the given box against the view frustum. - - Example:: - import GameLogic - co = GameLogic.getCurrentController() - cam = co.GetOwner() - - # Box to test... - box = [] - box.append([-1.0, -1.0, -1.0]) - box.append([-1.0, -1.0, 1.0]) - box.append([-1.0, 1.0, -1.0]) - box.append([-1.0, 1.0, 1.0]) - box.append([ 1.0, -1.0, -1.0]) - box.append([ 1.0, -1.0, 1.0]) - box.append([ 1.0, 1.0, -1.0]) - box.append([ 1.0, 1.0, 1.0]) - - if (cam.boxInsideFrustum(box) != cam.OUTSIDE): - # Box is inside/intersects frustum ! - # Do something useful ! - else: - # Box is outside the frustum ! - - @return: INSIDE, OUTSIDE or INTERSECT - @type box: list - @param box: Eight (8) corner points of the box (in world coordinates.) - """ - def pointInsideFrustum(point): - """ - Tests the given point against the view frustum. - - Example:: - import GameLogic - co = GameLogic.getCurrentController() - cam = co.GetOwner() - - # Test point [0.0, 0.0, 0.0] - if (cam.pointInsideFrustum([0.0, 0.0, 0.0])): - # Point is inside frustum ! - # Do something useful ! - else: - # Box is outside the frustum ! - - @rtype: boolean - @return: True if the given point is inside this camera's viewing frustum. - @type point: [x, y, z] - @param point: The point to test (in world coordinates.) - """ - def getCameraToWorld(): - """ - Returns the camera-to-world transform. - - @rtype: matrix (4x4 list) - @return: the camera-to-world transform matrix. - """ - def getWorldToCamera(): - """ - Returns the world-to-camera transform. - - This returns the inverse matrix of getCameraToWorld(). - - @rtype: matrix (4x4 list) - @return: the world-to-camera transform matrix. - """ - def getProjectionMatrix(): - """ - Returns the camera's projection matrix. - - @rtype: matrix (4x4 list) - @return: the camera's projection matrix. - """ - def setProjectionMatrix(matrix): - """ - Sets the camera's projection matrix. - - You should use normalised device coordinates for the clipping planes: - left = -1.0, right = 1.0, top = 1.0, bottom = -1.0, near = cam.near, far = cam.far - - Example:: - import GameLogic - - def Scale(matrix, size): - for y in range(4): - for x in range(4): - matrix[y][x] = matrix[y][x] * size[y] - return matrix - - # Generate a perspective projection matrix - def Perspective(cam): - return [[cam.near, 0.0 , 0.0 , 0.0 ], - [0.0 , cam.near, 0.0 , 0.0 ], - [0.0 , 0.0 , -(cam.far+cam.near)/(cam.far-cam.near), -2.0*cam.far*cam.near/(cam.far - cam.near)], - [0.0 , 0.0 , -1.0 , 0.0 ]] - - # Generate an orthographic projection matrix - # You will need to scale the camera - def Orthographic(cam): - return [[1.0/cam.scaling[0], 0.0 , 0.0 , 0.0 ], - [0.0 , 1.0/cam.scaling[1], 0.0 , 0.0 ], - [0.0 , 0.0 , -2.0/(cam.far-cam.near), -(cam.far+cam.near)/(cam.far-cam.near)], - [0.0 , 0.0 , 0.0 , 1.0 ]] - - # Generate an isometric projection matrix - def Isometric(cam): - return Scale([[0.707, 0.0 , 0.707, 0.0], - [0.408, 0.816,-0.408, 0.0], - [0.0 , 0.0 , 0.0 , 0.0], - [0.0 , 0.0 , 0.0 , 1.0]], - [1.0/cam.scaling[0], 1.0/cam.scaling[1], 1.0/cam.scaling[2], 1.0]) - - co = GameLogic.getCurrentController() - cam = co.getOwner() - cam.setProjectionMatrix(Perspective(cam))) - - @type matrix: 4x4 matrix. - @param matrix: The new projection matrix for this camera. - """ - - def enableViewport(viewport): - """ - DEPRECATED: use the isViewport property - Use this camera to draw a viewport on the screen (for split screen games or overlay scenes). The viewport region is defined with L{setViewport}. - - @type viewport: bool - @param viewport: the new viewport status - """ - def setOnTop(): - """ - Set this cameras viewport ontop of all other viewport. - """ - def setViewport(left, bottom, right, top): - """ - Sets the region of this viewport on the screen in pixels. - - Use L{Rasterizer.getWindowHeight} L{Rasterizer.getWindowWidth} to calculate values relative to the entire display. - - @type left: int - @type bottom: int - @type right: int - @type top: int - """ diff --git a/source/gameengine/PyDoc/KX_CameraActuator.py b/source/gameengine/PyDoc/KX_CameraActuator.py deleted file mode 100644 index 6ffc55a5854..00000000000 --- a/source/gameengine/PyDoc/KX_CameraActuator.py +++ /dev/null @@ -1,98 +0,0 @@ -# $Id$ -# Documentation for KX_CameraActuator -from SCA_IActuator import * - -class KX_CameraActuator(SCA_IActuator): - """ - Applies changes to a camera. - - @ivar min: minimum distance to the target object maintained by the actuator - @type min: float - @ivar max: maximum distance to stay from the target object - @type max: float - @ivar height: height to stay above the target object - @type height: float - @ivar xy: axis this actuator is tracking, true=X, false=Y - @type xy: boolean - @ivar object: the object this actuator tracks. - @type object: KX_GameObject or None - @author: snail - """ - def getObject(name_only = 1): - """ - Returns the name of the object this actuator tracks. - - @type name_only: bool - @param name_only: optional argument, when 0 return a KX_GameObject - @rtype: string, KX_GameObject or None if no object is set - """ - - def setObject(target): - """ - Sets the object this actuator tracks. - - @param target: the object to track. - @type target: L{KX_GameObject}, string or None - """ - - def getMin(): - """ - Returns the minimum distance to target maintained by the actuator. - - @rtype: float - """ - - def setMin(distance): - """ - Sets the minimum distance to the target object maintained by the - actuator. - - @param distance: The minimum distance to maintain. - @type distance: float - """ - - def getMax(): - """ - Gets the maximum distance to stay from the target object. - - @rtype: float - """ - - def setMax(distance): - """ - Sets the maximum distance to stay from the target object. - - @param distance: The maximum distance to maintain. - @type distance: float - """ - - def getHeight(): - """ - Returns the height to stay above the target object. - - @rtype: float - """ - - def setHeight(height): - """ - Sets the height to stay above the target object. - - @type height: float - @param height: The height to stay above the target object. - """ - - def setXY(xaxis): - """ - Sets the axis to get behind. - - @param xaxis: False to track Y axis, True to track X axis. - @type xaxis: boolean - """ - - def getXY(): - """ - Returns the axis this actuator is tracking. - - @return: True if tracking X axis, False if tracking Y axis. - @rtype: boolean - """ diff --git a/source/gameengine/PyDoc/KX_ConstraintActuator.py b/source/gameengine/PyDoc/KX_ConstraintActuator.py deleted file mode 100644 index 89ca4d80c73..00000000000 --- a/source/gameengine/PyDoc/KX_ConstraintActuator.py +++ /dev/null @@ -1,249 +0,0 @@ -# $Id$ -# Documentation for KX_ConstraintActuator -from SCA_IActuator import * - -class KX_ConstraintActuator(SCA_IActuator): - """ - A constraint actuator limits the position, rotation, distance or orientation of an object. - - Properties: - - @ivar damp: time constant of the constraint expressed in frame (not use by Force field constraint) - @type damp: integer - - @ivar rotDamp: time constant for the rotation expressed in frame (only for the distance constraint) - 0 = use damp for rotation as well - @type rotDamp: integer - - @ivar direction: the reference direction in world coordinate for the orientation constraint - @type direction: 3-tuple of float: [x,y,z] - - @ivar option: Binary combination of the following values: - Applicable to Distance constraint: - - KX_ACT_CONSTRAINT_NORMAL ( 64) : Activate alignment to surface - - KX_ACT_CONSTRAINT_DISTANCE ( 512) : Activate distance control - - KX_ACT_CONSTRAINT_LOCAL (1024) : direction of the ray is along the local axis - Applicable to Force field constraint: - - KX_ACT_CONSTRAINT_DOROTFH (2048) : Force field act on rotation as well - Applicable to both: - - KX_ACT_CONSTRAINT_MATERIAL ( 128) : Detect material rather than property - - KX_ACT_CONSTRAINT_PERMANENT ( 256) : No deactivation if ray does not hit target - @type option: integer - - @ivar time: activation time of the actuator. The actuator disables itself after this many frame. - If set to 0, the actuator is not limited in time. - @type time: integer - - @ivar property: the name of the property or material for the ray detection of the distance constraint. - @type property: string - - @ivar min: The lower bound of the constraint - For the rotation and orientation constraint, it represents radiant - @type min: float - - @ivar distance: the target distance of the distance constraint - @type distance: float - - @ivar max: the upper bound of the constraint. - For rotation and orientation constraints, it represents radiant. - @type max: float - - @ivar rayLength: the length of the ray of the distance constraint. - @type rayLength: float - - @ivar limit: type of constraint, use one of the following constant: - KX_ACT_CONSTRAINT_LOCX ( 1) : limit X coord - KX_ACT_CONSTRAINT_LOCY ( 2) : limit Y coord - KX_ACT_CONSTRAINT_LOCZ ( 3) : limit Z coord - KX_ACT_CONSTRAINT_ROTX ( 4) : limit X rotation - KX_ACT_CONSTRAINT_ROTY ( 5) : limit Y rotation - KX_ACT_CONSTRAINT_ROTZ ( 6) : limit Z rotation - KX_ACT_CONSTRAINT_DIRPX ( 7) : set distance along positive X axis - KX_ACT_CONSTRAINT_DIRPY ( 8) : set distance along positive Y axis - KX_ACT_CONSTRAINT_DIRPZ ( 9) : set distance along positive Z axis - KX_ACT_CONSTRAINT_DIRNX (10) : set distance along negative X axis - KX_ACT_CONSTRAINT_DIRNY (11) : set distance along negative Y axis - KX_ACT_CONSTRAINT_DIRNZ (12) : set distance along negative Z axis - KX_ACT_CONSTRAINT_ORIX (13) : set orientation of X axis - KX_ACT_CONSTRAINT_ORIY (14) : set orientation of Y axis - KX_ACT_CONSTRAINT_ORIZ (15) : set orientation of Z axis - KX_ACT_CONSTRAINT_FHPX (16) : set force field along positive X axis - KX_ACT_CONSTRAINT_FHPY (17) : set force field along positive Y axis - KX_ACT_CONSTRAINT_FHPZ (18) : set force field along positive Z axis - KX_ACT_CONSTRAINT_FHNX (19) : set force field along negative X axis - KX_ACT_CONSTRAINT_FHNY (20) : set force field along negative Y axis - KX_ACT_CONSTRAINT_FHNZ (21) : set force field along negative Z axis - @type limit: integer - """ - def setDamp(time): - """ - Sets the time this constraint is delayed. - - @param time: The number of frames to delay. - Negative values are ignored. - @type time: integer - """ - def getDamp(): - """ - Returns the damping time of the constraint. - - @rtype: integer - """ - def setMin(lower): - """ - Sets the lower bound of the constraint. - - For rotational and orientation constraints, lower is specified in degrees. - - @type lower: float - """ - def getMin(): - """ - Gets the lower bound of the constraint. - - For rotational and orientation constraints, the lower bound is returned in radians. - - @rtype: float - """ - def setMax(upper): - """ - Sets the upper bound of the constraint. - - For rotational and orientation constraints, upper is specified in degrees. - - @type upper: float - """ - def getMax(): - """ - Gets the upper bound of the constraint. - - For rotational and orientation constraints, the upper bound is returned in radians. - - @rtype: float - """ - def setLimit(limit): - """ - Sets the type of constraint. - - See module L{GameLogic} for valid constraint types. - - @param limit: - Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ - Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY or KX_CONSTRAINTACT_ROTZ - Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ - Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ - """ - def getLimit(): - """ - Gets the type of constraint. - - See module L{GameLogic} for valid constraints. - - @return: - Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, - Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ, - Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ, - Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ - """ - def setRotDamp(duration): - """ - Sets the time constant of the orientation constraint. - - @param duration: If the duration is negative, it is set to 0. - @type duration: integer - """ - def getRotDamp(): - """ - Returns the damping time for application of the constraint. - - @rtype: integer - """ - def setDirection(vector): - """ - Sets the reference direction in world coordinate for the orientation constraint - - @type vector: 3-tuple - """ - def getDirection(): - """ - Returns the reference direction of the orientation constraint in world coordinate. - - @rtype: 3-tuple - """ - def setOption(option): - """ - Sets several options of the distance constraint. - - @type option: integer - @param option: Binary combination of the following values: - 64 : Activate alignment to surface - 128 : Detect material rather than property - 256 : No deactivation if ray does not hit target - 512 : Activate distance control - """ - def getOption(): - """ - Returns the option parameter. - - @rtype: integer - """ - def setTime(duration): - """ - Sets the activation time of the actuator. - - @type duration: integer - @param duration: The actuator disables itself after this many frame. - If set to 0 or negative, the actuator is not limited in time. - """ - def getTime(): - """ - Returns the time parameter. - - @rtype: integer - """ - def setProperty(property): - """ - Sets the name of the property or material for the ray detection of the distance constraint. - - @type property: string - @param property: If empty, the ray will detect any collisioning object. - """ - def getProperty(): - """ - Returns the property parameter. - - @rtype: string - """ - def setDistance(distance): - """ - Sets the target distance in distance constraint. - - @type distance: float - """ - def getDistance(): - """ - Returns the distance parameter. - - @rtype: float - """ - def setRayLength(length): - """ - Sets the maximum ray length of the distance constraint. - - @type length: float - """ - def getRayLength(): - """ - Returns the length of the ray - - @rtype: float - """ - - - - - - - - - diff --git a/source/gameengine/PyDoc/KX_ConstraintWrapper.py b/source/gameengine/PyDoc/KX_ConstraintWrapper.py deleted file mode 100644 index 5b34e1609e8..00000000000 --- a/source/gameengine/PyDoc/KX_ConstraintWrapper.py +++ /dev/null @@ -1,28 +0,0 @@ -class KX_ConstraintWrapper: # (PyObjectPlus) - """ - KX_ConstraintWrapper - - All placeholders have a __ prefix - """ - def __getConstraintId(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - - def __testMethod(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description - """ - diff --git a/source/gameengine/PyDoc/KX_GameActuator.py b/source/gameengine/PyDoc/KX_GameActuator.py deleted file mode 100644 index 0b329419ad7..00000000000 --- a/source/gameengine/PyDoc/KX_GameActuator.py +++ /dev/null @@ -1,31 +0,0 @@ -# $Id$ -# Documentation for KX_GameActuator -from SCA_IActuator import * - -class KX_GameActuator(SCA_IActuator): - """ - The game actuator loads a new .blend file, restarts the current .blend file or quits the game. - - Properties: - - @ivar file: the new .blend file to load - @type file: string. - @ivar mode: The mode of this actuator - @type mode: int from 0 to 5 L{GameLogic.Game Actuator} - """ - def getFile(): - """ - DEPRECATED: use the file property - Returns the filename of the new .blend file to load. - - @rtype: string - """ - def setFile(filename): - """ - DEPRECATED: use the file property - Sets the new .blend file to load. - - @param filename: The file name this actuator will load. - @type filename: string - """ - diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py deleted file mode 100644 index 257a25e8ad9..00000000000 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ /dev/null @@ -1,507 +0,0 @@ -# $Id$ -# Documentation for game objects - -from SCA_IObject import * -# from SCA_ISensor import * -# from SCA_IController import * -# from SCA_IActuator import * - - -class KX_GameObject(SCA_IObject): - """ - All game objects are derived from this class. - - Properties assigned to game objects are accessible as attributes of this class. - - note: Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the L{invalid} attribute to check. - - @ivar name: The object's name. (Read only) - - note: Currently (Blender 2.49) the prefix "OB" is added to all objects name. This may change in blender 2.5. - @type name: string. - @ivar mass: The object's mass - - note: The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0 - @type mass: float - @ivar linVelocityMin: Enforces the object keeps moving at a minimum velocity. - - note: Applies to dynamic and rigid body objects only. - - note: A value of 0.0 disables this option. - - note: While objects are stationary the minimum velocity will not be applied. - @type linVelocityMin: float - @ivar linVelocityMax: Clamp the maximum linear velocity to prevent objects moving beyond a set speed. - - note: Applies to dynamic and rigid body objects only. - - note: A value of 0.0 disables this option (rather then setting it stationary). - @type linVelocityMax: float - @ivar localInertia: the object's inertia vector in local coordinates. Read only. - @type localInertia: list [ix, iy, iz] - @ivar parent: The object's parent object. (Read only) - @type parent: L{KX_GameObject} or None - @ivar visible: visibility flag. - - note: Game logic will still run for invisible objects. - @type visible: boolean - @ivar occlusion: occlusion capability flag. - @type occlusion: boolean - @ivar position: The object's position. - DEPRECATED: use localPosition and worldPosition - @type position: list [x, y, z] On write: local position, on read: world position - @ivar orientation: The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. - DEPRECATED: use localOrientation and worldOrientation - @type orientation: 3x3 Matrix [[float]] On write: local orientation, on read: world orientation - @ivar scaling: The object's scaling factor. list [sx, sy, sz] - DEPRECATED: use localScaling and worldScaling - @type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling - @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. - @type localOrientation: 3x3 Matrix [[float]] - @ivar worldOrientation: The object's world orientation. - @type worldOrientation: 3x3 Matrix [[float]] - @ivar localScaling: The object's local scaling factor. - @type localScaling: list [sx, sy, sz] - @ivar worldScaling: The object's world scaling factor. Read-only - @type worldScaling: list [sx, sy, sz] - @ivar localPosition: The object's local position. - @type localPosition: list [x, y, z] - @ivar worldPosition: The object's world position. - @type worldPosition: list [x, y, z] - @ivar timeOffset: adjust the slowparent delay at runtime. - @type timeOffset: float - @ivar state: the game object's state bitmask, using the first 30 bits, one bit must always be set. - @type state: int - @ivar meshes: a list meshes for this object. - - note: Most objects use only 1 mesh. - - note: Changes to this list will not update the KX_GameObject. - @type meshes: list of L{KX_MeshProxy} - @ivar sensors: a sequence of L{SCA_ISensor} objects with string/index lookups and iterator support. - - note: This attribute is experemental and may be removed (but probably wont be). - - note: Changes to this list will not update the KX_GameObject. - @type sensors: list - @ivar controllers: a sequence of L{SCA_IController} objects with string/index lookups and iterator support. - - note: This attribute is experemental and may be removed (but probably wont be). - - note: Changes to this list will not update the KX_GameObject. - @type controllers: list of L{SCA_ISensor}. - @ivar actuators: a list of L{SCA_IActuator} with string/index lookups and iterator support. - - note: This attribute is experemental and may be removed (but probably wont be). - - note: Changes to this list will not update the KX_GameObject. - @type actuators: list - @ivar attrDict: get the objects internal python attribute dictionary for direct (faster) access. - @type attrDict: dict - @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh - """ - def endObject(): - """ - Delete this object, can be used inpace of the EndObject Actuator. - The actual removal of the object from the scene is delayed. - """ - def replaceMesh(mesh): - """ - Replace the mesh of this object with a new mesh. This works the same was as the actuator. - @type mesh: L{KX_MeshProxy} or mesh name - """ - def getVisible(): - """ - Gets the game object's visible flag. (B{deprecated}) - - @rtype: boolean - """ - def setVisible(visible, recursive): - """ - Sets the game object's visible flag. - - @type visible: boolean - @type recursive: boolean - @param recursive: optional argument to set all childrens visibility flag too. - """ - def setOcclusion(occlusion, recursive): - """ - Sets the game object's occlusion capability. - - @type occlusion: boolean - @type recursive: boolean - @param recursive: optional argument to set all childrens occlusion flag too. - """ - def getState(): - """ - Gets the game object's state bitmask. (B{deprecated}) - - @rtype: int - @return: the objects state. - """ - def setState(state): - """ - Sets the game object's state flag. (B{deprecated}). - The bitmasks for states from 1 to 30 can be set with (1<<0, 1<<1, 1<<2 ... 1<<29) - - @type state: integer - """ - def setPosition(pos): - """ - Sets the game object's position. (B{deprecated}) - Global coordinates for root object, local for child objects. - - - @type pos: [x, y, z] - @param pos: the new position, in local coordinates. - """ - def setWorldPosition(pos): - """ - Sets the game object's position in world coordinates regardless if the object is root or child. - - @type pos: [x, y, z] - @param pos: the new position, in world coordinates. - """ - def getPosition(): - """ - Gets the game object's position. (B{deprecated}) - - @rtype: list [x, y, z] - @return: the object's position in world coordinates. - """ - def setOrientation(orn): - """ - Sets the game object's orientation. (B{deprecated}) - - @type orn: 3x3 rotation matrix, or Quaternion. - @param orn: a rotation matrix specifying the new rotation. - @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. - """ - def alignAxisToVect(vect, axis, factor): - """ - Aligns any of the game object's axis along the given vector. - - @type vect: 3d vector. - @param vect: a vector to align the axis. - @type axis: integer. - @param axis:The axis you want to align - - 0: X axis - - 1: Y axis - - 2: Z axis (default) - @type factor: float - @param factor: Only rotate a feaction of the distance to the target vector (0.0 - 1.0) - """ - def getAxisVect(vect): - """ - Returns the axis vector rotates by the objects worldspace orientation. - This is the equivalent if multiplying the vector by the orientation matrix. - - @type vect: 3d vector. - @param vect: a vector to align the axis. - @rtype: 3d vector. - @return: The vector in relation to the objects rotation. - - """ - def getOrientation(): - """ - Gets the game object's orientation. (B{deprecated}) - - @rtype: 3x3 rotation matrix - @return: The game object's rotation matrix - @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. - """ - def applyMovement(movement, local = 0): - """ - Sets the game object's movement. - - @type movement: 3d vector. - @param movement: movement vector. - @type local: boolean - @param local: - False: you get the "global" movement ie: relative to world orientation (default). - - True: you get the "local" movement ie: relative to object orientation. - """ - def applyRotation(rotation, local = 0): - """ - Sets the game object's rotation. - - @type rotation: 3d vector. - @param rotation: rotation vector. - @type local: boolean - @param local: - False: you get the "global" rotation ie: relative to world orientation (default). - - True: you get the "local" rotation ie: relative to object orientation. - """ - def applyForce(force, local = 0): - """ - Sets the game object's force. - - This requires a dynamic object. - - @type force: 3d vector. - @param force: force vector. - @type local: boolean - @param local: - False: you get the "global" force ie: relative to world orientation (default). - - True: you get the "local" force ie: relative to object orientation. - """ - def applyTorque(torque, local = 0): - """ - Sets the game object's torque. - - This requires a dynamic object. - - @type torque: 3d vector. - @param torque: torque vector. - @type local: boolean - @param local: - False: you get the "global" torque ie: relative to world orientation (default). - - True: you get the "local" torque ie: relative to object orientation. - """ - def getLinearVelocity(local = 0): - """ - Gets the game object's linear velocity. - - This method returns the game object's velocity through it's centre of mass, - ie no angular velocity component. - - @type local: boolean - @param local: - False: you get the "global" velocity ie: relative to world orientation (default). - - True: you get the "local" velocity ie: relative to object orientation. - @rtype: list [vx, vy, vz] - @return: the object's linear velocity. - """ - def setLinearVelocity(velocity, local = 0): - """ - Sets the game object's linear velocity. - - This method sets game object's velocity through it's centre of mass, - ie no angular velocity component. - - This requires a dynamic object. - - @type velocity: 3d vector. - @param velocity: linear velocity vector. - @type local: boolean - @param local: - False: you get the "global" velocity ie: relative to world orientation (default). - - True: you get the "local" velocity ie: relative to object orientation. - """ - def getAngularVelocity(local = 0): - """ - Gets the game object's angular velocity. - - @type local: boolean - @param local: - False: you get the "global" velocity ie: relative to world orientation (default). - - True: you get the "local" velocity ie: relative to object orientation. - @rtype: list [vx, vy, vz] - @return: the object's angular velocity. - """ - def setAngularVelocity(velocity, local = 0): - """ - Sets the game object's angular velocity. - - This requires a dynamic object. - - @type velocity: 3d vector. - @param velocity: angular velocity vector. - @type local: boolean - @param local: - False: you get the "global" velocity ie: relative to world orientation (default). - - True: you get the "local" velocity ie: relative to object orientation. - """ - def getVelocity(point): - """ - Gets the game object's velocity at the specified point. - - Gets the game object's velocity at the specified point, including angular - components. - - @type point: list [x, y, z] - @param point: the point to return the velocity for, in local coordinates. (optional: default = [0, 0, 0]) - @rtype: list [vx, vy, vz] - @return: the velocity at the specified point. - """ - def getMass(): - """ - Gets the game object's mass. (B{deprecated}) - - @rtype: float - @return: the object's mass. - """ - def getReactionForce(): - """ - Gets the game object's reaction force. - - The reaction force is the force applied to this object over the last simulation timestep. - This also includes impulses, eg from collisions. - - (B{This is not implimented for bullet physics at the moment}) - - @rtype: list [fx, fy, fz] - @return: the reaction force of this object. - """ - def applyImpulse(point, impulse): - """ - Applies an impulse to the game object. - - This will apply the specified impulse to the game object at the specified point. - If point != getPosition(), applyImpulse will also change the object's angular momentum. - Otherwise, only linear momentum will change. - - @type point: list [x, y, z] - @param point: the point to apply the impulse to (in world coordinates) - """ - def suspendDynamics(): - """ - Suspends physics for this object. - """ - def restoreDynamics(): - """ - Resumes physics for this object. - @Note: The objects linear velocity will be applied from when the dynamics were suspended. - """ - def enableRigidBody(): - """ - Enables rigid body physics for this object. - - Rigid body physics allows the object to roll on collisions. - @Note: This is not working with bullet physics yet. - """ - def disableRigidBody(): - """ - Disables rigid body physics for this object. - @Note: This is not working with bullet physics yet. The angular is removed but rigid body physics can still rotate it later. - """ - def getParent(): - """ - Gets this object's parent. (B{deprecated}) - - @rtype: L{KX_GameObject} - @return: this object's parent object, or None if this object has no parent. - """ - def setParent(parent): - """ - Sets this object's parent. - - @type parent: L{KX_GameObject} - @param parent: new parent object. - """ - def removeParent(): - """ - Removes this objects parent. - """ - def getChildren(): - """ - Return a list of immediate children of this object. - @rtype: L{CListValue} of L{KX_GameObject} - @return: a list of all this objects children. - """ - def getChildrenRecursive(): - """ - Return a list of children of this object, including all their childrens children. - @rtype: L{CListValue} of L{KX_GameObject} - @return: a list of all this objects children recursivly. - """ - def getMesh(mesh): - """ - Gets the mesh object for this object. - - @type mesh: integer - @param mesh: the mesh object to return (optional: default mesh = 0) - @rtype: L{KX_MeshProxy} - @return: the first mesh object associated with this game object, or None if this object has no meshs. - """ - def getPhysicsId(): - """ - Returns the user data object associated with this game object's physics controller. - """ - def getPropertyNames(): - """ - Gets a list of all property names. - @rtype: list - @return: All property names for this object. - """ - def getDistanceTo(other): - """ - Returns the distance to another object or point. - - @param other: a point or another L{KX_GameObject} to measure the distance to. - @type other: L{KX_GameObject} or list [x, y, z] - @rtype: float - """ - def getVectTo(other): - """ - Returns the vector and the distance to another object or point. - The vector is normalized unless the distance is 0, in which a NULL vector is returned. - - @param other: a point or another L{KX_GameObject} to get the vector and distance to. - @type other: L{KX_GameObject} or list [x, y, z] - @rtype: 3-tuple (float, 3-tuple (x,y,z), 3-tuple (x,y,z)) - @return: (distance, globalVector(3), localVector(3)) - """ - def rayCastTo(other,dist,prop): - """ - Look towards another point/object and find first object hit within dist that matches prop. - - The ray is always casted from the center of the object, ignoring the object itself. - The ray is casted towards the center of another object or an explicit [x,y,z] point. - Use rayCast() if you need to retrieve the hit point - - @param other: [x,y,z] or object towards which the ray is casted - @type other: L{KX_GameObject} or 3-tuple - @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other - @type dist: float - @param prop: property name that object must have; can be omitted => detect any object - @type prop: string - @rtype: L{KX_GameObject} - @return: the first object hit or None if no object or object does not match prop - """ - def rayCast(objto,objfrom,dist,prop,face,xray,poly): - """ - Look from a point/object to another point/object and find first object hit within dist that matches prop. - if poly is 0, returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no hit. - if poly is 1, returns a 4-tuple with in addition a L{KX_PolyProxy} as 4th element. - - Ex:: - # shoot along the axis gun-gunAim (gunAim should be collision-free) - ob,point,normal = gun.rayCast(gunAim,None,50) - if ob: - # hit something - - Notes: - The ray ignores the object on which the method is called. - It is casted from/to object center or explicit [x,y,z] points. - - The face paremeter determines the orientation of the normal:: - 0 => hit normal is always oriented towards the ray origin (as if you casted the ray from outside) - 1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect) - - The ray has X-Ray capability if xray parameter is 1, otherwise the first object hit (other than self object) stops the ray. - The prop and xray parameters interact as follow:: - prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray. - prop off, xray on : idem. - prop on, xray off: return closest hit if it matches prop, no hit otherwise. - prop on, xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray. - The L{KX_PolyProxy} 4th element of the return tuple when poly=1 allows to retrieve information on the polygon hit by the ray. - If there is no hit or the hit object is not a static mesh, None is returned as 4th element. - - The ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects. - - @param objto: [x,y,z] or object to which the ray is casted - @type objto: L{KX_GameObject} or 3-tuple - @param objfrom: [x,y,z] or object from which the ray is casted; None or omitted => use self object center - @type objfrom: L{KX_GameObject} or 3-tuple or None - @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to - @type dist: float - @param prop: property name that object must have; can be omitted or "" => detect any object - @type prop: string - @param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin - @type face: int - @param xray: X-ray option: 1=>skip objects that don't match prop; 0 or omitted => stop on first object - @type xray: int - @param poly: polygon option: 1=>return value is a 4-tuple and the 4th element is a L{KX_PolyProxy} - @type poly: int - @rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz)) - or 4-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz), L{KX_PolyProxy}) - @return: (object,hitpoint,hitnormal) or (object,hitpoint,hitnormal,polygon) - If no hit, returns (None,None,None) or (None,None,None,None) - If the object hit is not a static mesh, polygon is None - """ - def setCollisionMargin(margin): - """ - Set the objects collision margin. - - note: If this object has no physics controller (a physics ID of zero), this function will raise RuntimeError. - - @type margin: float - @param margin: the collision margin distance in blender units. - """ - def sendMessage(subject, body="", to=""): - """ - Sends a message. - - @param subject: The subject of the message - @type subject: string - @param body: The body of the message (optional) - @type body: string - @param to: The name of the object to send the message to (optional) - @type to: string - """ diff --git a/source/gameengine/PyDoc/KX_IpoActuator.py b/source/gameengine/PyDoc/KX_IpoActuator.py deleted file mode 100644 index ebc0b855f0a..00000000000 --- a/source/gameengine/PyDoc/KX_IpoActuator.py +++ /dev/null @@ -1,124 +0,0 @@ -# $Id$ -# Documentation for KX_IpoActuator -from SCA_IActuator import * - -class KX_IpoActuator(SCA_IActuator): - """ - IPO actuator activates an animation. - - @ivar startFrame: Start frame. - @type startFrame: float - @ivar endFrame: End frame. - @type endFrame: float - @ivar propName: Use this property to define the Ipo position - @type propName: string - @ivar framePropName: Assign this property this action current frame number - @type framePropName: string - @ivar type: Play mode for the ipo. (In GameLogic.KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND, KX_IPOACT_FROM_PROP) - @type type: int - @ivar useIpoAsForce: Apply Ipo as a global or local force depending on the local option (dynamic objects only) - @type useIpoAsForce: bool - @ivar useIpoAdd: Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag - @type useIpoAdd: bool - @ivar useIpoLocal: Let the ipo acts in local coordinates, used in Force and Add mode. - @type useIpoLocal: bool - @ivar useChildren: Update IPO on all children Objects as well - @type useChildren: bool - """ - def set(mode, startframe, endframe, force): - """ - Sets the properties of the actuator. (B{deprecated}) - - @param mode: "Play", "PingPong", "Flipper", "LoopStop", "LoopEnd" or "FromProp" - @type mode: string - @param startframe: first frame to use - @type startframe: integer - @param endframe: last frame to use - @type endframe: integer - @param force: special mode - @type force: integer (0=normal, 1=interpret location as force, 2=additive) - """ - def setProperty(property): - """ - Sets the name of the property to be used in FromProp mode. (B{deprecated}) - - @type property: string - """ - def setStart(startframe): - """ - Sets the frame from which the IPO starts playing. (B{deprecated}) - - @type startframe: integer - """ - def getStart(): - """ - Returns the frame from which the IPO starts playing. (B{deprecated}) - - @rtype: integer - """ - def setEnd(endframe): - """ - Sets the frame at which the IPO stops playing. (B{deprecated}) - - @type endframe: integer - """ - def getEnd(): - """ - Returns the frame at which the IPO stops playing. (B{deprecated}) - - @rtype: integer - """ - def setIpoAsForce(force): - """ - Set whether to interpret the ipo as a force rather than a displacement. (B{deprecated}) - - @type force: boolean - @param force: KX_TRUE or KX_FALSE - """ - def getIpoAsForce(): - """ - Returns whether to interpret the ipo as a force rather than a displacement. (B{deprecated}) - - @rtype: boolean - """ - def setIpoAdd(add): - """ - Set whether to interpret the ipo as additive rather than absolute. (B{deprecated}) - - @type add: boolean - @param add: KX_TRUE or KX_FALSE - """ - def getIpoAdd(): - """ - Returns whether to interpret the ipo as additive rather than absolute. (B{deprecated}) - - @rtype: boolean - """ - def setType(mode): - """ - Sets the operation mode of the actuator. (B{deprecated}) - - @param mode: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND - @type mode: string - """ - def getType(): - """ - Returns the operation mode of the actuator. (B{deprecated}) - - @rtype: integer - @return: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND - """ - def setForceIpoActsLocal(local): - """ - Set whether to apply the force in the object's local - coordinates rather than the world global coordinates. (B{deprecated}) - - @param local: Apply the ipo-as-force in the object's local - coordinates? (KX_TRUE, KX_FALSE) - @type local: boolean - """ - def getForceIpoActsLocal(): - """ - Return whether to apply the force in the object's local - coordinates rather than the world global coordinates. (B{deprecated}) - """ diff --git a/source/gameengine/PyDoc/KX_LightObject.py b/source/gameengine/PyDoc/KX_LightObject.py deleted file mode 100644 index 8cc1787887b..00000000000 --- a/source/gameengine/PyDoc/KX_LightObject.py +++ /dev/null @@ -1,45 +0,0 @@ -# $Id$ -# Documentation for Light game objects. -from KX_GameObject import * - -class KX_LightObject(KX_GameObject): - """ - A Light object. - - Example: - - # Turn on a red alert light. - import GameLogic - - co = GameLogic.getCurrentController() - light = co.getOwner() - - light.energy = 1.0 - light.colour = [1.0, 0.0, 0.0] - - @group Constants: NORMAL, SPOT, SUN - @ivar SPOT: A spot light source. See attribute 'type' - @ivar SUN: A point light source with no attenuation. See attribute 'type' - @ivar NORMAL: A point light source. See attribute 'type' - - @ivar type: The type of light - must be SPOT, SUN or NORMAL - @ivar layer: The layer mask that this light affects object on. - @type layer: bitfield - @ivar energy: The brightness of this light. - @type energy: float - @ivar distance: The maximum distance this light can illuminate. (SPOT and NORMAL lights only) - @type distance: float - @ivar colour: The colour of this light. Black = [0.0, 0.0, 0.0], White = [1.0, 1.0, 1.0] - @type colour: list [r, g, b] - @ivar color: Synonym for colour. - @ivar lin_attenuation: The linear component of this light's attenuation. (SPOT and NORMAL lights only) - @type lin_attenuation: float - @ivar quad_attenuation: The quadratic component of this light's attenuation (SPOT and NORMAL lights only) - @type quad_attenuation: float - @ivar spotsize: The cone angle of the spot light, in degrees. (float) (SPOT lights only) - 0.0 <= spotsize <= 180.0. Spotsize = 360.0 is also accepted. - @ivar spotblend: Specifies the intensity distribution of the spot light. (float) (SPOT lights only) - Higher values result in a more focused light source. - 0.0 <= spotblend <= 1.0. - - """ diff --git a/source/gameengine/PyDoc/KX_MeshProxy.py b/source/gameengine/PyDoc/KX_MeshProxy.py deleted file mode 100644 index c864523cde8..00000000000 --- a/source/gameengine/PyDoc/KX_MeshProxy.py +++ /dev/null @@ -1,134 +0,0 @@ -# $Id$ -# Documentation for KX_MeshProxy - -from SCA_IObject import * - -class KX_MeshProxy(SCA_IObject): - """ - A mesh object. - - You can only change the vertex properties of a mesh object, not the mesh topology. - - To use mesh objects effectively, you should know a bit about how the game engine handles them. - 1. Mesh Objects are converted from Blender at scene load. - 2. The Converter groups polygons by Material. This means they can be sent to the - renderer efficiently. A material holds: - 1. The texture. - 2. The Blender material. - 3. The Tile properties - 4. The face properties - (From the "Texture Face" panel) - 5. Transparency & z sorting - 6. Light layer - 7. Polygon shape (triangle/quad) - 8. Game Object - 3. Verticies will be split by face if necessary. Verticies can only be shared between - faces if: - 1. They are at the same position - 2. UV coordinates are the same - 3. Their normals are the same (both polygons are "Set Smooth") - 4. They are the same colour - For example: a cube has 24 verticies: 6 faces with 4 verticies per face. - - The correct method of iterating over every L{KX_VertexProxy} in a game object:: - import GameLogic - - co = GameLogic.getcurrentController() - obj = co.getOwner() - - m_i = 0 - mesh = obj.getMesh(m_i) # There can be more than one mesh... - while mesh != None: - for mat in range(mesh.getNumMaterials()): - for v_index in range(mesh.getVertexArrayLength(mat)): - vertex = mesh.getVertex(mat, v_index) - # Do something with vertex here... - # ... eg: colour the vertex red. - vertex.colour = [1.0, 0.0, 0.0, 1.0] - m_i += 1 - mesh = obj.getMesh(m_i) - - @ivar materials: - @type materials: list of L{KX_BlenderMaterial} or L{KX_PolygonMaterial} types - - @ivar numPolygons: - @type numPolygons: integer - - @ivar numMaterials: - @type numMaterials: integer - """ - - def getNumMaterials(): - """ - Gets the number of materials associated with this object. - - @rtype: integer - """ - - def getMaterialName(matid): - """ - Gets the name of the specified material. - - @type matid: integer - @param matid: the specified material. - @rtype: string - @return: the attached material name. - """ - def getTextureName(matid): - """ - Gets the name of the specified material's texture. - - @type matid: integer - @param matid: the specified material - @rtype: string - @return: the attached material's texture name. - """ - def getVertexArrayLength(matid): - """ - Gets the length of the vertex array associated with the specified material. - - There is one vertex array for each material. - - @type matid: integer - @param matid: the specified material - @rtype: integer - @return: the number of verticies in the vertex array. - """ - def getVertex(matid, index): - """ - Gets the specified vertex from the mesh object. - - @type matid: integer - @param matid: the specified material - @type index: integer - @param index: the index into the vertex array. - @rtype: L{KX_VertexProxy} - @return: a vertex object. - """ - def getNumPolygons(): - """ - Returns the number of polygon in the mesh. - - @rtype: integer - """ - def getPolygon(index): - """ - Gets the specified polygon from the mesh. - - @type index: integer - @param index: polygon number - @rtype: L{KX_PolyProxy} - @return: a polygon object. - """ - def reinstancePhysicsMesh(): - """ - Updates the physics system with the changed mesh. - - A mesh must have only one material with collision flags, - and have all collision primitives in one vertex array (ie. < 65535 verts) and - be either a polytope or polyheder mesh. If you don't get a warning in the - console when the collision type is polytope, the mesh is suitable for reinstance. - - @rtype: boolean - @return: True if reinstance succeeded, False if it failed. - """ - diff --git a/source/gameengine/PyDoc/KX_MouseFocusSensor.py b/source/gameengine/PyDoc/KX_MouseFocusSensor.py deleted file mode 100644 index 24f7716218b..00000000000 --- a/source/gameengine/PyDoc/KX_MouseFocusSensor.py +++ /dev/null @@ -1,67 +0,0 @@ -# $Id$ -# Documentation for KX_MouseFocusSensor -from SCA_MouseSensor import * - -class KX_MouseFocusSensor(SCA_MouseSensor): - """ - The mouse focus sensor detects when the mouse is over the current game object. - - The mouse focus sensor works by transforming the mouse coordinates from 2d device - space to 3d space then raycasting away from the camera. - - @ivar raySource: The worldspace source of the ray (the view position) - @type raySource: list (vector of 3 floats) - @ivar rayTarget: The worldspace target of the ray. - @type rayTarget: list (vector of 3 floats) - @ivar rayDirection: The L{rayTarget} - L{raySource} normalized. - @type rayDirection: list (normalized vector of 3 floats) - @ivar hitObject: the last object the mouse was over. - @type hitObject: L{KX_GameObject} or None - @ivar hitPosition: The worldspace position of the ray intersecton. - @type hitPosition: list (vector of 3 floats) - @ivar hitNormal: the worldspace normal from the face at point of intersection. - @type hitNormal: list (normalized vector of 3 floats) - """ - - def getHitNormal(): - """ - Returns the normal (in worldcoordinates) at the point of collision where the object was hit by this ray. (B{deprecated}) - - @rtype: list [x, y, z] - @return: the ray collision normal. - """ - def getHitObject(): - """ - Returns the object that was hit by this ray or None. (B{deprecated}) - - @rtype: L{KX_GameObject} or None - @return: the collision object. - """ - def getHitPosition(): - """ - Returns the position (in worldcoordinates) at the point of collision where the object was hit by this ray. (B{deprecated}) - - @rtype: list [x, y, z] - @return: the ray collision position. - """ - def getRayDirection(): - """ - Returns the normalized direction (in worldcoordinates) of the ray cast by the mouse. (B{deprecated}) - - @rtype: list [x, y, z] - @return: the ray direction. - """ - def getRaySource(): - """ - Returns the position (in worldcoordinates) the ray was cast from by the mouse. (B{deprecated}) - - @rtype: list [x, y, z] - @return: the ray source. - """ - def getRayTarget(): - """ - Returns the target of the ray (in worldcoordinates) that seeks the focus object. (B{deprecated}) - - @rtype: list [x, y, z] - @return: the ray target. - """ \ No newline at end of file diff --git a/source/gameengine/PyDoc/KX_NearSensor.py b/source/gameengine/PyDoc/KX_NearSensor.py deleted file mode 100644 index a8c408827fe..00000000000 --- a/source/gameengine/PyDoc/KX_NearSensor.py +++ /dev/null @@ -1,14 +0,0 @@ -# $Id$ -# Documentation for KX_NearSensor -from KX_TouchSensor import * - -class KX_NearSensor(KX_TouchSensor): - """ - A near sensor is a specialised form of touch sensor. - - @ivar distance: The near sensor activates when an object is within this distance. - @type distance: float - @ivar resetDistance: The near sensor deactivates when the object exceeds this distance. - @type resetDistance: float - """ - diff --git a/source/gameengine/PyDoc/KX_NetworkMessageActuator.py b/source/gameengine/PyDoc/KX_NetworkMessageActuator.py deleted file mode 100644 index c9f48d47eb8..00000000000 --- a/source/gameengine/PyDoc/KX_NetworkMessageActuator.py +++ /dev/null @@ -1,49 +0,0 @@ -# $Id$ -# Documentation for KX_NetworkMessageActuator -from SCA_IActuator import * - -class KX_NetworkMessageActuator(SCA_IActuator): - """ - Message Actuator - - @ivar propName: Messages will only be sent to objects with the given property name. - @type propName: string - @ivar subject: The subject field of the message. - @type subject: string - @ivar body: The body of the message. - @type body: string - @ivar usePropBody: Send a property instead of a regular body message. - @type usePropBody: boolean - """ - def setToPropName(name): - """ - DEPRECATED: Use the propName property instead. - Messages will only be sent to objects with the given property name. - - @type name: string - """ - def setSubject(subject): - """ - DEPRECATED: Use the subject property instead. - Sets the subject field of the message. - - @type subject: string - """ - def setBodyType(bodytype): - """ - DEPRECATED: Use the usePropBody property instead. - Sets the type of body to send. - - @type bodytype: boolean - @param bodytype: True to send the value of a property, False to send the body text. - """ - def setBody(body): - """ - DEPRECATED: Use the body property instead. - Sets the message body. - - @type body: string - @param body: if the body type is True, this is the name of the property to send. - if the body type is False, this is the text to send. - """ - diff --git a/source/gameengine/PyDoc/KX_NetworkMessageSensor.py b/source/gameengine/PyDoc/KX_NetworkMessageSensor.py deleted file mode 100644 index 0fecad58437..00000000000 --- a/source/gameengine/PyDoc/KX_NetworkMessageSensor.py +++ /dev/null @@ -1,60 +0,0 @@ -# $Id$ -# Documentation for KX_NetworkMessageSensor -from SCA_ISensor import * - -class KX_NetworkMessageSensor(SCA_ISensor): - """ - The Message Sensor logic brick. - - Currently only loopback (local) networks are supported. - - @ivar subject: The subject the sensor is looking for. - @type subject: string - @ivar frameMessageCount: The number of messages received since the last frame. - (Read-only) - @type framemessageCount: int - @ivar subjects: The list of message subjects received. (Read-only) - @type subjects: list of strings - @ivar bodies: The list of message bodies received. (Read-only) - @type bodies: list of strings - """ - - - def setSubjectFilterText(subject): - """ - DEPRECATED: Use the subject property instead. - Change the message subject text that this sensor is listening to. - - @type subject: string - @param subject: the new message subject to listen for. - """ - - def getFrameMessageCount(): - """ - DEPRECATED: Use the frameMessageCount property instead. - Get the number of messages received since the last frame. - - @rtype: integer - """ - def getBodies(): - """ - DEPRECATED: Use the bodies property instead. - Gets the list of message bodies. - - @rtype: list - """ - def getSubject(): - """ - DEPRECATED: Use the subject property instead. - Gets the message subject this sensor is listening for from the Subject: field. - - @rtype: string - """ - def getSubjects(): - """ - DEPRECATED: Use the subjects property instead. - Gets the list of message subjects received. - - @rtype: list - """ - \ No newline at end of file diff --git a/source/gameengine/PyDoc/KX_ObjectActuator.py b/source/gameengine/PyDoc/KX_ObjectActuator.py deleted file mode 100644 index b7b76473292..00000000000 --- a/source/gameengine/PyDoc/KX_ObjectActuator.py +++ /dev/null @@ -1,250 +0,0 @@ -# $Id$ -# Documentation for KX_ObjectActuator -from SCA_IActuator import * - -class KX_ObjectActuator(SCA_IActuator): - """ - The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement, - velocity, or angular velocity to an object. - Servo control allows to regulate force to achieve a certain speed target. - """ - def getForce(): - """ - Returns the force applied by the actuator. - - @rtype: list [fx, fy, fz, local] - @return: A four item list, containing the vector force, and a flag specifying whether the force is local. - """ - def setForce(fx, fy, fz, local): - """ - Sets the force applied by the actuator. - - @type fx: float - @param fx: the x component of the force. - @type fy: float - @param fy: the z component of the force. - @type fz: float - @param fz: the z component of the force. - @type local: boolean - @param local: - False: the force is applied in world coordinates. - - True: the force is applied in local coordinates. - """ - def getTorque(): - """ - Returns the torque applied by the actuator. - - @rtype: list [S{Tau}x, S{Tau}y, S{Tau}z, local] - @return: A four item list, containing the vector torque, and a flag specifying whether - the torque is applied in local coordinates (True) or world coordinates (False) - """ - def setTorque(tx, ty, tz, local): - """ - Sets the torque applied by the actuator. - - @type tx: float - @param tx: the x component of the torque. - @type ty: float - @param ty: the z component of the torque. - @type tz: float - @param tz: the z component of the torque. - @type local: boolean - @param local: - False: the torque is applied in world coordinates. - - True: the torque is applied in local coordinates. - """ - def getDLoc(): - """ - Returns the displacement vector applied by the actuator. - - @rtype: list [dx, dy, dz, local] - @return: A four item list, containing the vector displacement, and whether - the displacement is applied in local coordinates (True) or world - coordinates (False) - """ - def setDLoc(dx, dy, dz, local): - """ - Sets the displacement vector applied by the actuator. - - Since the displacement is applied every frame, you must adjust the displacement - based on the frame rate, or you game experience will depend on the player's computer - speed. - - @type dx: float - @param dx: the x component of the displacement vector. - @type dy: float - @param dy: the z component of the displacement vector. - @type dz: float - @param dz: the z component of the displacement vector. - @type local: boolean - @param local: - False: the displacement vector is applied in world coordinates. - - True: the displacement vector is applied in local coordinates. - """ - def getDRot(): - """ - Returns the angular displacement vector applied by the actuator. - - @rtype: list [dx, dy, dz, local] - @return: A four item list, containing the angular displacement vector, and whether - the displacement is applied in local coordinates (True) or world - coordinates (False) - """ - def setDRot(dx, dy, dz, local): - """ - Sets the angular displacement vector applied by the actuator. - - Since the displacement is applied every frame, you must adjust the displacement - based on the frame rate, or you game experience will depend on the player's computer - speed. - - @type dx: float - @param dx: the x component of the angular displacement vector. - @type dy: float - @param dy: the z component of the angular displacement vector. - @type dz: float - @param dz: the z component of the angular displacement vector. - @type local: boolean - @param local: - False: the angular displacement vector is applied in world coordinates. - - True: the angular displacement vector is applied in local coordinates. - """ - def getLinearVelocity(): - """ - Returns the linear velocity applied by the actuator. - For the servo control actuator, this is the target speed. - - @rtype: list [vx, vy, vz, local] - @return: A four item list, containing the vector velocity, and whether the velocity is applied in local coordinates (True) or world coordinates (False) - """ - def setLinearVelocity(vx, vy, vz, local): - """ - Sets the linear velocity applied by the actuator. - For the servo control actuator, sets the target speed. - - @type vx: float - @param vx: the x component of the velocity vector. - @type vy: float - @param vy: the z component of the velocity vector. - @type vz: float - @param vz: the z component of the velocity vector. - @type local: boolean - @param local: - False: the velocity vector is in world coordinates. - - True: the velocity vector is in local coordinates. - """ - def getAngularVelocity(): - """ - Returns the angular velocity applied by the actuator. - - @rtype: list [S{omega}x, S{omega}y, S{omega}z, local] - @return: A four item list, containing the vector velocity, and whether - the velocity is applied in local coordinates (True) or world - coordinates (False) - """ - def setAngularVelocity(wx, wy, wz, local): - """ - Sets the angular velocity applied by the actuator. - - @type wx: float - @param wx: the x component of the velocity vector. - @type wy: float - @param wy: the z component of the velocity vector. - @type wz: float - @param wz: the z component of the velocity vector. - @type local: boolean - @param local: - False: the velocity vector is applied in world coordinates. - - True: the velocity vector is applied in local coordinates. - """ - def getDamping(): - """ - Returns the damping parameter of the servo controller. - - @rtype: integer - @return: the time constant of the servo controller in frame unit. - """ - def setDamping(damp): - """ - Sets the damping parameter of the servo controller. - - @type damp: integer - @param damp: the damping parameter in frame unit. - """ - def getForceLimitX(): - """ - Returns the min/max force limit along the X axis used by the servo controller. - - @rtype: list [min, max, enabled] - @return: A three item list, containing the min and max limits of the force as float - and whether the limits are active(true) or inactive(true) - """ - def setForceLimitX(min, max, enable): - """ - Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller. - - @type min: float - @param min: the minimum value of the force along the X axis. - @type max: float - @param max: the maximum value of the force along the X axis. - @type enable: boolean - @param enable: - True: the force will be limited to the min/max - - False: the force will not be limited - """ - def getForceLimitY(): - """ - Returns the min/max force limit along the Y axis used by the servo controller. - - @rtype: list [min, max, enabled] - @return: A three item list, containing the min and max limits of the force as float - and whether the limits are active(true) or inactive(true) - """ - def setForceLimitY(min, max, enable): - """ - Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller. - - @type min: float - @param min: the minimum value of the force along the Y axis. - @type max: float - @param max: the maximum value of the force along the Y axis. - @type enable: boolean - @param enable: - True: the force will be limited to the min/max - - False: the force will not be limited - """ - def getForceLimitZ(): - """ - Returns the min/max force limit along the Z axis used by the servo controller. - - @rtype: list [min, max, enabled] - @return: A three item list, containing the min and max limits of the force as float - and whether the limits are active(true) or inactive(true) - """ - def setForceLimitZ(min, max, enable): - """ - Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller. - - @type min: float - @param min: the minimum value of the force along the Z axis. - @type max: float - @param max: the maximum value of the force along the Z axis. - @type enable: boolean - @param enable: - True: the force will be limited to the min/max - - False: the force will not be limited - """ - def getPID(): - """ - Returns the PID coefficient of the servo controller. - - @rtype: list [P, I, D] - @return: A three item list, containing the PID coefficient as floats: - P : proportional coefficient - I : Integral coefficient - D : Derivate coefficient - """ - def setPID(P, I, D): - """ - Sets the PID coefficients of the servo controller. - - @type P: flat - @param P: proportional coefficient - @type I: float - @param I: Integral coefficient - @type D: float - @param D: Derivate coefficient - """ - - diff --git a/source/gameengine/PyDoc/KX_ParentActuator.py b/source/gameengine/PyDoc/KX_ParentActuator.py deleted file mode 100644 index 1e2bfe60a4f..00000000000 --- a/source/gameengine/PyDoc/KX_ParentActuator.py +++ /dev/null @@ -1,29 +0,0 @@ -# $Id$ -# Documentation for KX_ParentActuator -from SCA_IActuator import * - -class KX_ParentActuator(SCA_IActuator): - """ - The parent actuator can set or remove an objects parent object. - @ivar object: the object this actuator sets the parent too. - @type object: KX_GameObject or None - @ivar mode: The mode of this actuator - @type mode: int from 0 to 1 L{GameLogic.Parent Actuator} - """ - def setObject(object): - """ - DEPRECATED: Use the object property. - Sets the object to set as parent. - - Object can be either a L{KX_GameObject} or the name of the object. - - @type object: L{KX_GameObject}, string or None - """ - def getObject(name_only = 1): - """ - DEPRECATED: Use the object property. - Returns the name of the object to change to. - @type name_only: bool - @param name_only: optional argument, when 0 return a KX_GameObject - @rtype: string, KX_GameObject or None if no object is set - """ diff --git a/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py b/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py deleted file mode 100644 index 4cbdbf7cebb..00000000000 --- a/source/gameengine/PyDoc/KX_PhysicsObjectWrapper.py +++ /dev/null @@ -1,60 +0,0 @@ -from PyObjectPlus import * - -class KX_PhysicsObjectWrapper(PyObjectPlus): - """ - KX_PhysicsObjectWrapper - - """ - def setActive(active): - """ - Set the object to be active. - - @param active: set to True to be active - @type active: bool - """ - - def setAngularVelocity(x, y, z, local): - """ - Set the angular velocity of the object. - - @param x: angular velocity for the x-axis - @type x: float - - @param y: angular velocity for the y-axis - @type y: float - - @param z: angular velocity for the z-axis - @type z: float - - @param local: set to True for local axis - @type local: bool - """ - def setLinearVelocity(x, y, z, local): - """ - Set the linear velocity of the object. - - @param x: linear velocity for the x-axis - @type x: float - - @param y: linear velocity for the y-axis - @type y: float - - @param z: linear velocity for the z-axis - @type z: float - - @param local: set to True for local axis - @type local: bool - """ - def setPosition(x, y, z): - """ - Set the position of the object - - @param x: x coordinate - @type x: float - - @param y: y coordinate - @type y: float - - @param z: z coordinate - @type z: float - """ diff --git a/source/gameengine/PyDoc/KX_PolyProxy.py b/source/gameengine/PyDoc/KX_PolyProxy.py deleted file mode 100644 index 2d1c1f9b218..00000000000 --- a/source/gameengine/PyDoc/KX_PolyProxy.py +++ /dev/null @@ -1,101 +0,0 @@ -# $Id$ -# Documentation for the polygon proxy class -from SCA_IObject import * - -class KX_PolyProxy(SCA_IObject): - """ - A polygon holds the index of the vertex forming the poylgon. - - Note: - The polygon attributes are read-only, you need to retrieve the vertex proxy if you want - to change the vertex settings. - - @ivar matname: The name of polygon material, empty if no material. - @type matname: string - @ivar material: The material of the polygon - @type material: L{KX_PolygonMaterial} or KX_BlenderMaterial - @ivar texture: The texture name of the polygon. - @type texture: string - @ivar matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy - @type matid: integer - @ivar v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy - @type v1: integer - @ivar v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy - @type v2: integer - @ivar v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy - @type v3: integer - @ivar v4: vertex index of the fourth vertex of the polygon, 0 if polygon has only 3 vertex - use this to retrieve vertex proxy from mesh proxy - @type v4: integer - @ivar visible: visible state of the polygon: 1=visible, 0=invisible - @type visible: integer - @ivar collide: collide state of the polygon: 1=receives collision, 0=collision free. - @type collide: integer - """ - - def getMaterialName(): - """ - Returns the polygon material name with MA prefix - - @rtype: string - @return: material name - """ - def getMaterial(): - """ - Returns the polygon material - - @rtype: L{KX_PolygonMaterial} or KX_BlenderMaterial - """ - def getTextureName(): - """ - Returns the polygon texture name - - @rtype: string - @return: texture name - """ - def getMaterialIndex(): - """ - Returns the material bucket index of the polygon. - This index and the ones returned by getVertexIndex() are needed to retrieve the vertex proxy from L{KX_MeshProxy}. - - @rtype: integer - @return: the material index in the mesh - """ - def getNumVertex(): - """ - Returns the number of vertex of the polygon. - - @rtype: integer - @return: number of vertex, 3 or 4. - """ - def isVisible(): - """ - Returns whether the polygon is visible or not - - @rtype: integer - @return: 0=invisible, 1=visible - """ - def isCollider(): - """ - Returns whether the polygon is receives collision or not - - @rtype: integer - @return: 0=collision free, 1=receives collision - """ - def getVertexIndex(vertex): - """ - Returns the mesh vertex index of a polygon vertex - This index and the one returned by getMaterialIndex() are needed to retrieve the vertex proxy from L{KX_MeshProxy}. - - @type vertex: integer - @param vertex: index of the vertex in the polygon: 0->3 - @rtype: integer - @return: mesh vertex index - """ - def getMesh(): - """ - Returns a mesh proxy - - @rtype: L{KX_MeshProxy} - @return: mesh proxy - """ diff --git a/source/gameengine/PyDoc/KX_PolygonMaterial.py b/source/gameengine/PyDoc/KX_PolygonMaterial.py deleted file mode 100644 index cfc4257f95d..00000000000 --- a/source/gameengine/PyDoc/KX_PolygonMaterial.py +++ /dev/null @@ -1,281 +0,0 @@ -# $Id$ - -class KX_PolygonMaterial: - """ - This is the interface to materials in the game engine. - - Materials define the render state to be applied to mesh objects. - - Warning: Some of the methods/variables are CObjects. If you mix these up, - you will crash blender. - - This example requires: - - PyOpenGL http://pyopengl.sourceforge.net/ - - GLEWPy http://glewpy.sourceforge.net/ - Example:: - - import GameLogic - import OpenGL - from OpenGL.GL import * - from OpenGL.GLU import * - import glew - from glew import * - - glewInit() - - vertex_shader = \"\"\" - - void main(void) - { - gl_Position = ftransform(); - } - \"\"\" - - fragment_shader =\"\"\" - - void main(void) - { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); - } - \"\"\" - - class MyMaterial: - def __init__(self): - self.pass_no = 0 - # Create a shader - self.m_program = glCreateProgramObjectARB() - # Compile the vertex shader - self.shader(GL_VERTEX_SHADER_ARB, (vertex_shader)) - # Compile the fragment shader - self.shader(GL_FRAGMENT_SHADER_ARB, (fragment_shader)) - # Link the shaders together - self.link() - - def PrintInfoLog(self, tag, object): - \"\"\" - PrintInfoLog prints the GLSL compiler log - \"\"\" - print "Tag: def PrintGLError(self, tag = ""): - - def PrintGLError(self, tag = ""): - \"\"\" - Prints the current GL error status - \"\"\" - if len(tag): - print tag - err = glGetError() - if err != GL_NO_ERROR: - print "GL Error: %s\\n"%(gluErrorString(err)) - - def shader(self, type, shaders): - \"\"\" - shader compiles a GLSL shader and attaches it to the current - program. - - type should be either GL_VERTEX_SHADER_ARB or GL_FRAGMENT_SHADER_ARB - shaders should be a sequence of shader source to compile. - \"\"\" - # Create a shader object - shader_object = glCreateShaderObjectARB(type) - - # Add the source code - glShaderSourceARB(shader_object, len(shaders), shaders) - - # Compile the shader - glCompileShaderARB(shader_object) - - # Print the compiler log - self.PrintInfoLog("vertex shader", shader_object) - - # Check if compiled, and attach if it did - compiled = glGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB) - if compiled: - glAttachObjectARB(self.m_program, shader_object) - - # Delete the object (glAttachObjectARB makes a copy) - glDeleteObjectARB(shader_object) - - # print the gl error log - self.PrintGLError() - - def link(self): - \"\"\" - Links the shaders together. - \"\"\" - # clear error indicator - glGetError() - - glLinkProgramARB(self.m_program) - - self.PrintInfoLog("link", self.m_program) - - linked = glGetObjectParameterivARB(self.m_program, GL_OBJECT_LINK_STATUS_ARB) - if not linked: - print "Shader failed to link" - return - - glValidateProgramARB(self.m_program) - valid = glGetObjectParameterivARB(self.m_program, GL_OBJECT_VALIDATE_STATUS_ARB) - if not valid: - print "Shader failed to validate" - return - - def activate(self, rasty, cachingInfo, mat): - self.pass_no+=1 - if (self.pass_no == 1): - glDisable(GL_COLOR_MATERIAL) - glUseProgramObjectARB(self.m_program) - return True - - glEnable(GL_COLOR_MATERIAL) - glUseProgramObjectARB(0) - self.pass_no = 0 - return False - - obj = GameLogic.getCurrentController().getOwner() - - mesh = obj.getMesh(0) - - for mat in mesh.materials: - mat.setCustomMaterial(MyMaterial()) - print mat.texture - - @ivar texture: Texture name - @type texture: string (read only) - - @ivar gl_texture: OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture) - @type gl_texture: integer (read only) - - @ivar material: Material name - @type material: string (read only) - - @ivar tface: Texture face properties - @type tface: CObject (read only) - - @ivar tile: Texture is tiling - @type tile: boolean - @ivar tilexrep: Number of tile repetitions in x direction. - @type tilexrep: integer - @ivar tileyrep: Number of tile repetitions in y direction. - @type tileyrep: integer - - @ivar drawingmode: Drawing mode for the material. - - 2 (drawingmode & 4) Textured - - 4 (drawingmode & 16) Light - - 14 (drawingmode & 16384) 3d Polygon Text - @type drawingmode: bitfield - - @ivar transparent: This material is transparent. All meshes with this - material will be rendered after non transparent meshes from back - to front. - @type transparent: boolean - - @ivar zsort: Transparent polygons in meshes with this material will be sorted back to - front before rendering. - Non-Transparent polygons will be sorted front to back before rendering. - @type zsort: boolean - - @ivar lightlayer: Light layers this material affects. - @type lightlayer: bitfield. - - @ivar triangle: Mesh data with this material is triangles. It's probably not safe to change this. - @type triangle: boolean - - @ivar diffuse: The diffuse colour of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0] - @type diffuse: list [r, g, b] - @ivar specular: The specular colour of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0] - @type specular: list [r, g, b] - @ivar shininess: The shininess (specular exponent) of the material. 0.0 <= shininess <= 128.0 - @type shininess: float - @ivar specularity: The amount of specular of the material. 0.0 <= specularity <= 1.0 - @type specularity: float - """ - def updateTexture(tface, rasty): - """ - Updates a realtime animation. - - @param tface: Texture face (eg mat.tface) - @type tface: CObject - @param rasty: Rasterizer - @type rasty: CObject - """ - def setTexture(tface): - """ - Sets texture render state. - - Example:: - mat.setTexture(mat.tface) - - @param tface: Texture face - @type tface: CObject - """ - def activate(rasty, cachingInfo): - """ - Sets material parameters for this object for rendering. - - Material Parameters set: - 1. Texture - 2. Backface culling - 3. Line drawing - 4. Specular Colour - 5. Shininess - 6. Diffuse Colour - 7. Polygon Offset. - - @param rasty: Rasterizer instance. - @type rasty: CObject - @param cachingInfo: Material cache instance. - @type cachingInfo: CObject - """ - def setCustomMaterial(material): - """ - Sets the material state setup object. - - Using this method, you can extend or completely replace the gameengine material - to do your own advanced multipass effects. - - Use this method to register your material class. Instead of the normal material, - your class's activate method will be called just before rendering the mesh. - This should setup the texture, material, and any other state you would like. - It should return True to render the mesh, or False if you are finished. You should - clean up any state Blender does not set before returning False. - - Activate Method Definition:: - def activate(self, rasty, cachingInfo, material): - - Example:: - class PyMaterial: - def __init__(self): - self.pass_no = -1 - - def activate(self, rasty, cachingInfo, material): - # Activate the material here. - # - # The activate method will be called until it returns False. - # Every time the activate method returns True the mesh will - # be rendered. - # - # rasty is a CObject for passing to material.updateTexture() - # and material.activate() - # cachingInfo is a CObject for passing to material.activate() - # material is the KX_PolygonMaterial instance this material - # was added to - - # default material properties: - self.pass_no += 1 - if self.pass_no == 0: - material.activate(rasty, cachingInfo) - # Return True to do this pass - return True - - # clean up and return False to finish. - self.pass_no = -1 - return False - - # Create a new Python Material and pass it to the renderer. - mat.setCustomMaterial(PyMaterial()) - - @param material: The material object. - @type material: instance - """ - diff --git a/source/gameengine/PyDoc/KX_RadarSensor.py b/source/gameengine/PyDoc/KX_RadarSensor.py deleted file mode 100644 index b68bf4ea0f3..00000000000 --- a/source/gameengine/PyDoc/KX_RadarSensor.py +++ /dev/null @@ -1,49 +0,0 @@ -# $Id$ -# Documentation for KX_RadarSensor -from KX_NearSensor import * - -class KX_RadarSensor(KX_NearSensor): - """ - Radar sensor is a near sensor with a conical sensor object. - - @ivar coneOrigin: The origin of the cone with which to test. The origin - is in the middle of the cone. - (Read only) - @type coneOrigin: list of floats [x, y, z] - @ivar coneTarget: The center of the bottom face of the cone with which to test. - (Read only) - @type coneTarget: list of floats [x, y, z] - @ivar distance: The height of the cone with which to test. - @type distance: float - @ivar angle: The angle of the cone (in degrees) with which to test. - @type angle: float from 0 to 360 - @ivar axis: The axis on which the radar cone is cast - @type axis: int from 0 to 5 - KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, - KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z - """ - - - #--The following methods are deprecated, please use properties instead. - def getConeOrigin(): - """ - Returns the origin of the cone with which to test. The origin - is in the middle of the cone. - - @rtype: list [x, y, z] - """ - - def getConeTarget(): - """ - Returns the center of the bottom face of the cone with which to test. - - @rtype: list [x, y, z] - """ - - def getConeHeight(): - """ - Returns the height of the cone with which to test. - - @rtype: float - """ - diff --git a/source/gameengine/PyDoc/KX_RaySensor.py b/source/gameengine/PyDoc/KX_RaySensor.py deleted file mode 100644 index b9de54e92a5..00000000000 --- a/source/gameengine/PyDoc/KX_RaySensor.py +++ /dev/null @@ -1,58 +0,0 @@ -# $Id$ -# Documentation for KX_RaySensor -from SCA_ISensor import * - -class KX_RaySensor(SCA_ISensor): - """ - A ray sensor detects the first object in a given direction. - - @ivar property: The property the ray is looking for. - @type property: string - @ivar range: The distance of the ray. - @type range: float - @ivar useMaterial: Whether or not to look for a material (false = property) - @type useMaterial: boolean - @ivar useXRay: Whether or not to use XRay. - @type useXRay: boolean - @ivar hitObject: The game object that was hit by the ray. (Read-only) - @type hitObject: KX_GameObject - @ivar hitPosition: The position (in worldcoordinates) where the object was hit by the ray. (Read-only) - @type hitPosition: list [x, y, z] - @ivar hitNormal: The normal (in worldcoordinates) of the object at the location where the object was hit by the ray. (Read-only) - @type hitNormal: list [x, y, z] - @ivar rayDirection: The direction from the ray (in worldcoordinates). (Read-only) - @type rayDirection: list [x, y, z] - @ivar axis: The axis the ray is pointing on. - @type axis: int from 0 to 5 - KX_RAY_AXIS_POS_X, KX_RAY_AXIS_POS_Y, KX_RAY_AXIS_POS_Z, - KX_RAY_AXIS_NEG_X, KX_RAY_AXIS_NEG_Y, KX_RAY_AXIS_NEG_Z - """ - - def getHitObject(): - """ - DEPRECATED: Use the hitObject property instead. - Returns the game object that was hit by this ray. - - @rtype: KX_GameObject - """ - def getHitPosition(): - """ - DEPRECATED: Use the hitPosition property instead. - Returns the position (in worldcoordinates) where the object was hit by this ray. - - @rtype: list [x, y, z] - """ - def getHitNormal(): - """ - DEPRECATED: Use the hitNormal property instead. - Returns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray. - - @rtype: list [nx, ny, nz] - """ - def getRayDirection(): - """ - DEPRECATED: Use the rayDirection property instead. - Returns the direction from the ray (in worldcoordinates) - - @rtype: list [dx, dy, dz] - """ diff --git a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py deleted file mode 100644 index 572b864ff0a..00000000000 --- a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py +++ /dev/null @@ -1,118 +0,0 @@ -# $Id$ -# Documentation for KX_SCA_AddObjectActuator -from SCA_IActuator import * - -class KX_SCA_AddObjectActuator(SCA_IActuator): - """ - Edit Object Actuator (in Add Object Mode) - @ivar object: the object this actuator adds. - @type object: KX_GameObject or None - @ivar objectLastCreated: the last added object from this actuator (read only). - @type objectLastCreated: KX_GameObject or None - @ivar time: the lifetime of added objects, in frames. - @type time: integer - @ivar linearVelocity: the initial linear velocity of added objects. - @type linearVelocity: list [vx, vy, vz] - @ivar angularVelocity: the initial angular velocity of added objects. - @type angularVelocity: list [vx, vy, vz] - - @warning: An Add Object actuator will be ignored if at game start, the linked object doesn't exist - (or is empty) or the linked object is in an active layer. - - This will genereate a warning in the console: - - C{ERROR: GameObject I{OBName} has a AddObjectActuator I{ActuatorName} without object (in 'nonactive' layer)} - """ - def setObject(object): - """ - DEPRECATED: use the object property - Sets the game object to add. - - A copy of the object will be added to the scene when the actuator is activated. - - If the object does not exist, this function is ignored. - - object can either be a L{KX_GameObject} or the name of an object or None. - - @type object: L{KX_GameObject}, string or None - """ - def getObject(name_only = 0): - """ - DEPRECATED: use the object property - Returns the name of the game object to be added. - - Returns None if no game object has been assigned to be added. - @type name_only: bool - @param name_only: optional argument, when 0 return a KX_GameObject - @rtype: string, KX_GameObject or None if no object is set - """ - def setTime(time): - """ - DEPRECATED: use the time property - Sets the lifetime of added objects, in frames. - - If time == 0, the object will last forever. - - @type time: integer - @param time: The minimum value for time is 0. - """ - def getTime(): - """ - DEPRECATED: use the time property - Returns the lifetime of the added object, in frames. - - @rtype: integer - """ - def setLinearVelocity(vx, vy, vz): - """ - DEPRECATED: use the linearVelocity property - Sets the initial linear velocity of added objects. - - @type vx: float - @param vx: the x component of the initial linear velocity. - @type vy: float - @param vy: the y component of the initial linear velocity. - @type vz: float - @param vz: the z component of the initial linear velocity. - """ - def getLinearVelocity(): - """ - DEPRECATED: use the linearVelocity property - Returns the initial linear velocity of added objects. - - @rtype: list [vx, vy, vz] - """ - def setAngularVelocity(vx, vy, vz): - """ - DEPRECATED: use the angularVelocity property - Sets the initial angular velocity of added objects. - - @type vx: float - @param vx: the x component of the initial angular velocity. - @type vy: float - @param vy: the y component of the initial angular velocity. - @type vz: float - @param vz: the z component of the initial angular velocity. - """ - def getAngularVelocity(): - """ - DEPRECATED: use the angularVelocity property - Returns the initial angular velocity of added objects. - - @rtype: list [vx, vy, vz] - """ - def getLastCreatedObject(): - """ - DEPRECATED: use the objectLastCreated property - Returns the last object created by this actuator. - - @rtype: L{KX_GameObject} - @return: A L{KX_GameObject} or None if no object has been created. - """ - def instantAddObject(): - """ - Returns the last object created by this actuator. The object can then be accessed from L{objectLastCreated}. - - @rtype: None - """ - diff --git a/source/gameengine/PyDoc/KX_SCA_DynamicActuator.py b/source/gameengine/PyDoc/KX_SCA_DynamicActuator.py deleted file mode 100644 index 22da159ce71..00000000000 --- a/source/gameengine/PyDoc/KX_SCA_DynamicActuator.py +++ /dev/null @@ -1,30 +0,0 @@ -# $Id$ -# Documentation for KX_SCA_DynamicActuator -from SCA_IActuator import * - -class KX_SCA_DynamicActuator(SCA_IActuator): - """ - Dynamic Actuator. - @ivar operation: the type of operation of the actuator, 0-4 - KX_DYN_RESTORE_DYNAMICS, KX_DYN_DISABLE_DYNAMICS, - KX_DYN_ENABLE_RIGID_BODY, KX_DYN_DISABLE_RIGID_BODY, KX_DYN_SET_MASS - @type operation: integer - @ivar mass: the mass value for the KX_DYN_SET_MASS operation - @type mass: float - """ - def setOperation(operation): - """ - DEPRECATED: Use the operation property instead. - Set the type of operation when the actuator is activated: - - 0 = restore dynamics - - 1 = disable dynamics - - 2 = enable rigid body - - 3 = disable rigid body - - 4 = set mass - """ - def getOperation(): - """ - DEPRECATED: Use the operation property instead. - return the type of operation - """ - diff --git a/source/gameengine/PyDoc/KX_SCA_EndObjectActuator.py b/source/gameengine/PyDoc/KX_SCA_EndObjectActuator.py deleted file mode 100644 index 8a7c79bb52b..00000000000 --- a/source/gameengine/PyDoc/KX_SCA_EndObjectActuator.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for KX_SCA_EndObjectActuator -from SCA_IActuator import * - -class KX_SCA_EndObjectActuator(SCA_IActuator): - """ - Edit Object Actuator (in End Object mode) - - This actuator has no python methods. - """ - diff --git a/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py b/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py deleted file mode 100644 index 951c118a99a..00000000000 --- a/source/gameengine/PyDoc/KX_SCA_ReplaceMeshActuator.py +++ /dev/null @@ -1,84 +0,0 @@ -# $Id$ -# Documentation for KX_SCA_ReplaceMeshActuator -from SCA_IActuator import * - -class KX_SCA_ReplaceMeshActuator(SCA_IActuator): - """ - Edit Object actuator, in Replace Mesh mode. - - Example:: - # Level-of-detail - # Switch a game object's mesh based on its depth in the camera view. - # +----------+ +-----------+ +-------------------------------------+ - # | Always +-----+ Python +-----+ Edit Object (Replace Mesh) LOD.Mesh | - # +----------+ +-----------+ +-------------------------------------+ - import GameLogic - - # List detail meshes here - # Mesh (name, near, far) - # Meshes overlap so that they don't 'pop' when on the edge of the distance. - meshes = ((".Hi", 0.0, -20.0), - (".Med", -15.0, -50.0), - (".Lo", -40.0, -100.0) - ) - - co = GameLogic.getCurrentController() - obj = co.getOwner() - act = co.getActuator("LOD." + obj.name) - cam = GameLogic.getCurrentScene().active_camera - - def Depth(pos, plane): - return pos[0]*plane[0] + pos[1]*plane[1] + pos[2]*plane[2] + plane[3] - - # Depth is negative and decreasing further from the camera - depth = Depth(obj.position, cam.world_to_camera[2]) - - newmesh = None - curmesh = None - # Find the lowest detail mesh for depth - for mesh in meshes: - if depth < mesh[1] and depth > mesh[2]: - newmesh = mesh - if "ME" + obj.name + mesh[0] == act.getMesh(): - curmesh = mesh - - if newmesh != None and "ME" + obj.name + newmesh[0] != act.getMesh(): - # The mesh is a different mesh - switch it. - # Check the current mesh is not a better fit. - if curmesh == None or curmesh[1] < depth or curmesh[2] > depth: - act.setMesh(obj.getName() + newmesh[0]) - GameLogic.addActiveActuator(act, True) - - @warning: Replace mesh actuators will be ignored if at game start, the - named mesh doesn't exist. - - This will generate a warning in the console: - - C{ERROR: GameObject I{OBName} ReplaceMeshActuator I{ActuatorName} without object} - - @ivar mesh: L{KX_MeshProxy} or the name of the mesh that will replace the current one - Set to None to disable actuator - @type mesh: L{KX_MeshProxy} or None if no mesh is set - """ - def setMesh(name): - """ - DEPRECATED: Use the mesh property instead. - Sets the name of the mesh that will replace the current one. - When the name is None it will unset the mesh value so no action is taken. - - @type name: string or None - """ - def getMesh(): - """ - DEPRECATED: Use the mesh property instead. - Returns the name of the mesh that will replace the current one. - - Returns None if no mesh has been scheduled to be added. - - @rtype: string or None - """ - def instantReplaceMesh(): - """ - Immediately replace mesh without delay. - @rtype: None - """ \ No newline at end of file diff --git a/source/gameengine/PyDoc/KX_Scene.py b/source/gameengine/PyDoc/KX_Scene.py deleted file mode 100644 index 4fe150be898..00000000000 --- a/source/gameengine/PyDoc/KX_Scene.py +++ /dev/null @@ -1,97 +0,0 @@ -# $Id$ -# Documentation for KX_Scene.py - -from PyObjectPlus import * - -class KX_Scene(PyObjectPlus): - """ - Scene. - - The activity culling stuff is supposed to disable logic bricks when their owner gets too far - from the active camera. It was taken from some code lurking at the back of KX_Scene - who knows - what it does! - - Example:: - import GameLogic - - # get the scene - scene = GameLogic.getCurrentScene() - - # print all the objects in the scene - for obj in scene.objects: - print obj.name - - # get an object named 'Cube' - obj = scene.objects["OBCube"] - - # get the first object in the scene. - obj = scene.objects[0] - - Example:: - # Get the depth of an object in the camera view. - import GameLogic - - obj = GameLogic.getCurrentController().getOwner() - cam = GameLogic.getCurrentScene().active_camera - - # Depth is negative and decreasing further from the camera - depth = obj.position[0]*cam.world_to_camera[2][0] + obj.position[1]*cam.world_to_camera[2][1] + obj.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3] - - @bug: All attributes are read only at the moment. - - @ivar name: The scene's name - @type name: string - @ivar objects: A list of objects in the scene. - @type objects: L{CListValue} of L{KX_GameObject} - @ivar objects_inactive: A list of objects on background layers (used for the addObject actuator). - @type objects_inactive: L{CListValue} of L{KX_GameObject} - @ivar lights: A list of lights in the scene. - @type lights: L{CListValue} of L{KX_GameObject} - @ivar cameras: A list of cameras in the scene. - @type cameras: L{CListValue} of L{KX_GameObject} - @ivar active_camera: The current active camera - @type active_camera: L{KX_Camera} - @ivar suspended: True if the scene is suspended. - @type suspended: boolean - @ivar activity_culling: True if the scene is activity culling - @type activity_culling: boolean - @ivar activity_culling_radius: The distance outside which to do activity culling. Measured in manhattan distance. - @type activity_culling_radius: float - @group Deprecated: getLightList, getObjectList, getName - """ - - def getLightList(): - """ - DEPRECATED: use the 'lights' property. - Returns the list of lights in the scene. - - @rtype: list [L{KX_LightObject}] - """ - def getObjectList(): - """ - DEPRECATED: use the 'objects' property. - Returns the list of objects in the scene. - - @rtype: list [L{KX_GameObject}] - """ - def getName(): - """ - DEPRECATED: use the 'name' property. - Returns the name of the scene. - - @rtype: string - """ - - def addObject(object, other, time=0): - """ - Adds an object to the scene like the Add Object Actuator would, and returns the created object. - - @param object: The object to add - @type object: L{KX_GameObject} or string - @param other: The object's center to use when adding the object - @type other: L{KX_GameObject} or string - @param time: The lifetime of the added object, in frames. A time of 0 means the object will last forever. - @type time: int - - @rtype: L{KX_GameObject} - """ diff --git a/source/gameengine/PyDoc/KX_SceneActuator.py b/source/gameengine/PyDoc/KX_SceneActuator.py deleted file mode 100644 index 937c94c91e6..00000000000 --- a/source/gameengine/PyDoc/KX_SceneActuator.py +++ /dev/null @@ -1,71 +0,0 @@ -# $Id$ -# Documentation for KX_SceneActuator -from SCA_IActuator import * - -class KX_SceneActuator(SCA_IActuator): - """ - Scene Actuator logic brick. - - @warning: Scene actuators that use a scene name will be ignored if at game start, the - named scene doesn't exist or is empty - - This will generate a warning in the console: - - C{ERROR: GameObject I{OBName} has a SceneActuator I{ActuatorName} (SetScene) without scene} - - @ivar scene: the name of the scene to change to/overlay/underlay/remove/suspend/resume - @type scene: string. - @ivar camera: the camera to change to. - When setting the attribute, you can use either a L{KX_Camera} or the name of the camera. - @type camera: L{KX_Camera} on read, string or L{KX_Camera} on write - @ivar useRestart: Set flag to True to restart the sene - @type useRestart: bool - @ivar mode: The mode of the actuator - @type mode: int from 0 to 5 L{GameLogic.Scene Actuator} - """ - def setUseRestart(flag): - """ - DEPRECATED: use the useRestart property instead - Set flag to True to restart the scene. - - @type flag: boolean - """ - def setScene(scene): - """ - DEPRECATED: use the scene property instead - Sets the name of the scene to change to/overlay/underlay/remove/suspend/resume. - - @type scene: string - """ - def setCamera(camera): - """ - DEPRECATED: use the camera property instead - Sets the camera to change to. - - Camera can be either a L{KX_Camera} or the name of the camera. - - @type camera: L{KX_Camera} or string - """ - def getUseRestart(): - """ - DEPRECATED: use the useRestart property instead - Returns True if the scene will be restarted. - - @rtype: boolean - """ - def getScene(): - """ - DEPRECATED: use the scene property instead - Returns the name of the scene to change to/overlay/underlay/remove/suspend/resume. - - Returns an empty string ("") if no scene has been set. - - @rtype: string - """ - def getCamera(): - """ - DEPRECATED: use the camera property instead - Returns the name of the camera to change to. - - @rtype: string - """ diff --git a/source/gameengine/PyDoc/KX_SoundActuator.py b/source/gameengine/PyDoc/KX_SoundActuator.py deleted file mode 100644 index 0aec57c851c..00000000000 --- a/source/gameengine/PyDoc/KX_SoundActuator.py +++ /dev/null @@ -1,195 +0,0 @@ -# $Id$ -# Documentation for KX_SoundActuator -from SCA_IActuator import * - -class KX_SoundActuator(SCA_IActuator): - """ - Sound Actuator. - - The L{startSound()}, L{pauseSound()} and L{stopSound()} do not require - the actuator to be activated - they act instantly provided that the actuator has - been activated once at least. - - @ivar filename: Sets the filename of the sound this actuator plays. - @type filename: string - - @ivar volume: Sets the volume (gain) of the sound. - @type volume: float - - @ivar pitch: Sets the pitch of the sound. - @type pitch: float - - @ivar rollOffFactor: Sets the roll off factor. Rolloff defines the rate of attenuation as the sound gets further away. - @type rollOffFactor: float - - @ivar looping: Sets the loop mode of the actuator. - @type looping: integer - - @ivar position: Sets the position of the sound. - @type position: float array - - @ivar velocity: Sets the speed of the sound; The speed of the sound alter the pitch. - @type velocity: float array - - @ivar orientation: Sets the orientation of the sound. When setting the orientation you can - also use quaternion [float,float,float,float] or euler angles [float,float,float] - @type orientation: 3x3 matrix [[float]] - - @ivar type: Sets the operation mode of the actuator. You can use one of the following constant: - - KX_SOUNDACT_PLAYSTOP (1) - - KX_SOUNDACT_PLAYEND (2) - - KX_SOUNDACT_LOOPSTOP (3) - - KX_SOUNDACT_LOOPEND (4) - - KX_SOUNDACT_LOOPBIDIRECTIONAL (5) - - KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP (6) - @type type: integer - - @group Play Methods: startSound, pauseSound, stopSound - """ - def setFilename(filename): - """ - DEPRECATED: Use the filename property instead. - Sets the filename of the sound this actuator plays. - - @type filename: string - """ - def getFilename(): - """ - DEPRECATED: Use the filename property instead. - Returns the filename of the sound this actuator plays. - - @rtype: string - """ - def startSound(): - """ - Starts the sound. - """ - def pauseSound(): - """ - Pauses the sound. - """ - def stopSound(): - """ - Stops the sound. - """ - def setGain(gain): - """ - DEPRECATED: Use the volume property instead - Sets the gain (volume) of the sound - - @type gain: float - @param gain: 0.0 (quiet) <= gain <= 1.0 (loud) - """ - def getGain(): - """ - DEPRECATED: Use the volume property instead. - Gets the gain (volume) of the sound. - - @rtype: float - """ - def setPitch(pitch): - """ - DEPRECATED: Use the pitch property instead. - Sets the pitch of the sound. - - @type pitch: float - """ - def getPitch(): - """ - DEPRECATED: Use the pitch property instead. - Returns the pitch of the sound. - - @rtype: float - """ - def setRollOffFactor(rolloff): - """ - DEPRECATED: Use the rollOffFactor property instead. - Sets the rolloff factor for the sounds. - - Rolloff defines the rate of attenuation as the sound gets further away. - Higher rolloff factors shorten the distance at which the sound can be heard. - - @type rolloff: float - """ - def getRollOffFactor(): - """ - DEPRECATED: Use the rollOffFactor property instead. - Returns the rolloff factor for the sound. - - @rtype: float - """ - def setLooping(loop): - """ - DEPRECATED: Use the looping property instead. - Sets the loop mode of the actuator. - - @bug: There are no constants defined for this method! - @param loop: - Play Stop 1 - - Play End 2 - - Loop Stop 3 - - Loop End 4 - - Bidirection Stop 5 - - Bidirection End 6 - @type loop: integer - """ - def getLooping(): - """ - DEPRECATED: Use the looping property instead. - Returns the current loop mode of the actuator. - - @rtype: integer - """ - def setPosition(x, y, z): - """ - DEPRECATED: Use the position property instead. - Sets the position this sound will come from. - - @type x: float - @param x: The x coordinate of the sound. - @type y: float - @param y: The y coordinate of the sound. - @type z: float - @param z: The z coordinate of the sound. - """ - def setVelocity(vx, vy, vz): - """ - DEPRECATED: Use the velocity property instead. - Sets the velocity this sound is moving at. - - The sound's pitch is determined from the velocity. - - @type vx: float - @param vx: The vx coordinate of the sound. - @type vy: float - @param vy: The vy coordinate of the sound. - @type vz: float - @param vz: The vz coordinate of the sound. - """ - def setOrientation(o11, o12, o13, o21, o22, o23, o31, o32, o33): - """ - DEPRECATED: Use the orientation property instead. - Sets the orientation of the sound. - - The nine parameters specify a rotation matrix:: - | o11, o12, o13 | - | o21, o22, o23 | - | o31, o32, o33 | - """ - - def setType(mode): - """ - DEPRECATED: Use the type property instead. - Sets the operation mode of the actuator. - - @param mode: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP - @type mode: integer - """ - - def getType(): - """ - DEPRECATED: Use the type property instead. - Returns the operation mode of the actuator. - - @rtype: integer - @return: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP - """ diff --git a/source/gameengine/PyDoc/KX_StateActuator.py b/source/gameengine/PyDoc/KX_StateActuator.py deleted file mode 100644 index d9785ad13fa..00000000000 --- a/source/gameengine/PyDoc/KX_StateActuator.py +++ /dev/null @@ -1,44 +0,0 @@ -# $Id$ -# Documentation for KX_StateActuator -from SCA_IActuator import * - -class KX_StateActuator(SCA_IActuator): - """ - State actuator changes the state mask of parent object. - - Property: - - @ivar operation: type of bit operation to be applied on object state mask. - You can use one of the following constant: - - KX_STATE_OP_CPY (0) : Copy state mask - - KX_STATE_OP_SET (1) : Add bits to state mask - - KX_STATE_OP_CLR (2) : Substract bits to state mask - - KX_STATE_OP_NEG (3) : Invert bits to state mask - @type operation: integer - - @ivar mask: value that defines the bits that will be modified by the operation. - The bits that are 1 in the mask will be updated in the object state, - the bits that are 0 are will be left unmodified expect for the Copy operation - which copies the mask to the object state - @type mask: integer - """ - def setOperation(op): - """ - DEPRECATED: Use the operation property instead. - Set the type of bit operation to be applied on object state mask. - Use setMask() to specify the bits that will be modified. - - @param op: bit operation (0=Copy, 1=Add, 2=Substract, 3=Invert) - @type op: integer - """ - def setMask(mask): - """ - DEPRECATED: Use the mask property instead. - Set the value that defines the bits that will be modified by the operation. - The bits that are 1 in the value will be updated in the object state, - the bits that are 0 are will be left unmodified expect for the Copy operation - which copies the value to the object state. - - @param mask: bits that will be modified - @type mask: integer - """ diff --git a/source/gameengine/PyDoc/KX_TouchSensor.py b/source/gameengine/PyDoc/KX_TouchSensor.py deleted file mode 100644 index f4fcbeefc62..00000000000 --- a/source/gameengine/PyDoc/KX_TouchSensor.py +++ /dev/null @@ -1,63 +0,0 @@ -# $Id$ -# Documentation for KX_TouchSensor -from SCA_ISensor import * -from KX_GameObject import * - -class KX_TouchSensor(SCA_ISensor): - """ - Touch sensor detects collisions between objects. - - @ivar property: The property or material to collide with. - @type property: string - @ivar useMaterial: Determines if the sensor is looking for a property or material. - KX_True = Find material; KX_False = Find property - @type useMaterial: boolean - @ivar pulseCollisions: The last collided object. - @type pulseCollisions: bool - @ivar objectHit: The last collided object. (Read Only) - @type objectHit: L{KX_GameObject} or None - @ivar objectHitList: A list of colliding objects. (Read Only) - @type objectHitList: L{CListValue} of L{KX_GameObject} - """ - - #--The following methods are deprecated, please use properties instead. - def setProperty(name): - """ - DEPRECATED: use the property property - Set the property or material to collide with. Use - setTouchMaterial() to switch between properties and - materials. - @type name: string - """ - - def getProperty(): - """ - DEPRECATED: use the property property - Returns the property or material to collide with. Use - getTouchMaterial() to find out whether this sensor - looks for properties or materials. (B{deprecated}) - - @rtype: string - """ - def getHitObject(): - """ - DEPRECATED: use the objectHit property - Returns the last object hit by this touch sensor. (B{deprecated}) - - @rtype: L{KX_GameObject} - """ - def getHitObjectList(): - """ - DEPRECATED: use the objectHitList property - Returns a list of all objects hit in the last frame. (B{deprecated}) - - Only objects that have the requisite material/property are listed. - - @rtype: L{CListValue} of L{KX_GameObject} - """ - def getTouchMaterial(): - """ - DEPRECATED: use the useMaterial property - Returns KX_TRUE if this sensor looks for a specific material, - KX_FALSE if it looks for a specific property. (B{deprecated}) - """ diff --git a/source/gameengine/PyDoc/KX_TrackToActuator.py b/source/gameengine/PyDoc/KX_TrackToActuator.py deleted file mode 100644 index ee2dc5d6144..00000000000 --- a/source/gameengine/PyDoc/KX_TrackToActuator.py +++ /dev/null @@ -1,70 +0,0 @@ -# $Id$ -# Documentation for KX_TrackToActuator -from SCA_IActuator import * - -class KX_TrackToActuator(SCA_IActuator): - """ - Edit Object actuator in Track To mode. - - @warning: Track To Actuators will be ignored if at game start, the - object to track to is invalid. - - This will generate a warning in the console: - - C{ERROR: GameObject I{OBName} no object in EditObjectActuator I{ActuatorName}} - - @ivar object: the object this actuator tracks. - @type object: KX_GameObject or None - @ivar time: the time in frames with which to delay the tracking motion - @type time: integer - @ivar use3D: the tracking motion to use 3D - @type use3D: boolean - - """ - def setObject(object): - """ - DEPRECATED: Use the object property. - Sets the object to track. - - @type object: L{KX_GameObject}, string or None - @param object: Either a reference to a game object or the name of the object to track. - """ - def getObject(name_only): - """ - DEPRECATED: Use the object property. - Returns the name of the object to track. - - @type name_only: bool - @param name_only: optional argument, when 0 return a KX_GameObject - @rtype: string, KX_GameObject or None if no object is set - """ - def setTime(time): - """ - DEPRECATED: Use the time property. - Sets the time in frames with which to delay the tracking motion. - - @type time: integer - """ - def getTime(): - """ - DEPRECATED: Use the time property. - Returns the time in frames with which the tracking motion is delayed. - - @rtype: integer - """ - def setUse3D(use3d): - """ - DEPRECATED: Use the use3D property. - Sets the tracking motion to use 3D. - - @type use3d: boolean - @param use3d: - True: allow the tracking motion to extend in the z-direction. - - False: lock the tracking motion to the x-y plane. - """ - def getUse3D(): - """ - DEPRECATED: Use the use3D property. - Returns True if the tracking motion will track in the z direction. - - @rtype: boolean - """ diff --git a/source/gameengine/PyDoc/KX_VehicleWrapper.py b/source/gameengine/PyDoc/KX_VehicleWrapper.py deleted file mode 100644 index 86991634f2d..00000000000 --- a/source/gameengine/PyDoc/KX_VehicleWrapper.py +++ /dev/null @@ -1,160 +0,0 @@ -from PyObjectPlus import * - -class KX_VehicleWrapper(PyObjectPlus): - """ - KX_VehicleWrapper - - TODO - description - """ - - def addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering): - - """ - Add a wheel to the vehicle - - @param wheel: The object to use as a wheel. - @type wheel: L{KX_GameObject} or a KX_GameObject name - @param attachPos: The position that this wheel will attach to. - @type attachPos: vector of 3 floats - @param attachDir: The direction this wheel points. - @type attachDir: vector of 3 floats - @param axleDir: The direction of this wheels axle. - @type axleDir: vector of 3 floats - @param suspensionRestLength: TODO - Description - @type suspensionRestLength: float - @param wheelRadius: The size of the wheel. - @type wheelRadius: float - """ - - def applyBraking(force, wheelIndex): - """ - Apply a braking force to the specified wheel - - @param force: the brake force - @type force: float - - @param wheelIndex: index of the wheel where the force needs to be applied - @type wheelIndex: integer - """ - def applyEngineForce(force, wheelIndex): - """ - Apply an engine force to the specified wheel - - @param force: the engine force - @type force: float - - @param wheelIndex: index of the wheel where the force needs to be applied - @type wheelIndex: integer - """ - def getConstraintId(): - """ - Get the constraint ID - - @rtype: integer - @return: the constraint id - """ - def getConstraintType(): - """ - Returns the constraint type. - - @rtype: integer - @return: constraint type - """ - def getNumWheels(): - """ - Returns the number of wheels. - - @rtype: integer - @return: the number of wheels for this vehicle - """ - def getWheelOrientationQuaternion(wheelIndex): - """ - Returns the wheel orientation as a quaternion. - - @param wheelIndex: the wheel index - @type wheelIndex: integer - - @rtype: TODO - type should be quat as per method name but from the code it looks like a matrix - @return: TODO Description - """ - def getWheelPosition(wheelIndex): - """ - Returns the position of the specified wheel - - @param wheelIndex: the wheel index - @type wheelIndex: integer - - @rtype: list[x, y, z] - @return: position vector - """ - def getWheelRotation(wheelIndex): - """ - Returns the rotation of the specified wheel - - @param wheelIndex: the wheel index - @type wheelIndex: integer - - @rtype: float - @return: the wheel rotation - """ - def setRollInfluence(rollInfluece, wheelIndex): - """ - Set the specified wheel's roll influence. - The higher the roll influence the more the vehicle will tend to roll over in corners. - - @param rollInfluece: the wheel roll influence - @type rollInfluece: float - - @param wheelIndex: the wheel index - @type wheelIndex: integer - """ - def setSteeringValue(steering, wheelIndex): - """ - Set the specified wheel's steering - - @param steering: the wheel steering - @type steering: float - - @param wheelIndex: the wheel index - @type wheelIndex: integer - """ - def setSuspensionCompression(compression, wheelIndex): - """ - Set the specified wheel's compression - - @param compression: the wheel compression - @type compression: float - - @param wheelIndex: the wheel index - @type wheelIndex: integer - """ - def setSuspensionDamping(damping, wheelIndex): - """ - Set the specified wheel's damping - - @param damping: the wheel damping - @type damping: float - - @param wheelIndex: the wheel index - @type wheelIndex: integer - """ - def setSuspensionStiffness(stiffness, wheelIndex): - """ - Set the specified wheel's stiffness - - @param stiffness: the wheel stiffness - @type stiffness: float - - @param wheelIndex: the wheel index - @type wheelIndex: integer - """ - def setTyreFriction(friction, wheelIndex): - """ - Set the specified wheel's tyre friction - - @param friction: the tyre friction - @type friction: float - - @param wheelIndex: the wheel index - @type wheelIndex: integer - """ diff --git a/source/gameengine/PyDoc/KX_VertexProxy.py b/source/gameengine/PyDoc/KX_VertexProxy.py deleted file mode 100644 index 75bd4d788a6..00000000000 --- a/source/gameengine/PyDoc/KX_VertexProxy.py +++ /dev/null @@ -1,152 +0,0 @@ -# $Id$ -# Documentation for the vertex proxy class - -from SCA_IObject import * - -class KX_VertexProxy(SCA_IObject): - """ - A vertex holds position, UV, colour and normal information. - - Note: - The physics simulation is NOT currently updated - physics will not respond - to changes in the vertex position. - - @ivar XYZ: The position of the vertex. - @type XYZ: list [x, y, z] - @ivar UV: The texture coordinates of the vertex. - @type UV: list [u, v] - @ivar normal: The normal of the vertex - @type normal: list [nx, ny, nz] - @ivar colour: The colour of the vertex. - Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0] - @type colour: list [r, g, b, a] - @ivar color: Synonym for colour. - - @group Position: x, y, z - @ivar x: The x coordinate of the vertex. - @type x: float - @ivar y: The y coordinate of the vertex. - @type y: float - @ivar z: The z coordinate of the vertex. - @type z: float - - @group Texture Coordinates: u, v - @ivar u: The u texture coordinate of the vertex. - @type u: float - @ivar v: The v texture coordinate of the vertex. - @type v: float - - @ivar u2: The second u texture coordinate of the vertex. - @type u2: float - @ivar v2: The second v texture coordinate of the vertex. - @type v2: float - - @group Colour: r, g, b, a - @ivar r: The red component of the vertex colour. 0.0 <= r <= 1.0 - @type r: float - @ivar g: The green component of the vertex colour. 0.0 <= g <= 1.0 - @type g: float - @ivar b: The blue component of the vertex colour. 0.0 <= b <= 1.0 - @type b: float - @ivar a: The alpha component of the vertex colour. 0.0 <= a <= 1.0 - @type a: float - """ - - def getXYZ(): - """ - Gets the position of this vertex. - - @rtype: list [x, y, z] - @return: this vertexes position in local coordinates. - """ - def setXYZ(pos): - """ - Sets the position of this vertex. - - @type pos: list [x, y, z] - @param pos: the new position for this vertex in local coordinates. - """ - def getUV(): - """ - Gets the UV (texture) coordinates of this vertex. - - @rtype: list [u, v] - @return: this vertexes UV (texture) coordinates. - """ - def setUV(uv): - """ - Sets the UV (texture) coordinates of this vertex. - - @type uv: list [u, v] - """ - def getUV2(): - """ - Gets the 2nd UV (texture) coordinates of this vertex. - - @rtype: list [u, v] - @return: this vertexes UV (texture) coordinates. - """ - def setUV2(uv, unit): - """ - Sets the 2nd UV (texture) coordinates of this vertex. - - @type uv: list [u, v] - @param unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV - @param unit: int - """ - def getRGBA(): - """ - Gets the colour of this vertex. - - The colour is represented as four bytes packed into an integer value. The colour is - packed as RGBA. - - Since Python offers no way to get each byte without shifting, you must use the struct module to - access colour in an machine independent way. - - Because of this, it is suggested you use the r, g, b and a attributes or the colour attribute instead. - - Example:: - import struct; - col = struct.unpack('4B', struct.pack('I', v.getRGBA())) - # col = (r, g, b, a) - # black = ( 0, 0, 0, 255) - # white = (255, 255, 255, 255) - - @rtype: integer - @return: packed colour. 4 byte integer with one byte per colour channel in RGBA format. - """ - def setRGBA(col): - """ - Sets the colour of this vertex. - - See getRGBA() for the format of col, and its relevant problems. Use the r, g, b and a attributes - or the colour attribute instead. - - setRGBA() also accepts a four component list as argument col. The list represents the colour as [r, g, b, a] - with black = [0.0, 0.0, 0.0, 1.0] and white = [1.0, 1.0, 1.0, 1.0] - - Example:: - v.setRGBA(0xff0000ff) # Red - v.setRGBA(0xff00ff00) # Green on little endian, transparent purple on big endian - v.setRGBA([1.0, 0.0, 0.0, 1.0]) # Red - v.setRGBA([0.0, 1.0, 0.0, 1.0]) # Green on all platforms. - - @type col: integer or list [r, g, b, a] - @param col: the new colour of this vertex in packed RGBA format. - """ - def getNormal(): - """ - Gets the normal vector of this vertex. - - @rtype: list [nx, ny, nz] - @return: normalised normal vector. - """ - def setNormal(normal): - """ - Sets the normal vector of this vertex. - - @type normal: sequence of floats [r, g, b] - @param normal: the new normal of this vertex. - """ - diff --git a/source/gameengine/PyDoc/KX_VisibilityActuator.py b/source/gameengine/PyDoc/KX_VisibilityActuator.py deleted file mode 100644 index 36f25b2423c..00000000000 --- a/source/gameengine/PyDoc/KX_VisibilityActuator.py +++ /dev/null @@ -1,22 +0,0 @@ -# $Id$ -# Documentation for KX_VisibilityActuator -from SCA_IActuator import * - -class KX_VisibilityActuator(SCA_IActuator): - """ - Visibility Actuator. - @ivar visibility: whether the actuator makes its parent object visible or invisible - @type visibility: boolean - @ivar occlusion: whether the actuator makes its parent object an occluder or not - @type occlusion: boolean - @ivar recursion: whether the visibility/occlusion should be propagated to all children of the object - @type recursion: boolean - """ - def set(visible): - """ - DEPRECATED: Use the visibility property instead. - Sets whether the actuator makes its parent object visible or invisible. - - @param visible: - True: Makes its parent visible. - - False: Makes its parent invisible. - """ diff --git a/source/gameengine/PyDoc/PyObjectPlus.py b/source/gameengine/PyDoc/PyObjectPlus.py deleted file mode 100644 index 1750bcb6ca1..00000000000 --- a/source/gameengine/PyDoc/PyObjectPlus.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# Documentation for PyObjectPlus base class - -class PyObjectPlus: - """ - PyObjectPlus base class of most other types in the Game Engine. - - @ivar invalid: Test if the object has been freed by the game engine and is no longer valid. - - Normally this is not a problem but when storing game engine data in the GameLogic module, - KX_Scenes or other KX_GameObjects its possible to hold a reference to invalid data. - Calling an attribute or method on an invalid object will raise a SystemError. - - The invalid attribute allows testing for this case without exception handling. - @type invalid: bool - """ - - def isA(game_type): - """ - Check if this is a type or a subtype game_type. - - @param game_type: the name of the type or the type its self from the L{GameTypes} module. - @type game_type: string or type - @return: True if this object is a type or a subtype of game_type. - @rtype: bool - """ diff --git a/source/gameengine/PyDoc/SCA_2DFilterActuator.py b/source/gameengine/PyDoc/SCA_2DFilterActuator.py deleted file mode 100644 index 9a010e8f221..00000000000 --- a/source/gameengine/PyDoc/SCA_2DFilterActuator.py +++ /dev/null @@ -1,44 +0,0 @@ -# $Id$ -# Documentation for SCA_2DFilterActuator -from SCA_IActuator import * -from SCA_ILogicBrick import * - -class SCA_2DFilterActuator(SCA_IActuator): - """ - Create, enable and disable 2D filters - - Properties: - - The following properties don't have an immediate effect. - You must active the actuator to get the result. - The actuator is not persistent: it automatically stops itself after setting up the filter - but the filter remains active. To stop a filter you must activate the actuator with 'type' - set to RAS_2DFILTER_DISABLED or RAS_2DFILTER_NOFILTER. - - @ivar shaderText: shader source code for custom shader - @type shaderText: string - @ivar disableMotionBlur: action on motion blur: 0=enable, 1=disable - @type disableMotionBlur: integer - @ivar type: type of 2D filter, use one of the following constants: - RAS_2DFILTER_ENABLED (-2) : enable the filter that was previously disabled - RAS_2DFILTER_DISABLED (-1) : disable the filter that is currently active - RAS_2DFILTER_NOFILTER (0) : disable and destroy the filter that is currently active - RAS_2DFILTER_MOTIONBLUR (1) : create and enable preset filters - RAS_2DFILTER_BLUR (2) - RAS_2DFILTER_SHARPEN (3) - RAS_2DFILTER_DILATION (4) - RAS_2DFILTER_EROSION (5) - RAS_2DFILTER_LAPLACIAN (6) - RAS_2DFILTER_SOBEL (7) - RAS_2DFILTER_PREWITT (8) - RAS_2DFILTER_GRAYSCALE (9) - RAS_2DFILTER_SEPIA (10) - RAS_2DFILTER_INVERT (11) - RAS_2DFILTER_CUSTOMFILTER (12) : customer filter, the code code is set via shaderText property - @type type: integer - @ivar passNb: order number of filter in the stack of 2D filters. Filters are executed in increasing order of passNb. - Only be one filter can be defined per passNb. - @type passNb: integer (0-100) - @ivar value: argument for motion blur filter - @type value: float (0.0-100.0) - """ diff --git a/source/gameengine/PyDoc/SCA_ANDController.py b/source/gameengine/PyDoc/SCA_ANDController.py deleted file mode 100644 index 1717e613595..00000000000 --- a/source/gameengine/PyDoc/SCA_ANDController.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for SCA_ANDController -from SCA_IController import * - -class SCA_ANDController(SCA_IController): - """ - An AND controller activates only when all linked sensors are activated. - - There are no special python methods for this controller. - """ - diff --git a/source/gameengine/PyDoc/SCA_ActuatorSensor.py b/source/gameengine/PyDoc/SCA_ActuatorSensor.py deleted file mode 100644 index 515354e8716..00000000000 --- a/source/gameengine/PyDoc/SCA_ActuatorSensor.py +++ /dev/null @@ -1,33 +0,0 @@ -# $Id$ -# Documentation for SCA_ActuatorSensor -from SCA_IActuator import * -from SCA_ISensor import * -from SCA_ILogicBrick import * - -class SCA_ActuatorSensor(SCA_ISensor): - """ - Actuator sensor detect change in actuator state of the parent object. - It generates a positive pulse if the corresponding actuator is activated - and a negative pulse if the actuator is deactivated. - - Properties: - - @ivar actuator: the name of the actuator that the sensor is monitoring. - @type actuator: string - """ - def getActuator(): - """ - DEPRECATED: use the actuator property - Return the Actuator with which the sensor operates. - - @rtype: string - """ - def setActuator(name): - """ - DEPRECATED: use the actuator property - Sets the Actuator with which to operate. If there is no Actuator - of this name, the function has no effect. - - @param name: actuator name - @type name: string - """ diff --git a/source/gameengine/PyDoc/SCA_AlwaysSensor.py b/source/gameengine/PyDoc/SCA_AlwaysSensor.py deleted file mode 100644 index 54ab07a8a99..00000000000 --- a/source/gameengine/PyDoc/SCA_AlwaysSensor.py +++ /dev/null @@ -1,9 +0,0 @@ -# $Id$ -# Documentation for SCA_AlwaysSensor -from SCA_ISensor import * - -class SCA_AlwaysSensor(SCA_ISensor): - """ - This sensor is always activated. - """ - diff --git a/source/gameengine/PyDoc/SCA_DelaySensor.py b/source/gameengine/PyDoc/SCA_DelaySensor.py deleted file mode 100644 index 6560df6573e..00000000000 --- a/source/gameengine/PyDoc/SCA_DelaySensor.py +++ /dev/null @@ -1,72 +0,0 @@ -# $Id$ -# Documentation for SCA_DelaySensor -from SCA_ISensor import * - -class SCA_DelaySensor(SCA_ISensor): - """ - The Delay sensor generates positive and negative triggers at precise time, - expressed in number of frames. The delay parameter defines the length - of the initial OFF period. A positive trigger is generated at the end of this period. - The duration parameter defines the length of the ON period following the OFF period. - There is a negative trigger at the end of the ON period. If duration is 0, the sensor - stays ON and there is no negative trigger. - The sensor runs the OFF-ON cycle once unless the repeat option is set: the - OFF-ON cycle repeats indefinately (or the OFF cycle if duration is 0). - Use SCA_ISensor::reset() at any time to restart sensor. - - Properties: - - @ivar delay: length of the initial OFF period as number of frame, 0 for immediate trigger. - @type delay: integer. - @ivar duration: length of the ON period in number of frame after the initial OFF period. - If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. - @type duration: integer - @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. - @type repeat: integer - """ - def setDelay(delay): - """ - DEPRECATED: use the delay property - Set the initial delay before the positive trigger. - - @param delay: length of the initial OFF period as number of frame, 0 for immediate trigger - @type delay: integer - """ - def setDuration(duration): - """ - DEPRECATED: use the duration property - Set the duration of the ON pulse after initial delay and the generation of the positive trigger. - If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. - - @param duration: length of the ON period in number of frame after the initial OFF period - @type duration: integer - """ - def setRepeat(repeat): - """ - DEPRECATED: use the repeat property - Set if the sensor repeat mode. - - @param repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. - @type repeat: integer - """ - def getDelay(): - """ - DEPRECATED: use the delay property - Return the delay parameter value. - - @rtype: integer - """ - def getDuration(): - """ - DEPRECATED: use the duration property - Return the duration parameter value - - @rtype: integer - """ - def getRepeat(): - """ - DEPRECATED: use the repeat property - Return the repeat parameter value - - @rtype: KX_TRUE or KX_FALSE - """ diff --git a/source/gameengine/PyDoc/SCA_IActuator.py b/source/gameengine/PyDoc/SCA_IActuator.py deleted file mode 100644 index ac47c15dc78..00000000000 --- a/source/gameengine/PyDoc/SCA_IActuator.py +++ /dev/null @@ -1,9 +0,0 @@ -# $Id$ -# Documentation for SCA_IActuator -from SCA_ILogicBrick import * - -class SCA_IActuator(SCA_ILogicBrick): - """ - Base class for all actuator logic bricks. - """ - diff --git a/source/gameengine/PyDoc/SCA_IController.py b/source/gameengine/PyDoc/SCA_IController.py deleted file mode 100644 index cfb4c18a826..00000000000 --- a/source/gameengine/PyDoc/SCA_IController.py +++ /dev/null @@ -1,63 +0,0 @@ -# $Id$ -# Documentation for KX_CameraActuator -from SCA_ILogicBrick import * - -class SCA_IController(SCA_ILogicBrick): - """ - Base class for all controller logic bricks. - - @ivar state: the controllers state bitmask. - This can be used with the GameObject's state to test if the controller is active. - @type state: int bitmask - @ivar sensors: a list of sensors linked to this controller - - note: the sensors are not necessarily owned by the same object. - - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. - @type sensors: sequence supporting index/string lookups and iteration. - @ivar actuators: a list of actuators linked to this controller. - - note: the sensors are not necessarily owned by the same object. - - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. - @type actuators: sequence supporting index/string lookups and iteration. - - @group Deprecated: getState, getSensors, getActuators, getSensor, getActuator - """ - - def getState(): - """ - DEPRECATED: use the state property - Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. - This for instance will always be true however you could compare with a previous state to see when the state was activated. - GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState() - - @rtype: int - """ - def getSensors(): - """ - DEPRECATED: use the sensors property - Gets a list of all sensors attached to this controller. - - @rtype: list [L{SCA_ISensor}] - """ - def getSensor(name): - """ - DEPRECATED: use the sensors[name] property - Gets the named linked sensor. - - @type name: string - @rtype: L{SCA_ISensor} - """ - def getActuators(): - """ - DEPRECATED: use the actuators property - Gets a list of all actuators linked to this controller. - - @rtype: list [L{SCA_IActuator}] - """ - def getActuator(name): - """ - DEPRECATED: use the actuators[name] property - Gets the named linked actuator. - - @type name: string - @rtype: L{SCA_IActuator} - """ - \ No newline at end of file diff --git a/source/gameengine/PyDoc/SCA_ILogicBrick.py b/source/gameengine/PyDoc/SCA_ILogicBrick.py deleted file mode 100644 index a96e77c3249..00000000000 --- a/source/gameengine/PyDoc/SCA_ILogicBrick.py +++ /dev/null @@ -1,49 +0,0 @@ -# $Id$ -# Documentation for the logic brick base class SCA_ILogicBrick -from KX_GameObject import * -from CValue import * - -class SCA_ILogicBrick(CValue): - """ - Base class for all logic bricks. - - @ivar executePriority: This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first). - @type executePriority: int - @ivar owner: The game object this logic brick is attached to (read only). - @type owner: L{KX_GameObject} or None in exceptional cases. - @ivar name: The name of this logic brick (read only). - @type name: string - @group Deprecated: getOwner, setExecutePriority, getExecutePriority - """ - - def getOwner(): - """ - Gets the game object associated with this logic brick. - - Deprecated: Use the "owner" property instead. - - @rtype: L{KX_GameObject} - """ - - #--The following methods are deprecated-- - def setExecutePriority(priority): - """ - Sets the priority of this logic brick. - - This determines the order controllers are evaluated, and actuators are activated. - Bricks with lower priority will be executed first. - - Deprecated: Use the "executePriority" property instead. - - @type priority: integer - @param priority: the priority of this logic brick. - """ - def getExecutePriority(): - """ - Gets the execution priority of this logic brick. - - Deprecated: Use the "executePriority" property instead. - - @rtype: integer - @return: this logic bricks current priority. - """ diff --git a/source/gameengine/PyDoc/SCA_IObject.py b/source/gameengine/PyDoc/SCA_IObject.py deleted file mode 100644 index 92e4884e815..00000000000 --- a/source/gameengine/PyDoc/SCA_IObject.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Documentation for SCA_IObject class - -from CValue import * -class SCA_IObject(CValue): - """ - This class has no python functions - """ - pass diff --git a/source/gameengine/PyDoc/SCA_ISensor.py b/source/gameengine/PyDoc/SCA_ISensor.py deleted file mode 100644 index 0b72548b103..00000000000 --- a/source/gameengine/PyDoc/SCA_ISensor.py +++ /dev/null @@ -1,112 +0,0 @@ -# $Id$ -# Documentation for SCA_ISensor -from SCA_ILogicBrick import * - -class SCA_ISensor(SCA_ILogicBrick): - """ - Base class for all sensor logic bricks. - - @ivar usePosPulseMode: Flag to turn positive pulse mode on and off. - @type usePosPulseMode: boolean - @ivar useNegPulseMode: Flag to turn negative pulse mode on and off. - @type useNegPulseMode: boolean - @ivar frequency: The frequency for pulse mode sensors. - @type frequency: int - @ivar level: Flag to set whether to detect level or edge transition when entering a state. - It makes a difference only in case of logic state transition (state actuator). - A level detector will immediately generate a pulse, negative or positive - depending on the sensor condition, as soon as the state is activated. - A edge detector will wait for a state change before generating a pulse. - @type level: boolean - @ivar invert: Flag to set if this sensor activates on positive or negative events. - @type invert: boolean - @ivar triggered: True if this sensor brick is in a positive state. (Read only) - @type triggered: boolean - @ivar positive: True if this sensor brick is in a positive state. (Read only) - @type positive: boolean - @group Deprecated: isPositive, isTriggered, getUsePosPulseMode, setUsePosPulseMode, getFrequency, setFrequency, getUseNegPulseMode, setUseNegPulseMode, getInvert, setInvert, getLevel, setLevel - """ - - def reset(): - """ - Reset sensor internal state, effect depends on the type of sensor and settings. - - The sensor is put in its initial state as if it was just activated. - """ - - #--The following methods are deprecated-- - def isPositive(): - """ - True if this sensor brick is in a positive state. - """ - - def isTriggered(): - """ - True if this sensor brick has triggered the current controller. - """ - - def getUsePosPulseMode(): - """ - True if the sensor is in positive pulse mode. - """ - def setUsePosPulseMode(pulse): - """ - Sets positive pulse mode. - - @type pulse: boolean - @param pulse: If True, will activate positive pulse mode for this sensor. - """ - def getFrequency(): - """ - The frequency for pulse mode sensors. - - @rtype: integer - @return: the pulse frequency in 1/50 sec. - """ - def setFrequency(freq): - """ - Sets the frequency for pulse mode sensors. - - @type freq: integer - @return: the pulse frequency in 1/50 sec. - """ - def getUseNegPulseMode(): - """ - True if the sensor is in negative pulse mode. - """ - def setUseNegPulseMode(pulse): - """ - Sets negative pulse mode. - - @type pulse: boolean - @param pulse: If True, will activate negative pulse mode for this sensor. - """ - def getInvert(): - """ - True if this sensor activates on negative events. - """ - def setInvert(invert): - """ - Sets if this sensor activates on positive or negative events. - - @type invert: boolean - @param invert: true if activates on negative events; false if activates on positive events. - """ - def getLevel(): - """ - Returns whether this sensor is a level detector or a edge detector. - It makes a difference only in case of logic state transition (state actuator). - A level detector will immediately generate a pulse, negative or positive - depending on the sensor condition, as soon as the state is activated. - A edge detector will wait for a state change before generating a pulse. - - @rtype: boolean - @return: true if sensor is level sensitive, false if it is edge sensitive - """ - def setLevel(level): - """ - Set whether to detect level or edge transition when entering a state. - - @param level: Detect level instead of edge? (KX_TRUE, KX_FALSE) - @type level: boolean - """ diff --git a/source/gameengine/PyDoc/SCA_JoystickSensor.py b/source/gameengine/PyDoc/SCA_JoystickSensor.py deleted file mode 100644 index 13b006e8dd6..00000000000 --- a/source/gameengine/PyDoc/SCA_JoystickSensor.py +++ /dev/null @@ -1,169 +0,0 @@ -# $Id$ -# Documentation for SCA_RandomSensor -from SCA_ISensor import * - -class SCA_JoystickSensor(SCA_ISensor): - """ - This sensor detects player joystick events. - - Properties: - - @ivar axisValues: (read-only) The state of the joysticks axis as a list of values L{numAxis} long. - each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. - The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls. - left:[-32767, 0, ...], right:[32767, 0, ...], up:[0, -32767, ...], down:[0, 32767, ...] - @type axisValues: list of ints - - @ivar axisSingle: (read-only) like L{axisValues} but returns a single axis value that is set by the sensor. - Only use this for "Single Axis" type sensors otherwise it will raise an error. - @type axisSingle: int - - @ivar numAxis: (read-only) The number of axes for the joystick at this index. - @type numAxis: integer - @ivar numButtons: (read-only) The number of buttons for the joystick at this index. - @type numButtons: integer - @ivar numHats: (read-only) The number of hats for the joystick at this index. - @type numHats: integer - @ivar connected: (read-only) True if a joystick is connected at this joysticks index. - @type connected: boolean - @ivar index: The joystick index to use (from 0 to 7). The first joystick is always 0. - @type index: integer - @ivar threshold: Axis threshold. Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. - @type threshold: integer - @ivar button: The button index the sensor reacts to (first button = 0). When the "All Events" toggle is set, this option has no effect. - @type button: integer - @ivar axis: The axis this sensor reacts to, as a list of two values [axisIndex, axisDirection] - axisIndex: the axis index to use when detecting axis movement, 1=primary directional control, 2=secondary directional control. - axisDirection: 0=right, 1=up, 2=left, 3=down - @type axis: [integer, integer] - @ivar hat: The hat the sensor reacts to, as a list of two values: [hatIndex, hatDirection] - hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat. - hatDirection: 0-11 - @type hat: [integer, integer] - """ - - def getButtonActiveList(): - """ - Returns a list containing the indicies of the currently pressed buttons. - @rtype: list - """ - def getButtonStatus(buttonIndex): - """ - Returns a bool of the current pressed state of the specified button. - @param buttonIndex: the button index, 0=first button - @type buttonIndex: integer - @rtype: bool - """ - def getIndex(): - """ - DEPRECATED: use the 'index' property. - Returns the joystick index to use (from 1 to 8). - @rtype: integer - """ - def setIndex(index): - """ - DEPRECATED: use the 'index' property. - Sets the joystick index to use. - @param index: The index of this joystick sensor, Clamped between 1 and 8. - @type index: integer - @note: This is only useful when you have more then 1 joystick connected to your computer - multiplayer games. - """ - def getAxis(): - """ - DEPRECATED: use the 'axis' property. - Returns the current axis this sensor reacts to. See L{getAxisValue()} for the current axis state. - @rtype: list - @return: 2 values returned are [axisIndex, axisDirection] - see L{setAxis()} for their purpose. - @note: When the "All Events" toggle is set, this option has no effect. - """ - def setAxis(axisIndex, axisDirection): - """ - DEPRECATED: use the 'axis' property. - @param axisIndex: Set the axis index to use when detecting axis movement. - @type axisIndex: integer from 1 to 2 - @param axisDirection: Set the axis direction used for detecting motion. 0:right, 1:up, 2:left, 3:down. - @type axisDirection: integer from 0 to 3 - @note: When the "All Events" toggle is set, this option has no effect. - """ - def getAxisValue(): - """ - DEPRECATED: use the 'axisPosition' property. - Returns the state of the joysticks axis. See differs to L{getAxis()} returning the current state of the joystick. - @rtype: list - @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. - - The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls. - - left:[-32767, 0, ...], right:[32767, 0, ...], up:[0, -32767, ...], down:[0, 32767, ...] - @note: Some gamepads only set the axis on and off like a button. - """ - def getThreshold(): - """ - DEPRECATED: use the 'threshold' property. - Get the axis threshold. See L{setThreshold()} for details. - @rtype: integer - """ - def setThreshold(threshold): - """ - DEPRECATED: use the 'threshold' property. - Set the axis threshold. - @param threshold: Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. - @type threshold: integer - """ - def getButton(): - """ - DEPRECATED: use the 'button' property. - Returns the button index the sensor reacts to. See L{getButtonValue()} for a list of pressed buttons. - @rtype: integer - @note: When the "All Events" toggle is set, this option has no effect. - """ - def setButton(index): - """ - DEPRECATED: use the 'button' property. - Sets the button index the sensor reacts to when the "All Events" option is not set. - @note: When the "All Events" toggle is set, this option has no effect. - """ - def getButtonValue(): - """ - DEPRECATED: use the 'getButtonActiveList' method. - Returns a list containing the indicies of the currently pressed buttons. - @rtype: list - """ - def getHat(): - """ - DEPRECATED: use the 'hat' property. - Returns the current hat direction this sensor is set to. - [hatNumber, hatDirection]. - @rtype: list - @note: When the "All Events" toggle is set, this option has no effect. - """ - def setHat(index,direction): - """ - DEPRECATED: use the 'hat' property. - Sets the hat index the sensor reacts to when the "All Events" option is not set. - @type index: integer - """ - def getNumAxes(): - """ - DEPRECATED: use the 'numAxis' property. - Returns the number of axes for the joystick at this index. - @rtype: integer - """ - def getNumButtons(): - """ - DEPRECATED: use the 'numButtons' property. - Returns the number of buttons for the joystick at this index. - @rtype: integer - """ - def getNumHats(): - """ - DEPRECATED: use the 'numHats' property. - Returns the number of hats for the joystick at this index. - @rtype: integer - """ - def isConnected(): - """ - DEPRECATED: use the 'connected' property. - Returns True if a joystick is detected at this joysticks index. - @rtype: bool - """ diff --git a/source/gameengine/PyDoc/SCA_KeyboardSensor.py b/source/gameengine/PyDoc/SCA_KeyboardSensor.py deleted file mode 100644 index 8abb1fda762..00000000000 --- a/source/gameengine/PyDoc/SCA_KeyboardSensor.py +++ /dev/null @@ -1,116 +0,0 @@ -# $Id$ -# Documentation for SCA_KeyboardSensor -from SCA_ISensor import * - -class SCA_KeyboardSensor(SCA_ISensor): - """ - A keyboard sensor detects player key presses. - - See module L{GameKeys} for keycode values. - - @ivar key: The key code this sensor is looking for. - @type key: keycode from L{GameKeys} module - @ivar hold1: The key code for the first modifier this sensor is looking for. - @type hold1: keycode from L{GameKeys} module - @ivar hold2: The key code for the second modifier this sensor is looking for. - @type hold2: keycode from L{GameKeys} module - @ivar toggleProperty: The name of the property that indicates whether or not to log keystrokes as a string. - @type toggleProperty: string - @ivar targetProperty: The name of the property that receives keystrokes in case in case a string is logged. - @type targetProperty: string - @ivar useAllKeys: Flag to determine whether or not to accept all keys. - @type useAllKeys: boolean - @ivar events: a list of pressed keys that have either been pressed, or just released, or are active this frame. (read only). - - - 'keycode' matches the values in L{GameKeys}. - - 'status' uses... - - L{GameLogic.KX_INPUT_NONE} - - L{GameLogic.KX_INPUT_JUST_ACTIVATED} - - L{GameLogic.KX_INPUT_ACTIVE} - - L{GameLogic.KX_INPUT_JUST_RELEASED} - - @type events: list [[keycode, status], ...] - """ - - def getKeyStatus(keycode): - """ - Get the status of a key. - - @rtype: key state L{GameLogic} members (KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED) - @return: The state of the given key - @type keycode: integer - @param keycode: The code that represents the key you want to get the state of - """ - - #--The following methods are DEPRECATED-- - def getKey(): - """ - Returns the key code this sensor is looking for. - - B{DEPRECATED: Use the "key" property instead}. - - @rtype: keycode from L{GameKeys} module - """ - - def setKey(keycode): - """ - Set the key this sensor should listen for. - - B{DEPRECATED: Use the "key" property instead}. - - @type keycode: keycode from L{GameKeys} module - """ - - def getHold1(): - """ - Returns the key code for the first modifier this sensor is looking for. - - B{DEPRECATED: Use the "hold1" property instead}. - - @rtype: keycode from L{GameKeys} module - """ - - def setHold1(keycode): - """ - Sets the key code for the first modifier this sensor should look for. - - B{DEPRECATED: Use the "hold1" property instead}. - - @type keycode: keycode from L{GameKeys} module - """ - - def getHold2(): - """ - Returns the key code for the second modifier this sensor is looking for. - - B{DEPRECATED: Use the "hold2" property instead}. - - @rtype: keycode from L{GameKeys} module - """ - - def setHold2(keycode): - """ - Sets the key code for the second modifier this sensor should look for. - - B{DEPRECATED: Use the "hold2" property instead.} - - @type keycode: keycode from L{GameKeys} module - """ - - def getPressedKeys(): - """ - Get a list of keys that have either been pressed, or just released this frame. - - B{DEPRECATED: Use "events" instead.} - - @rtype: list of key status. [[keycode, status]] - """ - - def getCurrentlyPressedKeys(): - """ - Get a list of currently pressed keys that have either been pressed, or just released - - B{DEPRECATED: Use "events" instead.} - - @rtype: list of key status. [[keycode, status]] - """ \ No newline at end of file diff --git a/source/gameengine/PyDoc/SCA_MouseSensor.py b/source/gameengine/PyDoc/SCA_MouseSensor.py deleted file mode 100644 index 278ebe63b8a..00000000000 --- a/source/gameengine/PyDoc/SCA_MouseSensor.py +++ /dev/null @@ -1,44 +0,0 @@ -# $Id$ -# Documentation for SCA_MouseSensor -from SCA_ISensor import * - -class SCA_MouseSensor(SCA_ISensor): - """ - Mouse Sensor logic brick. - - Properties: - - @ivar position: current [x,y] coordinates of the mouse, in frame coordinates (pixels) - @type position: [integer,interger] - @ivar mode: sensor mode: 1=KX_MOUSESENSORMODE_LEFTBUTTON 2=KX_MOUSESENSORMODE_MIDDLEBUTTON - 3=KX_MOUSESENSORMODE_RIGHTBUTTON 4=KX_MOUSESENSORMODE_WHEELUP - 5=KX_MOUSESENSORMODE_WHEELDOWN 9=KX_MOUSESENSORMODE_MOVEMENT - @type mode: integer - """ - - def getXPosition(): - """ - DEPRECATED: use the position property - Gets the x coordinate of the mouse. - - @rtype: integer - @return: the current x coordinate of the mouse, in frame coordinates (pixels) - """ - def getYPosition(): - """ - DEPRECATED: use the position property - Gets the y coordinate of the mouse. - - @rtype: integer - @return: the current y coordinate of the mouse, in frame coordinates (pixels). - """ - def getButtonStatus(button): - """ - Get the mouse button status. - - @type button: int - @param button: value in GameLogic members KX_MOUSE_BUT_LEFT, KX_MOUSE_BUT_MIDDLE, KX_MOUSE_BUT_RIGHT - - @rtype: integer - @return: value in GameLogic members KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED - """ diff --git a/source/gameengine/PyDoc/SCA_NANDController.py b/source/gameengine/PyDoc/SCA_NANDController.py deleted file mode 100644 index a864ff2981c..00000000000 --- a/source/gameengine/PyDoc/SCA_NANDController.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for SCA_NANDController -from SCA_IController import * - -class SCA_NANDController(SCA_IController): - """ - An NAND controller activates when all linked sensors are not active. - - There are no special python methods for this controller. - """ - diff --git a/source/gameengine/PyDoc/SCA_NORController.py b/source/gameengine/PyDoc/SCA_NORController.py deleted file mode 100644 index 0bc0a71d7b1..00000000000 --- a/source/gameengine/PyDoc/SCA_NORController.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for SCA_NORController -from SCA_IController import * - -class SCA_NORController(SCA_IController): - """ - An NOR controller activates only when all linked sensors are de-activated. - - There are no special python methods for this controller. - """ - diff --git a/source/gameengine/PyDoc/SCA_ORController.py b/source/gameengine/PyDoc/SCA_ORController.py deleted file mode 100644 index eeeb9de3afe..00000000000 --- a/source/gameengine/PyDoc/SCA_ORController.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for SCA_ORController -from SCA_IController import * - -class SCA_ORController(SCA_IController): - """ - An OR controller activates when any connected sensor activates. - - There are no special python methods for this controller. - """ - diff --git a/source/gameengine/PyDoc/SCA_PropertyActuator.py b/source/gameengine/PyDoc/SCA_PropertyActuator.py deleted file mode 100644 index 52aefcae651..00000000000 --- a/source/gameengine/PyDoc/SCA_PropertyActuator.py +++ /dev/null @@ -1,49 +0,0 @@ -# $Id$ -# Documentation for SCA_PropertyActuator -from SCA_IActuator import * - -class SCA_PropertyActuator(SCA_IActuator): - """ - Property Actuator - - Properties: - - @ivar property: the property on which to operate. - @type property: string - @ivar value: the value with which the actuator operates. - @type value: string - """ - def setProperty(prop): - """ - DEPRECATED: use the 'property' property - Set the property on which to operate. - - If there is no property of this name, the call is ignored. - - @type prop: string - @param prop: The name of the property to set. - """ - def getProperty(): - """ - DEPRECATED: use the 'property' property - Returns the name of the property on which to operate. - - @rtype: string - """ - def setValue(value): - """ - DEPRECATED: use the 'value' property - Set the value with which the actuator operates. - - If the value is not compatible with the type of the - property, the subsequent action is ignored. - - @type value: string - """ - def getValue(): - """ - DEPRECATED: use the 'value' property - Gets the value with which this actuator operates. - - @rtype: string - """ diff --git a/source/gameengine/PyDoc/SCA_PropertySensor.py b/source/gameengine/PyDoc/SCA_PropertySensor.py deleted file mode 100644 index 949ffd3b703..00000000000 --- a/source/gameengine/PyDoc/SCA_PropertySensor.py +++ /dev/null @@ -1,74 +0,0 @@ -# $Id$ -# Documentation for SCA_PropertySensor -from SCA_ISensor import * - -class SCA_PropertySensor(SCA_ISensor): - """ - Activates when the game object property matches. - - Properties: - - @ivar type: type of check on the property: - KX_PROPSENSOR_EQUAL(1), KX_PROPSENSOR_NOTEQUAL(2), KX_PROPSENSOR_INTERVAL(3), - KX_PROPSENSOR_CHANGED(4), KX_PROPSENSOR_EXPRESSION(5) - @type type: integer - @ivar property: the property with which the sensor operates. - @type property: string - @ivar value: the value with which the sensor compares to the value of the property. - @type value: string - """ - - def getType(): - """ - DEPRECATED: use the type property - Gets when to activate this sensor. - - @return: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, - KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, - or KX_PROPSENSOR_EXPRESSION. - """ - - def setType(checktype): - """ - DEPRECATED: use the type property - Set the type of check to perform. - - @type checktype: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, - KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, - or KX_PROPSENSOR_EXPRESSION. - """ - - def getProperty(): - """ - DEPRECATED: use the property property - Return the property with which the sensor operates. - - @rtype: string - @return: the name of the property this sensor is watching. - """ - def setProperty(name): - """ - DEPRECATED: use the property property - Sets the property with which to operate. If there is no property - of that name, this call is ignored. - - @type name: string. - """ - def getValue(): - """ - DEPRECATED: use the value property - Return the value with which the sensor compares to the value of the property. - - @rtype: string - @return: the value of the property this sensor is watching. - """ - def setValue(value): - """ - DEPRECATED: use the value property - Set the value with which the sensor operates. If the value - is not compatible with the type of the property, the subsequent - action is ignored. - - @type value: string - """ - diff --git a/source/gameengine/PyDoc/SCA_PythonController.py b/source/gameengine/PyDoc/SCA_PythonController.py deleted file mode 100644 index 7b9b6ccd80a..00000000000 --- a/source/gameengine/PyDoc/SCA_PythonController.py +++ /dev/null @@ -1,41 +0,0 @@ -# $Id$ -# Documentation for SCA_PythonController -from SCA_IController import * - -class SCA_PythonController(SCA_IController): - """ - A Python controller uses a Python script to activate it's actuators, - based on it's sensors. - - Properties: - - @ivar script: the Python script this controller executes - @type script: string, read-only - - @group Deprecated: getScript, setScript - """ - def activate(actuator): - """ - Activates an actuator attached to this controller. - @type actuator: actuator or the actuator name as a string - """ - def deactivate(actuator): - """ - Deactivates an actuator attached to this controller. - @type actuator: actuator or the actuator name as a string - """ - def getScript(): - """ - DEPRECATED: use the script property - Gets the Python script this controller executes. - - @rtype: string - """ - def setScript(script): - """ - DEPRECATED: use the script property - Sets the Python script this controller executes. - - @type script: string. - """ - diff --git a/source/gameengine/PyDoc/SCA_RandomActuator.py b/source/gameengine/PyDoc/SCA_RandomActuator.py deleted file mode 100644 index 000a1af7846..00000000000 --- a/source/gameengine/PyDoc/SCA_RandomActuator.py +++ /dev/null @@ -1,175 +0,0 @@ -# $Id$ -# Documentation for SCA_RandomActuator -from SCA_IActuator import * - -class SCA_RandomActuator(SCA_IActuator): - """ - Random Actuator - - Properties: - - @ivar seed: Seed of the random number generator. - Equal seeds produce equal series. If the seed is 0, - the generator will produce the same value on every call. - @type seed: integer - @ivar para1: the first parameter of the active distribution. - Refer to the documentation of the generator types for the meaning - of this value. - @type para1: float, read-only - @ivar para2: the second parameter of the active distribution. - Refer to the documentation of the generator types for the meaning - of this value. - @type para2: float, read-only - @ivar distribution: distribution type: - KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, - KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, - KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, - KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL - @type distribution: integer, read-only - @ivar property: the name of the property to set with the random value. - If the generator and property types do not match, the assignment is ignored. - @type property: string - - """ - def setSeed(seed): - """ - DEPRECATED: use the seed property - Sets the seed of the random number generator. - - Equal seeds produce equal series. If the seed is 0, - the generator will produce the same value on every call. - - @type seed: integer - """ - def getSeed(): - """ - DEPRECATED: use the seed property - Returns the initial seed of the generator. - - @rtype: integer - """ - def getPara1(): - """ - DEPRECATED: use the para1 property - Returns the first parameter of the active distribution. - - Refer to the documentation of the generator types for the meaning - of this value. - - @rtype: float - """ - def getPara2(): - """ - DEPRECATED: use the para2 property - Returns the second parameter of the active distribution. - - Refer to the documentation of the generator types for the meaning - of this value. - - @rtype: float - """ - def getDistribution(): - """ - DEPRECATED: use the distribution property - Returns the type of random distribution. - - @rtype: distribution type - @return: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, - KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, - KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, - KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL - """ - def setProperty(property): - """ - DEPRECATED: use the property property - Set the property to which the random value is assigned. - - If the generator and property types do not match, the assignment is ignored. - - @type property: string - @param property: The name of the property to set. - """ - def getProperty(): - """ - DEPRECATED: use the property property - Returns the name of the property to set. - - @rtype: string - """ - def setBoolConst(value): - """ - Sets this generator to produce a constant boolean value. - - @param value: The value to return. - @type value: boolean - """ - def setBoolUniform(): - """ - Sets this generator to produce a uniform boolean distribution. - - The generator will generate True or False with 50% chance. - """ - def setBoolBernouilli(value): - """ - Sets this generator to produce a Bernouilli distribution. - - @param value: Specifies the proportion of False values to produce. - - 0.0: Always generate True - - 1.0: Always generate False - @type value: float - """ - def setIntConst(value): - """ - Sets this generator to always produce the given value. - - @param value: the value this generator produces. - @type value: integer - """ - def setIntUniform(lower_bound, upper_bound): - """ - Sets this generator to produce a random value between the given lower and - upper bounds (inclusive). - - @type lower_bound: integer - @type upper_bound: integer - """ - def setIntPoisson(value): - """ - Generate a Poisson-distributed number. - - This performs a series of Bernouilli tests with parameter value. - It returns the number of tries needed to achieve succes. - - @type value: float - """ - def setFloatConst(value): - """ - Always generate the given value. - - @type value: float - """ - def setFloatUniform(lower_bound, upper_bound): - """ - Generates a random float between lower_bound and upper_bound with a - uniform distribution. - - @type lower_bound: float - @type upper_bound: float - """ - def setFloatNormal(mean, standard_deviation): - """ - Generates a random float from the given normal distribution. - - @type mean: float - @param mean: The mean (average) value of the generated numbers - @type standard_deviation: float - @param standard_deviation: The standard deviation of the generated numbers. - """ - def setFloatNegativeExponential(half_life): - """ - Generate negative-exponentially distributed numbers. - - The half-life 'time' is characterized by half_life. - - @type half_life: float - """ diff --git a/source/gameengine/PyDoc/SCA_RandomSensor.py b/source/gameengine/PyDoc/SCA_RandomSensor.py deleted file mode 100644 index 6dc0a3c23c0..00000000000 --- a/source/gameengine/PyDoc/SCA_RandomSensor.py +++ /dev/null @@ -1,35 +0,0 @@ -# $Id$ -# Documentation for SCA_RandomSensor -from SCA_ISensor import * - -class SCA_RandomSensor(SCA_ISensor): - """ - This sensor activates randomly. - - @ivar lastDraw: The seed of the random number generator. - @type lastDraw: int - @ivar seed: The seed of the random number generator. - @type seed: int - """ - - def setSeed(seed): - """ - Sets the seed of the random number generator. - - If the seed is 0, the generator will produce the same value on every call. - - @type seed: integer. - """ - def getSeed(): - """ - Returns the initial seed of the generator. Equal seeds produce equal random - series. - - @rtype: integer - """ - def getLastDraw(): - """ - Returns the last random number generated. - - @rtype: integer - """ diff --git a/source/gameengine/PyDoc/SCA_XNORController.py b/source/gameengine/PyDoc/SCA_XNORController.py deleted file mode 100644 index 5fb2561f35a..00000000000 --- a/source/gameengine/PyDoc/SCA_XNORController.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for SCA_XNORController -from SCA_IController import * - -class SCA_XNORController(SCA_IController): - """ - An XNOR controller activates when all linked sensors are the same (activated or inative). - - There are no special python methods for this controller. - """ - diff --git a/source/gameengine/PyDoc/SCA_XORController.py b/source/gameengine/PyDoc/SCA_XORController.py deleted file mode 100644 index 10e20fb0945..00000000000 --- a/source/gameengine/PyDoc/SCA_XORController.py +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# Documentation for SCA_XORController -from SCA_IController import * - -class SCA_XORController(SCA_IController): - """ - An XOR controller activates when there is the input is mixed, but not when all are on or off. - - There are no special python methods for this controller. - """ - diff --git a/source/gameengine/PyDoc/WhatsNew.py b/source/gameengine/PyDoc/WhatsNew.py deleted file mode 100644 index 4d86e6ef3c4..00000000000 --- a/source/gameengine/PyDoc/WhatsNew.py +++ /dev/null @@ -1,34 +0,0 @@ -# $Id$ -""" -New Python Functionality in this Version of Blender -=================================================== - -This document lists what has been changed in the Game Engine Python API. - -Blender CVS - - Added L{KX_GameObject}.getDistanceTo() method. (thanks Charlie C) - - Added L{KX_PolygonMaterial} module - -Blender 2.36 ------------- - - Added L{KX_CameraActuator} methods (thanks snail) - -Blender 2.35 ------------- - - Added tic rate methods to L{GameLogic} - - Added stereo eye separation and focal length methods to L{Rasterizer}. - - Fixed L{Rasterizer}.makeScreenshot() method. - - Added setLogicTicRate() and setPhysicsTicRate() to L{GameLogic} - -Blender 2.34 ------------- - - - Added getType() and setType() to L{BL_ActionActuator} and L{KX_SoundActuator} (sgefant) - - New Scene module: L{KX_Scene} - - New Camera module: L{KX_Camera} - - New Light module: L{KX_LightObject} - - Added attributes to L{KX_GameObject}, L{KX_VertexProxy} - - L{KX_SCA_AddObjectActuator}.setObject(), L{KX_TrackToActuator}.setObject() and - L{KX_SceneActuator}.setCamera() now accept L{KX_GameObject}s as parameters - -""" From df1879783aba023bb0ab7d48a5faf0ec8ebe5eb2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 May 2009 12:26:54 +0000 Subject: [PATCH 227/444] use epy deprecated field and link to attributes --- source/gameengine/PyDoc/GameTypes.py | 521 ++++++++++++++------------- 1 file changed, 278 insertions(+), 243 deletions(-) diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index a22f63854ea..d1b92e37099 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -67,16 +67,15 @@ class SCA_ILogicBrick(CValue): @group Deprecated: getOwner, setExecutePriority, getExecutePriority """ + #--The following methods are deprecated-- def getOwner(): """ Gets the game object associated with this logic brick. - Deprecated: Use the "owner" property instead. - + @deprecated: Use the L{owner} property instead. @rtype: L{KX_GameObject} """ - - #--The following methods are deprecated-- + def setExecutePriority(priority): """ Sets the priority of this logic brick. @@ -84,8 +83,7 @@ class SCA_ILogicBrick(CValue): This determines the order controllers are evaluated, and actuators are activated. Bricks with lower priority will be executed first. - Deprecated: Use the "executePriority" property instead. - + @deprecated: Use the L{executePriority} property instead. @type priority: integer @param priority: the priority of this logic brick. """ @@ -93,8 +91,7 @@ class SCA_ILogicBrick(CValue): """ Gets the execution priority of this logic brick. - Deprecated: Use the "executePriority" property instead. - + @deprecated: Use the L{executePriority} property instead. @rtype: integer @return: this logic bricks current priority. """ @@ -236,40 +233,35 @@ class SCA_IController(SCA_ILogicBrick): def getState(): """ - DEPRECATED: use the state property Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. This for instance will always be true however you could compare with a previous state to see when the state was activated. GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState() - + @deprecated: Use the L{state} property @rtype: int """ def getSensors(): """ - DEPRECATED: use the sensors property Gets a list of all sensors attached to this controller. - + @deprecated: use the L{sensors} property @rtype: list [L{SCA_ISensor}] """ def getSensor(name): """ - DEPRECATED: use the sensors[name] property Gets the named linked sensor. - + @deprecated: use the L{sensors}[name] property @type name: string @rtype: L{SCA_ISensor} """ def getActuators(): """ - DEPRECATED: use the actuators property Gets a list of all actuators linked to this controller. - + @deprecated: Use the L{actuators} property @rtype: list [L{SCA_IActuator}] """ def getActuator(name): """ - DEPRECATED: use the actuators[name] property Gets the named linked actuator. - + @deprecated: use the L{actuators}[name] property @type name: string @rtype: L{SCA_IActuator} """ @@ -325,9 +317,8 @@ class BL_ActionActuator(SCA_IActuator): #--The following methods are deprecated-- def setAction(action, reset = True): """ - DEPRECATED: use the 'action' property Sets the current action. - + @deprecated: use the L{action} property @param action: The name of the action to set as the current action. @type action: string @param reset: Optional parameter indicating whether to reset the @@ -339,36 +330,33 @@ class BL_ActionActuator(SCA_IActuator): def setStart(start): """ - DEPRECATED: use the 'start' property Specifies the starting frame of the animation. - + @deprecated: Use the L{start} property @param start: the starting frame of the animation @type start: float """ def setEnd(end): """ - DEPRECATED: use the 'end' property Specifies the ending frame of the animation. - + @deprecated: use the L{end} property @param end: the ending frame of the animation @type end: float """ def setBlendin(blendin): """ - DEPRECATED: use the 'blendin' property Specifies the number of frames of animation to generate when making transitions between actions. - + @deprecated: use the L{blendin} property @param blendin: the number of frames in transition. @type blendin: float """ def setPriority(priority): """ - DEPRECATED: use the 'priority' property Sets the priority of this actuator. + @deprecated: Use use the L{priority} property @param priority: Specifies the new priority. Actuators will lower priority numbers will override actuators with higher numbers. @@ -376,131 +364,131 @@ class BL_ActionActuator(SCA_IActuator): """ def setFrame(frame): """ - DEPRECATED: use the 'frame' property Sets the current frame for the animation. + @deprecated: use the L{frame} property @param frame: Specifies the new current frame for the animation @type frame: float """ def setProperty(prop): """ - DEPRECATED: use the 'property' property Sets the property to be used in FromProp playback mode. + @deprecated: use the L{property} property @param prop: the name of the property to use. @type prop: string. """ def setBlendtime(blendtime): """ - DEPRECATED: use the 'blendTime' property Sets the internal frame timer. - + Allows the script to directly modify the internal timer used when generating transitions between actions. + @deprecated: use the L{blendTime} property @param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0. @type blendtime: float """ def setType(mode): """ - DEPRECATED: use the 'type' property Sets the operation mode of the actuator + @deprecated: use the L{type} property @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND @type mode: integer """ def setContinue(cont): """ - DEPRECATED: use the 'continue' property Set the actions continue option True or False. see getContinue. + @deprecated: use the L{continue} property @param cont: The continue option. @type cont: bool """ def getType(): """ - DEPRECATED: use the 'type' property Returns the operation mode of the actuator - + + @deprecated: use the L{type} property @rtype: integer @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND """ def getContinue(): """ - DEPRECATED: use the 'continue' property When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. - + + @deprecated: use the L{useContinue} property @rtype: bool """ def getAction(): """ - DEPRECATED: use the 'action' property getAction() returns the name of the action associated with this actuator. + @deprecated: use the L{action} property @rtype: string """ def getStart(): """ - DEPRECATED: use the 'start' property Returns the starting frame of the action. + @deprecated: use the L{start} property @rtype: float """ def getEnd(): """ - DEPRECATED: use the 'end' property Returns the last frame of the action. + @deprecated: use the L{end} property @rtype: float """ def getBlendin(): """ - DEPRECATED: use the 'blendin' property Returns the number of interpolation animation frames to be generated when this actuator is triggered. + @deprecated: use the L{blendin} property @rtype: float """ def getPriority(): """ - DEPRECATED: use the 'priority' property Returns the priority for this actuator. Actuators with lower Priority numbers will override actuators with higher numbers. + @deprecated: use the L{priority} property @rtype: integer """ def getFrame(): """ - DEPRECATED: use the 'frame' property Returns the current frame number. + @deprecated: use the L{frame} property @rtype: float """ def getProperty(): """ - DEPRECATED: use the 'property' property Returns the name of the property to be used in FromProp mode. + @deprecated: use the L{property} property @rtype: string """ def setFrameProperty(prop): """ - DEPRECATED: use the 'frameProperty' property + @deprecated: use the L{frameProperty} property @param prop: A string specifying the property of the object that will be updated with the action frame number. @type prop: string """ def getFrameProperty(): """ - DEPRECATED: use the 'frameProperty' property Returns the name of the property that is set to the current frame number. + @deprecated: use the L{frameProperty} property @rtype: string """ @@ -783,9 +771,9 @@ class BL_ShapeActionActuator(SCA_IActuator): """ def setAction(action, reset = True): """ - DEPRECATED: use the 'action' property Sets the current action. + @deprecated: use the L{action} property @param action: The name of the action to set as the current action. @type action: string @param reset: Optional parameter indicating whether to reset the @@ -797,36 +785,36 @@ class BL_ShapeActionActuator(SCA_IActuator): def setStart(start): """ - DEPRECATED: use the 'start' property Specifies the starting frame of the animation. + @deprecated: use the L{start} property @param start: the starting frame of the animation @type start: float """ def setEnd(end): """ - DEPRECATED: use the 'end' property Specifies the ending frame of the animation. + @deprecated: use the L{end} property @param end: the ending frame of the animation @type end: float """ def setBlendin(blendin): """ - DEPRECATED: use the 'blendin' property Specifies the number of frames of animation to generate when making transitions between actions. + @deprecated: use the L{blendin} property @param blendin: the number of frames in transition. @type blendin: float """ def setPriority(priority): """ - DEPRECATED: use the 'priority' property Sets the priority of this actuator. + @deprecated: use the L{priority} property @param priority: Specifies the new priority. Actuators will lower priority numbers will override actuators with higher numbers. @@ -834,114 +822,114 @@ class BL_ShapeActionActuator(SCA_IActuator): """ def setFrame(frame): """ - DEPRECATED: use the 'frame' property Sets the current frame for the animation. + @deprecated: use the L{frame} property @param frame: Specifies the new current frame for the animation @type frame: float """ def setProperty(prop): """ - DEPRECATED: use the 'property' property Sets the property to be used in FromProp playback mode. + @deprecated: use the L{property} property @param prop: the name of the property to use. @type prop: string. """ def setBlendtime(blendtime): """ - DEPRECATED: use the 'blendTime' property Sets the internal frame timer. - + Allows the script to directly modify the internal timer used when generating transitions between actions. + @deprecated: use the L{blendTime} property @param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0. @type blendtime: float """ def setType(mode): """ - DEPRECATED: use the 'type' property Sets the operation mode of the actuator + @deprecated: use the L{type} property @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND @type mode: integer """ def getType(): """ - DEPRECATED: use the 'type' property Returns the operation mode of the actuator - + + @deprecated: use the L{type} property @rtype: integer @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND """ def getAction(): """ - DEPRECATED: use the 'action' property getAction() returns the name of the action associated with this actuator. + @deprecated: use the L{action} property @rtype: string """ def getStart(): """ - DEPRECATED: use the 'start' property Returns the starting frame of the action. + @deprecated: use the L{start} property @rtype: float """ def getEnd(): """ - DEPRECATED: use the 'end' property Returns the last frame of the action. + @deprecated: use the L{end} property @rtype: float """ def getBlendin(): """ - DEPRECATED: use the 'blendin' property Returns the number of interpolation animation frames to be generated when this actuator is triggered. + @deprecated: use the L{blendin} property @rtype: float """ def getPriority(): """ - DEPRECATED: use the 'priority' property Returns the priority for this actuator. Actuators with lower Priority numbers will override actuators with higher numbers. + @deprecated: use the L{priority} property @rtype: integer """ def getFrame(): """ - DEPRECATED: use the 'frame' property Returns the current frame number. + @deprecated: use the L{frame} property @rtype: float """ def getProperty(): """ - DEPRECATED: use the 'property' property Returns the name of the property to be used in FromProp mode. + @deprecated: use the L{property} property @rtype: string """ def setFrameProperty(prop): """ - DEPRECATED: use the 'frameProperty' property + @deprecated: use the L{frameProperty} property @param prop: A string specifying the property of the object that will be updated with the action frame number. @type prop: string """ def getFrameProperty(): """ - DEPRECATED: use the 'frameProperty' property Returns the name of the property that is set to the current frame number. + @deprecated: use the L{frameProperty} property @rtype: string """ @@ -1080,17 +1068,17 @@ class KX_CDActuator(SCA_IActuator): """ def setGain(gain): """ - DEPRECATED: Use the volume property. Sets the gain (volume) of the CD. + @deprecated: Use the L{volume} property. @type gain: float @param gain: the gain to set the CD to. 0.0 = silent, 1.0 = max volume. """ def getGain(): """ - DEPRECATED: Use the volume property. Gets the current gain (volume) of the CD. + @deprecated: Use the L{volume} property. @rtype: float @return: Between 0.0 (silent) and 1.0 (max volume) """ @@ -1468,16 +1456,16 @@ class KX_GameActuator(SCA_IActuator): """ def getFile(): """ - DEPRECATED: use the file property Returns the filename of the new .blend file to load. + @deprecated: use the L{file} property @rtype: string """ def setFile(filename): """ - DEPRECATED: use the file property Sets the new .blend file to load. + @deprecated: use the L{file} property @param filename: The file name this actuator will load. @type filename: string """ @@ -1514,13 +1502,16 @@ class KX_GameObject(SCA_IObject): @ivar occlusion: occlusion capability flag. @type occlusion: boolean @ivar position: The object's position. - DEPRECATED: use localPosition and worldPosition + + deprecated: use L{localPosition} and L{worldPosition} @type position: list [x, y, z] On write: local position, on read: world position @ivar orientation: The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. - DEPRECATED: use localOrientation and worldOrientation + + deprecated: use L{localOrientation} and L{worldOrientation} @type orientation: 3x3 Matrix [[float]] On write: local orientation, on read: world orientation @ivar scaling: The object's scaling factor. list [sx, sy, sz] - DEPRECATED: use localScaling and worldScaling + + deprecated: use L{localScaling} and L{worldScaling} @type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. @type localOrientation: 3x3 Matrix [[float]] @@ -1570,8 +1561,9 @@ class KX_GameObject(SCA_IObject): """ def getVisible(): """ - Gets the game object's visible flag. (B{deprecated}) + Gets the game object's visible flag. + @deprecated: use L{visible} @rtype: boolean """ def setVisible(visible, recursive): @@ -1592,24 +1584,25 @@ class KX_GameObject(SCA_IObject): """ def getState(): """ - Gets the game object's state bitmask. (B{deprecated}) + Gets the game object's state bitmask. + @deprecated: use L{state} @rtype: int @return: the objects state. """ def setState(state): """ - Sets the game object's state flag. (B{deprecated}). + Sets the game object's state flag. The bitmasks for states from 1 to 30 can be set with (1<<0, 1<<1, 1<<2 ... 1<<29) - + @deprecated: use L{state} @type state: integer """ def setPosition(pos): """ - Sets the game object's position. (B{deprecated}) + Sets the game object's position. Global coordinates for root object, local for child objects. - + @deprecated: use L{localPosition} @type pos: [x, y, z] @param pos: the new position, in local coordinates. """ @@ -1622,15 +1615,17 @@ class KX_GameObject(SCA_IObject): """ def getPosition(): """ - Gets the game object's position. (B{deprecated}) + Gets the game object's position. + @deprecated: use L{worldPosition} @rtype: list [x, y, z] @return: the object's position in world coordinates. """ def setOrientation(orn): """ - Sets the game object's orientation. (B{deprecated}) + Sets the game object's orientation. + @deprecated: use L{localOrientation} @type orn: 3x3 rotation matrix, or Quaternion. @param orn: a rotation matrix specifying the new rotation. @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. @@ -1662,8 +1657,9 @@ class KX_GameObject(SCA_IObject): """ def getOrientation(): """ - Gets the game object's orientation. (B{deprecated}) + Gets the game object's orientation. + @deprecated: use L{worldOrientation} @rtype: 3x3 rotation matrix @return: The game object's rotation matrix @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. @@ -1776,8 +1772,9 @@ class KX_GameObject(SCA_IObject): """ def getMass(): """ - Gets the game object's mass. (B{deprecated}) + Gets the game object's mass. + @deprecated: use L{mass} @rtype: float @return: the object's mass. """ @@ -1827,8 +1824,9 @@ class KX_GameObject(SCA_IObject): """ def getParent(): """ - Gets this object's parent. (B{deprecated}) + Gets this object's parent. + @deprecated: use L{parent} @rtype: L{KX_GameObject} @return: this object's parent object, or None if this object has no parent. """ @@ -2006,8 +2004,9 @@ class KX_IpoActuator(SCA_IActuator): """ def set(mode, startframe, endframe, force): """ - Sets the properties of the actuator. (B{deprecated}) + Sets the properties of the actuator. + @deprecated: use other attributes. @param mode: "Play", "PingPong", "Flipper", "LoopStop", "LoopEnd" or "FromProp" @type mode: string @param startframe: first frame to use @@ -2019,79 +2018,91 @@ class KX_IpoActuator(SCA_IActuator): """ def setProperty(property): """ - Sets the name of the property to be used in FromProp mode. (B{deprecated}) + Sets the name of the property to be used in FromProp mode. + @deprecated: use L{propName} @type property: string """ def setStart(startframe): """ - Sets the frame from which the IPO starts playing. (B{deprecated}) + Sets the frame from which the IPO starts playing. + @deprecated: use L{startFrame} @type startframe: integer """ def getStart(): """ - Returns the frame from which the IPO starts playing. (B{deprecated}) + Returns the frame from which the IPO starts playing. + @deprecated: use L{startFrame} @rtype: integer """ def setEnd(endframe): """ - Sets the frame at which the IPO stops playing. (B{deprecated}) + Sets the frame at which the IPO stops playing. + @deprecated: use L{endFrame} @type endframe: integer """ def getEnd(): """ - Returns the frame at which the IPO stops playing. (B{deprecated}) + Returns the frame at which the IPO stops playing. + @deprecated: use L{endFrame} @rtype: integer """ def setIpoAsForce(force): """ - Set whether to interpret the ipo as a force rather than a displacement. (B{deprecated}) + Set whether to interpret the ipo as a force rather than a displacement. + @deprecated: use L{useIpoAsForce} @type force: boolean @param force: KX_TRUE or KX_FALSE """ def getIpoAsForce(): """ - Returns whether to interpret the ipo as a force rather than a displacement. (B{deprecated}) + Returns whether to interpret the ipo as a force rather than a displacement. + @deprecated: use L{useIpoAsForce} @rtype: boolean """ def setIpoAdd(add): """ - Set whether to interpret the ipo as additive rather than absolute. (B{deprecated}) + Set whether to interpret the ipo as additive rather than absolute. + @deprecated: use L{useIpoAdd} @type add: boolean @param add: KX_TRUE or KX_FALSE """ def getIpoAdd(): """ - Returns whether to interpret the ipo as additive rather than absolute. (B{deprecated}) + Returns whether to interpret the ipo as additive rather than absolute. + @deprecated: use L{useIpoAdd} @rtype: boolean """ def setType(mode): """ - Sets the operation mode of the actuator. (B{deprecated}) + Sets the operation mode of the actuator. + @deprecated: use L{type} @param mode: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND @type mode: string """ def getType(): """ - Returns the operation mode of the actuator. (B{deprecated}) + Returns the operation mode of the actuator. + @deprecated: use L{type} @rtype: integer @return: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND """ def setForceIpoActsLocal(local): """ Set whether to apply the force in the object's local - coordinates rather than the world global coordinates. (B{deprecated}) + coordinates rather than the world global coordinates. + @deprecated: use L{useIpoLocal} @param local: Apply the ipo-as-force in the object's local coordinates? (KX_TRUE, KX_FALSE) @type local: boolean @@ -2099,7 +2110,9 @@ class KX_IpoActuator(SCA_IActuator): def getForceIpoActsLocal(): """ Return whether to apply the force in the object's local - coordinates rather than the world global coordinates. (B{deprecated}) + coordinates rather than the world global coordinates. + + @deprecated: use L{useIpoLocal} """ class KX_LightObject(KX_GameObject): @@ -2289,17 +2302,17 @@ class SCA_MouseSensor(SCA_ISensor): def getXPosition(): """ - DEPRECATED: use the position property Gets the x coordinate of the mouse. + @deprecated: use the L{position} property @rtype: integer @return: the current x coordinate of the mouse, in frame coordinates (pixels) """ def getYPosition(): """ - DEPRECATED: use the position property Gets the y coordinate of the mouse. + @deprecated: use the L{position} property @rtype: integer @return: the current y coordinate of the mouse, in frame coordinates (pixels). """ @@ -2337,43 +2350,49 @@ class KX_MouseFocusSensor(SCA_MouseSensor): def getHitNormal(): """ - Returns the normal (in worldcoordinates) at the point of collision where the object was hit by this ray. (B{deprecated}) - + Returns the normal (in worldcoordinates) at the point of collision where the object was hit by this ray. + + @deprecated: use the L{hitNormal} property @rtype: list [x, y, z] @return: the ray collision normal. """ def getHitObject(): """ - Returns the object that was hit by this ray or None. (B{deprecated}) + Returns the object that was hit by this ray or None. + @deprecated: use the L{hitObject} property @rtype: L{KX_GameObject} or None @return: the collision object. """ def getHitPosition(): """ - Returns the position (in worldcoordinates) at the point of collision where the object was hit by this ray. (B{deprecated}) + Returns the position (in worldcoordinates) at the point of collision where the object was hit by this ray. + @deprecated: use the L{hitPosition} property @rtype: list [x, y, z] @return: the ray collision position. """ def getRayDirection(): """ - Returns the normalized direction (in worldcoordinates) of the ray cast by the mouse. (B{deprecated}) + Returns the normalized direction (in worldcoordinates) of the ray cast by the mouse. + @deprecated: use the L{rayDirection} property @rtype: list [x, y, z] @return: the ray direction. """ def getRaySource(): """ - Returns the position (in worldcoordinates) the ray was cast from by the mouse. (B{deprecated}) + Returns the position (in worldcoordinates) the ray was cast from by the mouse. + @deprecated: use the L{raySource} property @rtype: list [x, y, z] @return: the ray source. """ def getRayTarget(): """ - Returns the target of the ray (in worldcoordinates) that seeks the focus object. (B{deprecated}) + Returns the target of the ray (in worldcoordinates) that seeks the focus object. + @deprecated: use the L{rayTarget} property @rtype: list [x, y, z] @return: the ray target. """ @@ -2398,43 +2417,45 @@ class KX_TouchSensor(SCA_ISensor): #--The following methods are deprecated, please use properties instead. def setProperty(name): """ - DEPRECATED: use the property property Set the property or material to collide with. Use setTouchMaterial() to switch between properties and materials. + + @deprecated: use the L{property} property @type name: string """ def getProperty(): """ - DEPRECATED: use the property property Returns the property or material to collide with. Use getTouchMaterial() to find out whether this sensor looks for properties or materials. (B{deprecated}) + @deprecated: use the L{property} property @rtype: string """ def getHitObject(): """ - DEPRECATED: use the objectHit property - Returns the last object hit by this touch sensor. (B{deprecated}) + Returns the last object hit by this touch sensor. + @deprecated: use the L{objectHit} property @rtype: L{KX_GameObject} """ def getHitObjectList(): """ - DEPRECATED: use the objectHitList property Returns a list of all objects hit in the last frame. (B{deprecated}) Only objects that have the requisite material/property are listed. + @deprecated: use the L{objectHitList} property @rtype: L{CListValue} of L{KX_GameObject} """ def getTouchMaterial(): """ - DEPRECATED: use the useMaterial property Returns KX_TRUE if this sensor looks for a specific material, KX_FALSE if it looks for a specific property. (B{deprecated}) + + @deprecated: use the L{useMaterial} property """ class KX_NearSensor(KX_TouchSensor): @@ -2462,31 +2483,31 @@ class KX_NetworkMessageActuator(SCA_IActuator): """ def setToPropName(name): """ - DEPRECATED: Use the propName property instead. Messages will only be sent to objects with the given property name. + @deprecated: Use the L{propName} property instead. @type name: string """ def setSubject(subject): """ - DEPRECATED: Use the subject property instead. Sets the subject field of the message. + @deprecated: Use the L{subject} property instead. @type subject: string """ def setBodyType(bodytype): """ - DEPRECATED: Use the usePropBody property instead. Sets the type of body to send. + @deprecated: Use the L{usePropBody} property instead. @type bodytype: boolean @param bodytype: True to send the value of a property, False to send the body text. """ def setBody(body): """ - DEPRECATED: Use the body property instead. Sets the message body. + deprecated: Use the L{body} property instead. @type body: string @param body: if the body type is True, this is the name of the property to send. if the body type is False, this is the text to send. @@ -2512,39 +2533,39 @@ class KX_NetworkMessageSensor(SCA_ISensor): def setSubjectFilterText(subject): """ - DEPRECATED: Use the subject property instead. Change the message subject text that this sensor is listening to. + @deprecated: Use the L{subject} property instead. @type subject: string @param subject: the new message subject to listen for. """ def getFrameMessageCount(): """ - DEPRECATED: Use the frameMessageCount property instead. Get the number of messages received since the last frame. + @deprecated: Use the L{frameMessageCount} property instead. @rtype: integer """ def getBodies(): """ - DEPRECATED: Use the bodies property instead. Gets the list of message bodies. + @deprecated: Use the L{bodies} property instead. @rtype: list """ def getSubject(): """ - DEPRECATED: Use the subject property instead. Gets the message subject this sensor is listening for from the Subject: field. + @deprecated: Use the L{subject} property instead. @rtype: string """ def getSubjects(): """ - DEPRECATED: Use the subjects property instead. Gets the list of message subjects received. + @deprecated: Use the L{subjects} property instead. @rtype: list """ @@ -2803,17 +2824,18 @@ class KX_ParentActuator(SCA_IActuator): """ def setObject(object): """ - DEPRECATED: Use the object property. Sets the object to set as parent. Object can be either a L{KX_GameObject} or the name of the object. + @deprecated: Use the L{object} property. @type object: L{KX_GameObject}, string or None """ def getObject(name_only = 1): """ - DEPRECATED: Use the object property. Returns the name of the object to change to. + + @deprecated: Use the L{object} property. @type name_only: bool @param name_only: optional argument, when 0 return a KX_GameObject @rtype: string, KX_GameObject or None if no object is set @@ -2889,7 +2911,7 @@ class KX_PolyProxy(SCA_IObject): @ivar matname: The name of polygon material, empty if no material. @type matname: string @ivar material: The material of the polygon - @type material: L{KX_PolygonMaterial} or KX_BlenderMaterial + @type material: L{KX_PolygonMaterial} or L{KX_BlenderMaterial} @ivar texture: The texture name of the polygon. @type texture: string @ivar matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy @@ -2920,7 +2942,7 @@ class KX_PolyProxy(SCA_IObject): """ Returns the polygon material - @rtype: L{KX_PolygonMaterial} or KX_BlenderMaterial + @rtype: L{KX_PolygonMaterial} or L{KX_BlenderMaterial} """ def getTextureName(): """ @@ -3283,6 +3305,7 @@ class KX_RadarSensor(KX_NearSensor): Returns the origin of the cone with which to test. The origin is in the middle of the cone. + @deprecated: Use the L{coneOrigin} property. @rtype: list [x, y, z] """ @@ -3290,6 +3313,7 @@ class KX_RadarSensor(KX_NearSensor): """ Returns the center of the bottom face of the cone with which to test. + @deprecated: Use the L{coneTarget} property. @rtype: list [x, y, z] """ @@ -3328,30 +3352,30 @@ class KX_RaySensor(SCA_ISensor): def getHitObject(): """ - DEPRECATED: Use the hitObject property instead. Returns the game object that was hit by this ray. + @deprecated: Use the L{hitObject} property instead. @rtype: KX_GameObject """ def getHitPosition(): """ - DEPRECATED: Use the hitPosition property instead. Returns the position (in worldcoordinates) where the object was hit by this ray. + @deprecated: Use the L{hitPosition} property instead. @rtype: list [x, y, z] """ def getHitNormal(): """ - DEPRECATED: Use the hitNormal property instead. Returns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray. + @deprecated: Use the L{hitNormal} property instead. @rtype: list [nx, ny, nz] """ def getRayDirection(): """ - DEPRECATED: Use the rayDirection property instead. Returns the direction from the ray (in worldcoordinates) + @deprecated: Use the L{rayDirection} property instead. @rtype: list [dx, dy, dz] """ @@ -3378,7 +3402,6 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): """ def setObject(object): """ - DEPRECATED: use the object property Sets the game object to add. A copy of the object will be added to the scene when the actuator is activated. @@ -3387,40 +3410,42 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): object can either be a L{KX_GameObject} or the name of an object or None. + @deprecated: use the L{object} property @type object: L{KX_GameObject}, string or None """ def getObject(name_only = 0): """ - DEPRECATED: use the object property Returns the name of the game object to be added. Returns None if no game object has been assigned to be added. + + @deprecated: use the L{object} property @type name_only: bool @param name_only: optional argument, when 0 return a KX_GameObject @rtype: string, KX_GameObject or None if no object is set """ def setTime(time): """ - DEPRECATED: use the time property Sets the lifetime of added objects, in frames. If time == 0, the object will last forever. + @deprecated: use the L{time} property @type time: integer @param time: The minimum value for time is 0. """ def getTime(): """ - DEPRECATED: use the time property Returns the lifetime of the added object, in frames. + @deprecated: use the L{time} property @rtype: integer """ def setLinearVelocity(vx, vy, vz): """ - DEPRECATED: use the linearVelocity property Sets the initial linear velocity of added objects. + @deprecated: use the L{linearVelocity} property @type vx: float @param vx: the x component of the initial linear velocity. @type vy: float @@ -3430,16 +3455,16 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): """ def getLinearVelocity(): """ - DEPRECATED: use the linearVelocity property Returns the initial linear velocity of added objects. + @deprecated: use the L{linearVelocity} property @rtype: list [vx, vy, vz] """ def setAngularVelocity(vx, vy, vz): """ - DEPRECATED: use the angularVelocity property Sets the initial angular velocity of added objects. + @deprecated: use the L{angularVelocity} property @type vx: float @param vx: the x component of the initial angular velocity. @type vy: float @@ -3449,16 +3474,16 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): """ def getAngularVelocity(): """ - DEPRECATED: use the angularVelocity property Returns the initial angular velocity of added objects. + @deprecated: use the L{angularVelocity} property @rtype: list [vx, vy, vz] """ def getLastCreatedObject(): """ - DEPRECATED: use the objectLastCreated property Returns the last object created by this actuator. + @deprecated: use the L{objectLastCreated} property @rtype: L{KX_GameObject} @return: A L{KX_GameObject} or None if no object has been created. """ @@ -3481,18 +3506,19 @@ class KX_SCA_DynamicActuator(SCA_IActuator): """ def setOperation(operation): """ - DEPRECATED: Use the operation property instead. Set the type of operation when the actuator is activated: - 0 = restore dynamics - 1 = disable dynamics - 2 = enable rigid body - 3 = disable rigid body - 4 = set mass + + @deprecated: Use the L{operation} property instead. """ def getOperation(): """ - DEPRECATED: Use the operation property instead. return the type of operation + @deprecated: Use the L{operation} property instead. """ class KX_SCA_EndObjectActuator(SCA_IActuator): @@ -3562,19 +3588,19 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): """ def setMesh(name): """ - DEPRECATED: Use the mesh property instead. Sets the name of the mesh that will replace the current one. When the name is None it will unset the mesh value so no action is taken. + @deprecated: Use the L{mesh} property instead. @type name: string or None """ def getMesh(): """ - DEPRECATED: Use the mesh property instead. Returns the name of the mesh that will replace the current one. Returns None if no mesh has been scheduled to be added. + @deprecated: Use the L{mesh} property instead. @rtype: string or None """ def instantReplaceMesh(): @@ -3642,23 +3668,23 @@ class KX_Scene(PyObjectPlus): def getLightList(): """ - DEPRECATED: use the 'lights' property. Returns the list of lights in the scene. + @deprecated: Use the L{lights} property instead. @rtype: list [L{KX_LightObject}] """ def getObjectList(): """ - DEPRECATED: use the 'objects' property. Returns the list of objects in the scene. + @deprecated: Use the L{objects} property instead. @rtype: list [L{KX_GameObject}] """ def getName(): """ - DEPRECATED: use the 'name' property. Returns the name of the scene. + @deprecated: Use the L{name} property instead. @rtype: string """ @@ -3699,48 +3725,48 @@ class KX_SceneActuator(SCA_IActuator): """ def setUseRestart(flag): """ - DEPRECATED: use the useRestart property instead Set flag to True to restart the scene. + @deprecated: Use the L{useRestart} property instead. @type flag: boolean """ def setScene(scene): """ - DEPRECATED: use the scene property instead Sets the name of the scene to change to/overlay/underlay/remove/suspend/resume. + @deprecated: use the L{scene} property instead. @type scene: string """ def setCamera(camera): """ - DEPRECATED: use the camera property instead Sets the camera to change to. Camera can be either a L{KX_Camera} or the name of the camera. + @deprecated: use the L{camera} property instead. @type camera: L{KX_Camera} or string """ def getUseRestart(): """ - DEPRECATED: use the useRestart property instead Returns True if the scene will be restarted. + @deprecated: use the L{useRestart} property instead. @rtype: boolean """ def getScene(): """ - DEPRECATED: use the scene property instead Returns the name of the scene to change to/overlay/underlay/remove/suspend/resume. Returns an empty string ("") if no scene has been set. + @deprecated: use the L{scene} property instead. @rtype: string """ def getCamera(): """ - DEPRECATED: use the camera property instead Returns the name of the camera to change to. + @deprecated: use the L{camera} property instead. @rtype: string """ @@ -3790,16 +3816,16 @@ class KX_SoundActuator(SCA_IActuator): """ def setFilename(filename): """ - DEPRECATED: Use the filename property instead. Sets the filename of the sound this actuator plays. + @deprecated: Use the L{filename} property instead. @type filename: string """ def getFilename(): """ - DEPRECATED: Use the filename property instead. Returns the filename of the sound this actuator plays. + @deprecated: Use the L{filename} property instead. @rtype: string """ def startSound(): @@ -3816,76 +3842,77 @@ class KX_SoundActuator(SCA_IActuator): """ def setGain(gain): """ - DEPRECATED: Use the volume property instead Sets the gain (volume) of the sound + @deprecated: Use the L{volume} property instead. @type gain: float @param gain: 0.0 (quiet) <= gain <= 1.0 (loud) """ def getGain(): """ - DEPRECATED: Use the volume property instead. Gets the gain (volume) of the sound. + @deprecated: Use the L{volume} property instead. @rtype: float """ def setPitch(pitch): """ - DEPRECATED: Use the pitch property instead. Sets the pitch of the sound. + @deprecated: Use the L{pitch} property instead. @type pitch: float """ def getPitch(): """ - DEPRECATED: Use the pitch property instead. Returns the pitch of the sound. + @deprecated: Use the L{pitch} property instead. @rtype: float """ def setRollOffFactor(rolloff): """ - DEPRECATED: Use the rollOffFactor property instead. Sets the rolloff factor for the sounds. Rolloff defines the rate of attenuation as the sound gets further away. Higher rolloff factors shorten the distance at which the sound can be heard. + @deprecated: Use the L{rollOffFactor} property instead. @type rolloff: float """ def getRollOffFactor(): """ - DEPRECATED: Use the rollOffFactor property instead. Returns the rolloff factor for the sound. + @deprecated: Use the L{rollOffFactor} property instead. @rtype: float """ def setLooping(loop): """ - DEPRECATED: Use the looping property instead. Sets the loop mode of the actuator. @bug: There are no constants defined for this method! @param loop: - Play Stop 1 - - Play End 2 - - Loop Stop 3 - - Loop End 4 - - Bidirection Stop 5 - - Bidirection End 6 + - Play End 2 + - Loop Stop 3 + - Loop End 4 + - Bidirection Stop 5 + - Bidirection End 6 + + @deprecated: Use the L{looping} property instead. @type loop: integer """ def getLooping(): """ - DEPRECATED: Use the looping property instead. Returns the current loop mode of the actuator. + @deprecated: Use the L{looping} property instead. @rtype: integer """ def setPosition(x, y, z): """ - DEPRECATED: Use the position property instead. Sets the position this sound will come from. + @deprecated: Use the L{position} property instead. @type x: float @param x: The x coordinate of the sound. @type y: float @@ -3895,11 +3922,11 @@ class KX_SoundActuator(SCA_IActuator): """ def setVelocity(vx, vy, vz): """ - DEPRECATED: Use the velocity property instead. Sets the velocity this sound is moving at. The sound's pitch is determined from the velocity. + @deprecated: Use the L{velocity} property instead. @type vx: float @param vx: The vx coordinate of the sound. @type vy: float @@ -3909,29 +3936,29 @@ class KX_SoundActuator(SCA_IActuator): """ def setOrientation(o11, o12, o13, o21, o22, o23, o31, o32, o33): """ - DEPRECATED: Use the orientation property instead. Sets the orientation of the sound. The nine parameters specify a rotation matrix:: | o11, o12, o13 | | o21, o22, o23 | | o31, o32, o33 | + @deprecated: Use the L{orientation} property instead. """ def setType(mode): """ - DEPRECATED: Use the type property instead. Sets the operation mode of the actuator. + @deprecated: Use the L{type} property instead. @param mode: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP @type mode: integer """ def getType(): """ - DEPRECATED: Use the type property instead. Returns the operation mode of the actuator. + @deprecated: Use the L{type} property instead. @rtype: integer @return: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP """ @@ -3958,21 +3985,21 @@ class KX_StateActuator(SCA_IActuator): """ def setOperation(op): """ - DEPRECATED: Use the operation property instead. Set the type of bit operation to be applied on object state mask. Use setMask() to specify the bits that will be modified. + @deprecated: Use the L{operation} property instead. @param op: bit operation (0=Copy, 1=Add, 2=Substract, 3=Invert) @type op: integer """ def setMask(mask): """ - DEPRECATED: Use the mask property instead. Set the value that defines the bits that will be modified by the operation. The bits that are 1 in the value will be updated in the object state, the bits that are 0 are will be left unmodified expect for the Copy operation which copies the value to the object state. + @deprecated: Use the L{mask} property instead. @param mask: bits that will be modified @type mask: integer """ @@ -3998,49 +4025,50 @@ class KX_TrackToActuator(SCA_IActuator): """ def setObject(object): """ - DEPRECATED: Use the object property. Sets the object to track. + @deprecated: Use the L{object} property instead. @type object: L{KX_GameObject}, string or None @param object: Either a reference to a game object or the name of the object to track. """ def getObject(name_only): """ - DEPRECATED: Use the object property. Returns the name of the object to track. + @deprecated: Use the L{object} property instead. @type name_only: bool @param name_only: optional argument, when 0 return a KX_GameObject @rtype: string, KX_GameObject or None if no object is set """ def setTime(time): """ - DEPRECATED: Use the time property. Sets the time in frames with which to delay the tracking motion. + @deprecated: Use the L{time} property instead. @type time: integer """ def getTime(): """ - DEPRECATED: Use the time property. Returns the time in frames with which the tracking motion is delayed. + @deprecated: Use the L{time} property instead. @rtype: integer """ def setUse3D(use3d): """ - DEPRECATED: Use the use3D property. + DEPRECATED: Use the property. Sets the tracking motion to use 3D. + @deprecated: Use the L{use3D} property instead. @type use3d: boolean @param use3d: - True: allow the tracking motion to extend in the z-direction. - False: lock the tracking motion to the x-y plane. """ def getUse3D(): """ - DEPRECATED: Use the use3D property. Returns True if the tracking motion will track in the z direction. + @deprecated: Use the L{use3D} property instead. @rtype: boolean """ @@ -4362,9 +4390,9 @@ class KX_VisibilityActuator(SCA_IActuator): """ def set(visible): """ - DEPRECATED: Use the visibility property instead. Sets whether the actuator makes its parent object visible or invisible. - + + @deprecated: Use the L{visibility} property instead. @param visible: - True: Makes its parent visible. - False: Makes its parent invisible. """ @@ -4431,17 +4459,17 @@ class SCA_ActuatorSensor(SCA_ISensor): """ def getActuator(): """ - DEPRECATED: use the actuator property Return the Actuator with which the sensor operates. + @deprecated: Use the L{actuator} property instead. @rtype: string """ def setActuator(name): """ - DEPRECATED: use the actuator property Sets the Actuator with which to operate. If there is no Actuator of this name, the function has no effect. + @deprecated: Use the L{actuator} property instead. @param name: actuator name @type name: string """ @@ -4475,48 +4503,48 @@ class SCA_DelaySensor(SCA_ISensor): """ def setDelay(delay): """ - DEPRECATED: use the delay property Set the initial delay before the positive trigger. + @deprecated: Use the L{delay} property instead. @param delay: length of the initial OFF period as number of frame, 0 for immediate trigger @type delay: integer """ def setDuration(duration): """ - DEPRECATED: use the duration property Set the duration of the ON pulse after initial delay and the generation of the positive trigger. If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. + @deprecated: Use the L{duration} property instead. @param duration: length of the ON period in number of frame after the initial OFF period @type duration: integer """ def setRepeat(repeat): """ - DEPRECATED: use the repeat property Set if the sensor repeat mode. + @deprecated: Use the L{repeat} property instead. @param repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. @type repeat: integer """ def getDelay(): """ - DEPRECATED: use the delay property Return the delay parameter value. + @deprecated: Use the L{delay} property instead. @rtype: integer """ def getDuration(): """ - DEPRECATED: use the duration property Return the duration parameter value + @deprecated: Use the L{duration} property instead. @rtype: integer """ def getRepeat(): """ - DEPRECATED: use the repeat property Return the repeat parameter value + @deprecated: Use the L{repeat} property instead. @rtype: KX_TRUE or KX_FALSE """ @@ -4574,29 +4602,32 @@ class SCA_JoystickSensor(SCA_ISensor): """ def getIndex(): """ - DEPRECATED: use the 'index' property. Returns the joystick index to use (from 1 to 8). + + @deprecated: Use the L{index} property instead. @rtype: integer """ def setIndex(index): """ - DEPRECATED: use the 'index' property. Sets the joystick index to use. + + @deprecated: Use the L{index} property instead. @param index: The index of this joystick sensor, Clamped between 1 and 8. @type index: integer @note: This is only useful when you have more then 1 joystick connected to your computer - multiplayer games. """ def getAxis(): """ - DEPRECATED: use the 'axis' property. Returns the current axis this sensor reacts to. See L{getAxisValue()} for the current axis state. + + @deprecated: Use the L{axis} property instead. @rtype: list @return: 2 values returned are [axisIndex, axisDirection] - see L{setAxis()} for their purpose. @note: When the "All Events" toggle is set, this option has no effect. """ def setAxis(axisIndex, axisDirection): """ - DEPRECATED: use the 'axis' property. + @deprecated: Use the L{axis} property instead. @param axisIndex: Set the axis index to use when detecting axis movement. @type axisIndex: integer from 1 to 2 @param axisDirection: Set the axis direction used for detecting motion. 0:right, 1:up, 2:left, 3:down. @@ -4605,8 +4636,9 @@ class SCA_JoystickSensor(SCA_ISensor): """ def getAxisValue(): """ - DEPRECATED: use the 'axisPosition' property. Returns the state of the joysticks axis. See differs to L{getAxis()} returning the current state of the joystick. + + @deprecated: Use the L{axisPosition} property instead. @rtype: list @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. @@ -4617,72 +4649,83 @@ class SCA_JoystickSensor(SCA_ISensor): """ def getThreshold(): """ - DEPRECATED: use the 'threshold' property. Get the axis threshold. See L{setThreshold()} for details. + + @deprecated: Use the L{threshold} property instead. @rtype: integer """ def setThreshold(threshold): """ - DEPRECATED: use the 'threshold' property. Set the axis threshold. + + @deprecated: Use the L{threshold} property instead. @param threshold: Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. @type threshold: integer """ def getButton(): """ - DEPRECATED: use the 'button' property. Returns the button index the sensor reacts to. See L{getButtonValue()} for a list of pressed buttons. + + @deprecated: Use the L{button} property instead. @rtype: integer @note: When the "All Events" toggle is set, this option has no effect. """ def setButton(index): """ - DEPRECATED: use the 'button' property. Sets the button index the sensor reacts to when the "All Events" option is not set. + + @deprecated: Use the L{button} property instead. @note: When the "All Events" toggle is set, this option has no effect. """ def getButtonValue(): """ - DEPRECATED: use the 'getButtonActiveList' method. Returns a list containing the indicies of the currently pressed buttons. + + @deprecated: Use the L{getButtonActiveList} method instead. @rtype: list """ def getHat(): """ - DEPRECATED: use the 'hat' property. Returns the current hat direction this sensor is set to. [hatNumber, hatDirection]. + + @deprecated: Use the L{hat} property instead. @rtype: list @note: When the "All Events" toggle is set, this option has no effect. """ def setHat(index,direction): """ - DEPRECATED: use the 'hat' property. Sets the hat index the sensor reacts to when the "All Events" option is not set. + + @deprecated: Use the L{hat} property instead. @type index: integer """ def getNumAxes(): """ - DEPRECATED: use the 'numAxis' property. Returns the number of axes for the joystick at this index. + + @deprecated: Use the L{numAxis} property instead. @rtype: integer """ def getNumButtons(): """ - DEPRECATED: use the 'numButtons' property. Returns the number of buttons for the joystick at this index. + + @deprecated: Use the L{numButtons} property instead. @rtype: integer """ def getNumHats(): """ - DEPRECATED: use the 'numHats' property. Returns the number of hats for the joystick at this index. + + @deprecated: Use the L{numHats} property instead. @rtype: integer """ def isConnected(): """ - DEPRECATED: use the 'connected' property. Returns True if a joystick is detected at this joysticks index. + + @deprecated: Use the L{connected} property instead. @rtype: bool """ @@ -4731,8 +4774,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Returns the key code this sensor is looking for. - B{DEPRECATED: Use the "key" property instead}. - + @deprecated: Use the L{key} property instead. @rtype: keycode from L{GameKeys} module """ @@ -4740,8 +4782,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Set the key this sensor should listen for. - B{DEPRECATED: Use the "key" property instead}. - + @deprecated: Use the L{key} property instead. @type keycode: keycode from L{GameKeys} module """ @@ -4749,8 +4790,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Returns the key code for the first modifier this sensor is looking for. - B{DEPRECATED: Use the "hold1" property instead}. - + @deprecated: Use the L{hold1} property instead. @rtype: keycode from L{GameKeys} module """ @@ -4758,8 +4798,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Sets the key code for the first modifier this sensor should look for. - B{DEPRECATED: Use the "hold1" property instead}. - + @deprecated: Use the L{hold1} property instead. @type keycode: keycode from L{GameKeys} module """ @@ -4767,8 +4806,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Returns the key code for the second modifier this sensor is looking for. - B{DEPRECATED: Use the "hold2" property instead}. - + @deprecated: Use the L{hold2} property instead. @rtype: keycode from L{GameKeys} module """ @@ -4776,8 +4814,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Sets the key code for the second modifier this sensor should look for. - B{DEPRECATED: Use the "hold2" property instead.} - + @deprecated: Use the L{hold2} property instead. @type keycode: keycode from L{GameKeys} module """ @@ -4785,8 +4822,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Get a list of keys that have either been pressed, or just released this frame. - B{DEPRECATED: Use "events" instead.} - + @deprecated: Use the L{events} property instead. @rtype: list of key status. [[keycode, status]] """ @@ -4794,8 +4830,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Get a list of currently pressed keys that have either been pressed, or just released - B{DEPRECATED: Use "events" instead.} - + @deprecated: Use the L{events} property instead. @rtype: list of key status. [[keycode, status]] """ @@ -4833,36 +4868,36 @@ class SCA_PropertyActuator(SCA_IActuator): """ def setProperty(prop): """ - DEPRECATED: use the 'property' property Set the property on which to operate. If there is no property of this name, the call is ignored. + @deprecated: Use the L{property} property instead. @type prop: string @param prop: The name of the property to set. """ def getProperty(): """ - DEPRECATED: use the 'property' property Returns the name of the property on which to operate. + @deprecated: Use the L{property} property instead. @rtype: string """ def setValue(value): """ - DEPRECATED: use the 'value' property Set the value with which the actuator operates. If the value is not compatible with the type of the property, the subsequent action is ignored. + @deprecated: Use the L{value} property instead. @type value: string """ def getValue(): """ - DEPRECATED: use the 'value' property Gets the value with which this actuator operates. + @deprecated: Use the L{value} property instead. @rtype: string """ @@ -4884,9 +4919,9 @@ class SCA_PropertySensor(SCA_ISensor): def getType(): """ - DEPRECATED: use the type property Gets when to activate this sensor. + @deprecated: Use the L{type} property instead. @return: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, or KX_PROPSENSOR_EXPRESSION. @@ -4894,9 +4929,9 @@ class SCA_PropertySensor(SCA_ISensor): def setType(checktype): """ - DEPRECATED: use the type property Set the type of check to perform. + @deprecated: Use the L{type} property instead. @type checktype: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, or KX_PROPSENSOR_EXPRESSION. @@ -4904,35 +4939,35 @@ class SCA_PropertySensor(SCA_ISensor): def getProperty(): """ - DEPRECATED: use the property property Return the property with which the sensor operates. + @deprecated: Use the L{property} property instead. @rtype: string @return: the name of the property this sensor is watching. """ def setProperty(name): """ - DEPRECATED: use the property property Sets the property with which to operate. If there is no property of that name, this call is ignored. + @deprecated: Use the L{property} property instead. @type name: string. """ def getValue(): """ - DEPRECATED: use the value property Return the value with which the sensor compares to the value of the property. + @deprecated: Use the L{value} property instead. @rtype: string @return: the value of the property this sensor is watching. """ def setValue(value): """ - DEPRECATED: use the value property Set the value with which the sensor operates. If the value is not compatible with the type of the property, the subsequent action is ignored. + @deprecated: Use the L{value} property instead. @type value: string """ @@ -4960,16 +4995,16 @@ class SCA_PythonController(SCA_IController): """ def getScript(): """ - DEPRECATED: use the script property Gets the Python script this controller executes. + @deprecated: Use the L{script} property instead. @rtype: string """ def setScript(script): """ - DEPRECATED: use the script property Sets the Python script this controller executes. + @deprecated: Use the L{script} property instead. @type script: string. """ @@ -5004,46 +5039,46 @@ class SCA_RandomActuator(SCA_IActuator): """ def setSeed(seed): """ - DEPRECATED: use the seed property Sets the seed of the random number generator. Equal seeds produce equal series. If the seed is 0, the generator will produce the same value on every call. + @deprecated: Use the L{seed} property instead. @type seed: integer """ def getSeed(): """ - DEPRECATED: use the seed property Returns the initial seed of the generator. + @deprecated: Use the L{seed} property instead. @rtype: integer """ def getPara1(): """ - DEPRECATED: use the para1 property Returns the first parameter of the active distribution. Refer to the documentation of the generator types for the meaning of this value. + @deprecated: Use the L{para1} property instead. @rtype: float """ def getPara2(): """ - DEPRECATED: use the para2 property Returns the second parameter of the active distribution. Refer to the documentation of the generator types for the meaning of this value. + @deprecated: Use the L{para2} property instead. @rtype: float """ def getDistribution(): """ - DEPRECATED: use the distribution property Returns the type of random distribution. + @deprecated: Use the L{distribution} property instead. @rtype: distribution type @return: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, @@ -5052,19 +5087,19 @@ class SCA_RandomActuator(SCA_IActuator): """ def setProperty(property): """ - DEPRECATED: use the property property Set the property to which the random value is assigned. If the generator and property types do not match, the assignment is ignored. + @deprecated: Use the L{property} property instead. @type property: string @param property: The name of the property to set. """ def getProperty(): """ - DEPRECATED: use the property property Returns the name of the property to set. + @deprecated: Use the L{property} property instead. @rtype: string """ def setBoolConst(value): @@ -5378,9 +5413,9 @@ class KX_Camera(KX_GameObject): def enableViewport(viewport): """ - DEPRECATED: use the isViewport property Use this camera to draw a viewport on the screen (for split screen games or overlay scenes). The viewport region is defined with L{setViewport}. + @deprecated: Use the L{isViewport} property instead. @type viewport: bool @param viewport: the new viewport status """ From 77f321d15fbd39d42700b43909d6d7ec8bbc0262 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Wed, 13 May 2009 15:41:33 +0000 Subject: [PATCH 228/444] Python API ---------- Fix problem with ShrinkWrap PROJECT_OVER_NORMAL setting. --- source/blender/python/api2_2x/Modifier.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/blender/python/api2_2x/Modifier.c b/source/blender/python/api2_2x/Modifier.c index 49220bcd05e..db2afe1072c 100644 --- a/source/blender/python/api2_2x/Modifier.c +++ b/source/blender/python/api2_2x/Modifier.c @@ -1046,7 +1046,7 @@ static PyObject *shrinkwrap_getter( BPy_Modifier * self, int type ) ( md->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) ) ; case EXPP_MOD_PROJECT_OVER_NORMAL: return PyBool_FromLong( ( long ) - ( md->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) ) ; + ( md->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) ) ; case EXPP_MOD_SUBSURFLEVELS: return PyInt_FromLong( ( long )md->subsurfLevels ); default: @@ -1107,10 +1107,10 @@ static int shrinkwrap_setter( BPy_Modifier *self, int type, PyObject *value ) case EXPP_MOD_PROJECT_OVER_Z_AXIS: return EXPP_setBitfield( value, &md->projAxis, MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS, 'h' ); - case EXPP_MOD_PROJECT_OVER_NORMAL: - return EXPP_setBitfield( value, &md->projAxis, - MOD_SHRINKWRAP_PROJECT_OVER_NORMAL, 'h' ); - + case EXPP_MOD_PROJECT_OVER_NORMAL:{ + md->projAxis = MOD_SHRINKWRAP_PROJECT_OVER_NORMAL; + return 0; + } case EXPP_MOD_ALLOW_POS_DIR: return EXPP_setBitfield( value, &md->shrinkOpts, MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR, 'h' ); @@ -1974,8 +1974,7 @@ for var in st.replace(',','').split('\n'): PyConstant_Insert( d, "LOCK_AXIS_X", PyInt_FromLong( EXPP_MOD_LOCK_AXIS_X ) ); PyConstant_Insert( d, "LOCK_AXIS_Y", - PyInt_FromLong( EXPP_MOD_LOCK_AXIS_Y ) ); - + PyInt_FromLong( EXPP_MOD_LOCK_AXIS_Y ) ); PyConstant_Insert( d, "OBJECT_AUX", PyInt_FromLong( EXPP_MOD_OBJECT_AUX ) ); PyConstant_Insert( d, "KEEPDIST", @@ -1985,7 +1984,9 @@ for var in st.replace(',','').split('\n'): PyConstant_Insert( d, "PROJECT_OVER_Y_AXIS", PyInt_FromLong( EXPP_MOD_PROJECT_OVER_Y_AXIS ) ); PyConstant_Insert( d, "PROJECT_OVER_Z_AXIS", - PyInt_FromLong( EXPP_MOD_PROJECT_OVER_Z_AXIS ) ); + PyInt_FromLong( EXPP_MOD_PROJECT_OVER_Z_AXIS ) ); + PyConstant_Insert( d, "PROJECT_OVER_NORMAL", + PyInt_FromLong( EXPP_MOD_PROJECT_OVER_NORMAL ) ); PyConstant_Insert( d, "SUBSURFLEVELS", PyInt_FromLong( EXPP_MOD_SUBSURFLEVELS ) ); PyConstant_Insert( d, "ALLOW_POS_DIR", From f5bacc6c8a6bf06c20301fbfdc36d7b5b9de041d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 13 May 2009 16:48:33 +0000 Subject: [PATCH 229/444] BGE API cleanup: motion actuator. Apply patch from Moguri. --- .../gameengine/Ketsji/KX_ObjectActuator.cpp | 185 ++++++++++++++++-- source/gameengine/Ketsji/KX_ObjectActuator.h | 79 ++++++-- source/gameengine/PyDoc/GameTypes.py | 90 ++++++--- 3 files changed, 298 insertions(+), 56 deletions(-) diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index e3d7a0f4b71..0232e3407b0 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -31,6 +31,7 @@ #include "KX_ObjectActuator.h" #include "KX_GameObject.h" +#include "KX_PyMath.h" // For PyVecTo - should this include be put in PyObjectPlus? #include "KX_IPhysicsController.h" #ifdef HAVE_CONFIG_H @@ -76,7 +77,10 @@ KX_ObjectActuator( { // in servo motion, the force is local if the target velocity is local m_bitLocalFlag.Force = m_bitLocalFlag.LinearVelocity; + + m_pid = m_torque; } + UpdateFuzzyFlags(); } @@ -132,7 +136,7 @@ bool KX_ObjectActuator::Update() MT_Vector3 dv = e - m_previous_error; MT_Vector3 I = m_error_accumulator + e; - m_force = m_torque.x()*e+m_torque.y()*I+m_torque.z()*dv; + m_force = m_pid.x()*e+m_pid.y()*I+m_pid.z()*dv; // to automatically adapt the PID coefficient to mass; m_force *= mass; if (m_bitLocalFlag.Torque) @@ -306,6 +310,7 @@ PyParentObject KX_ObjectActuator::Parents[] = { }; PyMethodDef KX_ObjectActuator::Methods[] = { + // Deprecated -----> {"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_NOARGS}, {"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS}, {"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_NOARGS}, @@ -329,40 +334,163 @@ PyMethodDef KX_ObjectActuator::Methods[] = { {"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_NOARGS}, {"getPID", (PyCFunction) KX_ObjectActuator::sPySetPID, METH_VARARGS}, - + // <----- Deprecated {NULL,NULL} //Sentinel }; PyAttributeDef KX_ObjectActuator::Attributes[] = { - //KX_PYATTRIBUTE_TODO("force"), - //KX_PYATTRIBUTE_TODO("torque"), - //KX_PYATTRIBUTE_TODO("dLoc"), - //KX_PYATTRIBUTE_TODO("dRot"), - //KX_PYATTRIBUTE_TODO("linV"), - //KX_PYATTRIBUTE_TODO("angV"), - //KX_PYATTRIBUTE_TODO("damping"), - //KX_PYATTRIBUTE_TODO("forceLimitX"), - //KX_PYATTRIBUTE_TODO("forceLimitY"), - //KX_PYATTRIBUTE_TODO("forceLimitZ"), - //KX_PYATTRIBUTE_TODO("pid"), + KX_PYATTRIBUTE_VECTOR_RW_CHECK("force", -1000, 1000, false, KX_ObjectActuator, m_force, PyUpdateFuzzyFlags), + KX_PYATTRIBUTE_BOOL_RW("useLocalForce", KX_ObjectActuator, m_bitLocalFlag.Force), + KX_PYATTRIBUTE_VECTOR_RW_CHECK("torque", -1000, 1000, false, KX_ObjectActuator, m_torque, PyUpdateFuzzyFlags), + KX_PYATTRIBUTE_BOOL_RW("useLocalTorque", KX_ObjectActuator, m_bitLocalFlag.Torque), + KX_PYATTRIBUTE_VECTOR_RW_CHECK("dLoc", -1000, 1000, false, KX_ObjectActuator, m_dloc, PyUpdateFuzzyFlags), + 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), + 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), + 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), + KX_PYATTRIBUTE_RW_FUNCTION("forceLimitY", KX_ObjectActuator, pyattr_get_forceLimitY, pyattr_set_forceLimitY), + KX_PYATTRIBUTE_RW_FUNCTION("forceLimitZ", KX_ObjectActuator, pyattr_get_forceLimitZ, pyattr_set_forceLimitZ), + KX_PYATTRIBUTE_VECTOR_RW_CHECK("pid", -100, 200, true, KX_ObjectActuator, m_pid, PyCheckPid), { NULL } //Sentinel }; PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) { py_getattro_up(SCA_IActuator); -}; +} + PyObject* KX_ObjectActuator::py_getattro_dict() { py_getattro_dict_up(SCA_IActuator); } +int KX_ObjectActuator::py_setattro(PyObject *attr, PyObject *value) +{ + py_setattro_up(SCA_IActuator); +} + +/* Attribute get/set functions */ + +PyObject* KX_ObjectActuator::pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_ObjectActuator* self = reinterpret_cast(self_v); + PyObject *retVal = PyList_New(3); + + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[0])); + PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.Torque)); + + return retVal; +} + +int KX_ObjectActuator::pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self = reinterpret_cast(self_v); + + PyObject* seq = PySequence_Fast(value, ""); + if (seq && PySequence_Fast_GET_SIZE(seq) == 3) + { + self->m_drot[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); + self->m_dloc[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); + self->m_bitLocalFlag.Torque = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + + if (!PyErr_Occurred()) + { + Py_DECREF(seq); + return PY_SET_ATTR_SUCCESS; + } + } + + Py_XDECREF(seq); + + PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool"); + return PY_SET_ATTR_FAIL; +} + +PyObject* KX_ObjectActuator::pyattr_get_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_ObjectActuator* self = reinterpret_cast(self_v); + PyObject *retVal = PyList_New(3); + + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[1])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[1])); + PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.DLoc)); + + return retVal; +} + +int KX_ObjectActuator::pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self = reinterpret_cast(self_v); + + PyObject* seq = PySequence_Fast(value, ""); + if (seq && PySequence_Fast_GET_SIZE(seq) == 3) + { + self->m_drot[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); + self->m_dloc[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); + self->m_bitLocalFlag.DLoc = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + + if (!PyErr_Occurred()) + { + Py_DECREF(seq); + return PY_SET_ATTR_SUCCESS; + } + } + + Py_XDECREF(seq); + + PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool"); + return PY_SET_ATTR_FAIL; +} + +PyObject* KX_ObjectActuator::pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_ObjectActuator* self = reinterpret_cast(self_v); + PyObject *retVal = PyList_New(3); + + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[2])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[2])); + PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.DRot)); + + return retVal; +} + +int KX_ObjectActuator::pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self = reinterpret_cast(self_v); + + PyObject* seq = PySequence_Fast(value, ""); + if (seq && PySequence_Fast_GET_SIZE(seq) == 3) + { + self->m_drot[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); + self->m_dloc[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); + self->m_bitLocalFlag.DRot = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + + if (!PyErr_Occurred()) + { + Py_DECREF(seq); + return PY_SET_ATTR_SUCCESS; + } + } + + Py_XDECREF(seq); + + PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool"); + return PY_SET_ATTR_FAIL; +} + /* 1. set ------------------------------------------------------------------ */ /* Removed! */ /* 2. getForce */ PyObject* KX_ObjectActuator::PyGetForce() { + ShowDeprecationWarning("getForce()", "the force and the useLocalForce properties"); PyObject *retVal = PyList_New(4); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_force[0])); @@ -375,6 +503,7 @@ PyObject* KX_ObjectActuator::PyGetForce() /* 3. setForce */ PyObject* KX_ObjectActuator::PySetForce(PyObject* args) { + ShowDeprecationWarning("setForce()", "the force and the useLocalForce properties"); float vecArg[3]; int bToggle = 0; if (!PyArg_ParseTuple(args, "fffi:setForce", &vecArg[0], &vecArg[1], @@ -390,6 +519,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* args) /* 4. getTorque */ PyObject* KX_ObjectActuator::PyGetTorque() { + ShowDeprecationWarning("getTorque()", "the torque and the useLocalTorque properties"); PyObject *retVal = PyList_New(4); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_torque[0])); @@ -402,6 +532,7 @@ PyObject* KX_ObjectActuator::PyGetTorque() /* 5. setTorque */ PyObject* KX_ObjectActuator::PySetTorque(PyObject* args) { + ShowDeprecationWarning("setTorque()", "the torque and the useLocalTorque properties"); float vecArg[3]; int bToggle = 0; if (!PyArg_ParseTuple(args, "fffi:setTorque", &vecArg[0], &vecArg[1], @@ -417,6 +548,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* args) /* 6. getDLoc */ PyObject* KX_ObjectActuator::PyGetDLoc() { + ShowDeprecationWarning("getDLoc()", "the dLoc and the useLocalDLoc properties"); PyObject *retVal = PyList_New(4); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_dloc[0])); @@ -429,6 +561,7 @@ PyObject* KX_ObjectActuator::PyGetDLoc() /* 7. setDLoc */ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* args) { + ShowDeprecationWarning("setDLoc()", "the dLoc and the useLocalDLoc properties"); float vecArg[3]; int bToggle = 0; if(!PyArg_ParseTuple(args, "fffi:setDLoc", &vecArg[0], &vecArg[1], @@ -444,6 +577,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* args) /* 8. getDRot */ PyObject* KX_ObjectActuator::PyGetDRot() { + ShowDeprecationWarning("getDRot()", "the dRot and the useLocalDRot properties"); PyObject *retVal = PyList_New(4); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0])); @@ -456,6 +590,7 @@ PyObject* KX_ObjectActuator::PyGetDRot() /* 9. setDRot */ PyObject* KX_ObjectActuator::PySetDRot(PyObject* args) { + ShowDeprecationWarning("setDRot()", "the dRot and the useLocalDRot properties"); float vecArg[3]; int bToggle = 0; if (!PyArg_ParseTuple(args, "fffi:setDRot", &vecArg[0], &vecArg[1], @@ -470,6 +605,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* args) /* 10. getLinearVelocity */ PyObject* KX_ObjectActuator::PyGetLinearVelocity() { + ShowDeprecationWarning("getLinearVelocity()", "the linV and the useLocalLinV properties"); PyObject *retVal = PyList_New(4); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); @@ -482,6 +618,7 @@ PyObject* KX_ObjectActuator::PyGetLinearVelocity() { /* 11. setLinearVelocity */ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) { + ShowDeprecationWarning("setLinearVelocity()", "the linV and the useLocalLinV properties"); float vecArg[3]; int bToggle = 0; if (!PyArg_ParseTuple(args, "fffi:setLinearVelocity", &vecArg[0], &vecArg[1], @@ -497,6 +634,7 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) { /* 12. getAngularVelocity */ PyObject* KX_ObjectActuator::PyGetAngularVelocity() { + ShowDeprecationWarning("getAngularVelocity()", "the angV and the useLocalAngV properties"); PyObject *retVal = PyList_New(4); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0])); @@ -508,6 +646,7 @@ PyObject* KX_ObjectActuator::PyGetAngularVelocity() { } /* 13. setAngularVelocity */ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* args) { + ShowDeprecationWarning("setAngularVelocity()", "the angV and the useLocalAngV properties"); float vecArg[3]; int bToggle = 0; if (!PyArg_ParseTuple(args, "fffi:setAngularVelocity", &vecArg[0], &vecArg[1], @@ -522,6 +661,7 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* args) { /* 13. setDamping */ PyObject* KX_ObjectActuator::PySetDamping(PyObject* args) { + ShowDeprecationWarning("setDamping()", "the damping property"); int damping = 0; if (!PyArg_ParseTuple(args, "i:setDamping", &damping) || damping < 0 || damping > 1000) { return NULL; @@ -532,11 +672,13 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* args) { /* 13. getVelocityDamping */ PyObject* KX_ObjectActuator::PyGetDamping() { + ShowDeprecationWarning("getDamping()", "the damping property"); return Py_BuildValue("i",m_damping); } /* 6. getForceLimitX */ PyObject* KX_ObjectActuator::PyGetForceLimitX() { + ShowDeprecationWarning("getForceLimitX()", "the forceLimitX property"); PyObject *retVal = PyList_New(3); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0])); @@ -548,6 +690,7 @@ PyObject* KX_ObjectActuator::PyGetForceLimitX() /* 7. setForceLimitX */ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* args) { + ShowDeprecationWarning("setForceLimitX()", "the forceLimitX property"); float vecArg[2]; int bToggle = 0; if(!PyArg_ParseTuple(args, "ffi:setForceLimitX", &vecArg[0], &vecArg[1], &bToggle)) { @@ -562,6 +705,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* args) /* 6. getForceLimitY */ PyObject* KX_ObjectActuator::PyGetForceLimitY() { + ShowDeprecationWarning("getForceLimitY()", "the forceLimitY property"); PyObject *retVal = PyList_New(3); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[1])); @@ -573,6 +717,7 @@ PyObject* KX_ObjectActuator::PyGetForceLimitY() /* 7. setForceLimitY */ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* args) { + ShowDeprecationWarning("setForceLimitY()", "the forceLimitY property"); float vecArg[2]; int bToggle = 0; if(!PyArg_ParseTuple(args, "ffi:setForceLimitY", &vecArg[0], &vecArg[1], &bToggle)) { @@ -587,6 +732,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* args) /* 6. getForceLimitZ */ PyObject* KX_ObjectActuator::PyGetForceLimitZ() { + ShowDeprecationWarning("getForceLimitZ()", "the forceLimitZ property"); PyObject *retVal = PyList_New(3); PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[2])); @@ -598,6 +744,7 @@ PyObject* KX_ObjectActuator::PyGetForceLimitZ() /* 7. setForceLimitZ */ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* args) { + ShowDeprecationWarning("setForceLimitZ()", "the forceLimitZ property"); float vecArg[2]; int bToggle = 0; if(!PyArg_ParseTuple(args, "ffi:setForceLimitZ", &vecArg[0], &vecArg[1], &bToggle)) { @@ -612,22 +759,24 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* args) /* 4. getPID */ PyObject* KX_ObjectActuator::PyGetPID() { + ShowDeprecationWarning("getPID()", "the pid property"); PyObject *retVal = PyList_New(3); - PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_torque[0])); - PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_torque[1])); - PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_torque[2])); + PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_pid[0])); + PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_pid[1])); + PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_pid[2])); return retVal; } /* 5. setPID */ PyObject* KX_ObjectActuator::PySetPID(PyObject* args) { + ShowDeprecationWarning("setPID()", "the pid property"); float vecArg[3]; if (!PyArg_ParseTuple(args, "fff:setPID", &vecArg[0], &vecArg[1], &vecArg[2])) { return NULL; } - m_torque.setValue(vecArg); + m_pid.setValue(vecArg); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index ab5fbe44409..b60f877074d 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -36,7 +36,7 @@ #include "MT_Vector3.h" // -// Bitfield that stores the flags for each CValue derived class +// Stores the flags for each CValue derived class // struct KX_LocalFlags { KX_LocalFlags() : @@ -55,20 +55,20 @@ struct KX_LocalFlags { { } - unsigned short Force : 1; - unsigned short Torque : 1; - unsigned short DRot : 1; - unsigned short DLoc : 1; - unsigned short LinearVelocity : 1; - unsigned short AngularVelocity : 1; - unsigned short AddOrSetLinV : 1; - unsigned short ServoControl : 1; - unsigned short ZeroForce : 1; - unsigned short ZeroTorque : 1; - unsigned short ZeroDRot : 1; - unsigned short ZeroDLoc : 1; - unsigned short ZeroLinearVelocity : 1; - unsigned short ZeroAngularVelocity : 1; + bool Force; + bool Torque; + bool DRot; + bool DLoc; + bool LinearVelocity; + bool AngularVelocity; + bool AddOrSetLinV; + bool ServoControl; + bool ZeroForce; + bool ZeroTorque; + bool ZeroDRot; + bool ZeroDLoc; + bool ZeroLinearVelocity; + bool ZeroAngularVelocity; }; class KX_ObjectActuator : public SCA_IActuator @@ -80,7 +80,8 @@ class KX_ObjectActuator : public SCA_IActuator MT_Vector3 m_dloc; MT_Vector3 m_drot; MT_Vector3 m_linear_velocity; - MT_Vector3 m_angular_velocity; + MT_Vector3 m_angular_velocity; + MT_Vector3 m_pid; MT_Scalar m_linear_length2; MT_Scalar m_angular_length2; // used in damping @@ -155,6 +156,7 @@ public: virtual PyObject* py_getattro(PyObject *attr); virtual PyObject* py_getattro_dict(); + virtual int py_setattro(PyObject *attr, PyObject *value); KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce); KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForce); @@ -178,6 +180,51 @@ public: KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForceLimitZ); KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetPID); KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetPID); + + /* Attributes */ + static PyObject* pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + + // This lets the attribute macros use UpdateFuzzyFlags() + static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef) + { + KX_ObjectActuator* act = reinterpret_cast(self); + act->UpdateFuzzyFlags(); + return 0; + } + + // This is the keep the PID values in check after they are assigned with Python + static int PyCheckPid(void *self, const PyAttributeDef *attrdef) + { + KX_ObjectActuator* act = reinterpret_cast(self); + + //P 0 to 200 + if (act->m_pid[0] < 0) { + act->m_pid[0] = 0; + } else if (act->m_pid[0] > 200) { + act->m_pid[0] = 200; + } + + //I 0 to 3 + if (act->m_pid[1] < 0) { + act->m_pid[1] = 0; + } else if (act->m_pid[1] > 3) { + act->m_pid[1] = 3; + } + + //D -100 to 100 + if (act->m_pid[2] < -100) { + act->m_pid[2] = -100; + } else if (act->m_pid[2] > 100) { + act->m_pid[2] = 100; + } + + return 0; + } }; #endif //__KX_OBJECTACTUATOR diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index d1b92e37099..828435b813a 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -2574,17 +2574,63 @@ class KX_ObjectActuator(SCA_IActuator): The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement, velocity, or angular velocity to an object. Servo control allows to regulate force to achieve a certain speed target. + + @ivar force: The force applied by the actuator + @type force: list [x, y, z] + @ivar useLocalForce: A flag specifying if the force is local + @type force: bool + @ivar torque: The torque applied by the actuator + @type torque: list [x, y, z] + @ivar useLocalTorque: A flag specifying if the torque is local + @type useLocalTorque: bool + @ivar dLoc: The displacement vector applied by the actuator + @type dLoc: list [x, y, z] + @ivar useLocalDLoc: A flag specifying if the dLoc is local + @type useLocalDLoc: bool + @ivar dRot: The angular displacement vector applied by the actuator + - note: Since the displacement is applied every frame, you must adjust the displacement + based on the frame rate, or you game experience will depend on the player's computer + speed. + @type dRot: list [x, y, z] + @ivar useLocalDRot: A flag specifying if the dRot is local + @type useLocalDRot: bool + @ivar linV: The linear velocity applied by the actuator + @type linV: list [x, y, z] + @ivar useLocalLinV: A flag specifying if the linear velocity is local + - note: This is the target speed for servo controllers + @type useLocalLinV: bool + @ivar angV: The angular velocity applied by the actuator + @type angV: list [x, y, z] + @ivar useLocalAngV: A flag specifying if the angular velocity is local + @type useLocalAngV: bool + + @ivar damping: The damping parameter of the servo controller + @type damping: short + + @ivar forceLimitX: The min/max force limit along the X axis and activates or deactivates the limits in the servo controller + @type forceLimitX: list [min(float), max(float), bool] + @ivar forceLimitY: The min/max force limit along the Y axis and activates or deactivates the limits in the servo controller + @type forceLimitY: list [min(float), max(float), bool] + @ivar forceLimitZ: The min/max force limit along the Z axis and activates or deactivates the limits in the servo controller + @type forceLimitZ: list [min(float), max(float), bool] + + @ivar pid: The PID coefficients of the servo controller + @type pid: list of floats [proportional, integral, derivate] + + @group Deprecated: getForce, setForce, getTorque, setTorque, getDLoc, setDLoc, getDRot, setDRot, getLinearVelocity, setLinearVelocity, getAngularVelocity, + setAngularVelocity, getDamping, setDamping, getForceLimitX, setForceLimitX, getForceLimitY, setForceLimitY, getForceLimitZ, setForceLimitZ, + getPID, setPID """ def getForce(): """ - Returns the force applied by the actuator. + Returns the force applied by the actuator. (B{deprecated}) @rtype: list [fx, fy, fz, local] @return: A four item list, containing the vector force, and a flag specifying whether the force is local. """ def setForce(fx, fy, fz, local): """ - Sets the force applied by the actuator. + Sets the force applied by the actuator. (B{deprecated}) @type fx: float @param fx: the x component of the force. @@ -2598,7 +2644,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getTorque(): """ - Returns the torque applied by the actuator. + Returns the torque applied by the actuator. (B{deprecated}) @rtype: list [S{Tau}x, S{Tau}y, S{Tau}z, local] @return: A four item list, containing the vector torque, and a flag specifying whether @@ -2606,7 +2652,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setTorque(tx, ty, tz, local): """ - Sets the torque applied by the actuator. + Sets the torque applied by the actuator. (B{deprecated}) @type tx: float @param tx: the x component of the torque. @@ -2620,7 +2666,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getDLoc(): """ - Returns the displacement vector applied by the actuator. + Returns the displacement vector applied by the actuator. (B{deprecated}) @rtype: list [dx, dy, dz, local] @return: A four item list, containing the vector displacement, and whether @@ -2629,7 +2675,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setDLoc(dx, dy, dz, local): """ - Sets the displacement vector applied by the actuator. + Sets the displacement vector applied by the actuator. (B{deprecated}) Since the displacement is applied every frame, you must adjust the displacement based on the frame rate, or you game experience will depend on the player's computer @@ -2647,7 +2693,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getDRot(): """ - Returns the angular displacement vector applied by the actuator. + Returns the angular displacement vector applied by the actuator. (B{deprecated}) @rtype: list [dx, dy, dz, local] @return: A four item list, containing the angular displacement vector, and whether @@ -2656,7 +2702,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setDRot(dx, dy, dz, local): """ - Sets the angular displacement vector applied by the actuator. + Sets the angular displacement vector applied by the actuator. (B{deprecated}) Since the displacement is applied every frame, you must adjust the displacement based on the frame rate, or you game experience will depend on the player's computer @@ -2675,7 +2721,7 @@ class KX_ObjectActuator(SCA_IActuator): def getLinearVelocity(): """ Returns the linear velocity applied by the actuator. - For the servo control actuator, this is the target speed. + For the servo control actuator, this is the target speed. (B{deprecated}) @rtype: list [vx, vy, vz, local] @return: A four item list, containing the vector velocity, and whether the velocity is applied in local coordinates (True) or world coordinates (False) @@ -2683,7 +2729,7 @@ class KX_ObjectActuator(SCA_IActuator): def setLinearVelocity(vx, vy, vz, local): """ Sets the linear velocity applied by the actuator. - For the servo control actuator, sets the target speed. + For the servo control actuator, sets the target speed. (B{deprecated}) @type vx: float @param vx: the x component of the velocity vector. @@ -2697,7 +2743,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getAngularVelocity(): """ - Returns the angular velocity applied by the actuator. + Returns the angular velocity applied by the actuator. (B{deprecated}) @rtype: list [S{omega}x, S{omega}y, S{omega}z, local] @return: A four item list, containing the vector velocity, and whether @@ -2706,7 +2752,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setAngularVelocity(wx, wy, wz, local): """ - Sets the angular velocity applied by the actuator. + Sets the angular velocity applied by the actuator. (B{deprecated}) @type wx: float @param wx: the x component of the velocity vector. @@ -2720,21 +2766,21 @@ class KX_ObjectActuator(SCA_IActuator): """ def getDamping(): """ - Returns the damping parameter of the servo controller. + Returns the damping parameter of the servo controller. (B{deprecated}) @rtype: integer @return: the time constant of the servo controller in frame unit. """ def setDamping(damp): """ - Sets the damping parameter of the servo controller. + Sets the damping parameter of the servo controller. (B{deprecated}) @type damp: integer @param damp: the damping parameter in frame unit. """ def getForceLimitX(): """ - Returns the min/max force limit along the X axis used by the servo controller. + Returns the min/max force limit along the X axis used by the servo controller. (B{deprecated}) @rtype: list [min, max, enabled] @return: A three item list, containing the min and max limits of the force as float @@ -2742,7 +2788,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setForceLimitX(min, max, enable): """ - Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller. + Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller. (B{deprecated}) @type min: float @param min: the minimum value of the force along the X axis. @@ -2754,7 +2800,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getForceLimitY(): """ - Returns the min/max force limit along the Y axis used by the servo controller. + Returns the min/max force limit along the Y axis used by the servo controller. (B{deprecated}) @rtype: list [min, max, enabled] @return: A three item list, containing the min and max limits of the force as float @@ -2762,7 +2808,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setForceLimitY(min, max, enable): """ - Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller. + Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller. (B{deprecated}) @type min: float @param min: the minimum value of the force along the Y axis. @@ -2774,7 +2820,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getForceLimitZ(): """ - Returns the min/max force limit along the Z axis used by the servo controller. + Returns the min/max force limit along the Z axis used by the servo controller. (B{deprecated}) @rtype: list [min, max, enabled] @return: A three item list, containing the min and max limits of the force as float @@ -2782,7 +2828,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setForceLimitZ(min, max, enable): """ - Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller. + Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller. (B{deprecated}) @type min: float @param min: the minimum value of the force along the Z axis. @@ -2794,7 +2840,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def getPID(): """ - Returns the PID coefficient of the servo controller. + Returns the PID coefficient of the servo controller. (B{deprecated}) @rtype: list [P, I, D] @return: A three item list, containing the PID coefficient as floats: @@ -2804,7 +2850,7 @@ class KX_ObjectActuator(SCA_IActuator): """ def setPID(P, I, D): """ - Sets the PID coefficients of the servo controller. + Sets the PID coefficients of the servo controller. (B{deprecated}) @type P: flat @param P: proportional coefficient From c7519789b8a7ba8973b2a165b2d008679c3f8241 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 13 May 2009 17:02:39 +0000 Subject: [PATCH 230/444] BGE: 1-liner patch to put the Always sensor in non pulse mode by default. I've seen enough games with Always sensors in pulse mode while they should not; this patch should prevent this common mistake. --- source/blender/blenkernel/intern/sca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 47d11bb9d29..bbca97d75f7 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -134,7 +134,7 @@ void init_sensor(bSensor *sens) switch(sens->type) { case SENS_ALWAYS: - sens->pulse = 1; + sens->pulse = 0; break; case SENS_TOUCH: sens->data= MEM_callocN(sizeof(bTouchSensor), "touchsens"); From 240aa6d34d561ac6156eda50ece90130903a2df0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 May 2009 22:52:31 +0000 Subject: [PATCH 231/444] * More updates to game engine type docs from Roelf de Kock * FBX Bugfix, was exporting all animation curves as 'Constant' type (no docs for this so could only guess), Thanks to Sander Brandenburg for spotting this problem. Also improved keyframe removal to work on animation curves an angle --- release/scripts/export_fbx.py | 41 +++++++++---- source/gameengine/PyDoc/GameTypes.py | 87 ++++++++++++++-------------- 2 files changed, 74 insertions(+), 54 deletions(-) diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 707ab9ebbb7..d2028c22468 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -2611,10 +2611,9 @@ Takes: {''') if frame!=act_start: file.write(',') - # Curve types are + # Curve types are 'C,n' for constant, 'L' for linear # C,n is for bezier? - linear is best for now so we can do simple keyframe removal - file.write('\n\t\t\t\t\t\t\t%i,%.15f,C,n' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) - #file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) + file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) frame+=1 else: # remove unneeded keys, j is the frame, needed when some frames are removed. @@ -2622,11 +2621,32 @@ Takes: {''') # last frame to fisrt frame, missing 1 frame on either side. # removeing in a backwards loop is faster - for j in xrange( (act_end-act_start)-1, 0, -1 ): - # Is this key reduenant? - if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\ - abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + #for j in xrange( (act_end-act_start)-1, 0, -1 ): + # j = (act_end-act_start)-1 + j = len(context_bone_anim_keys)-2 + while j > 0 and len(context_bone_anim_keys) > 2: + # print j, len(context_bone_anim_keys) + # Is this key the same as the ones next to it? + + # co-linear horizontal... + if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\ + abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + del context_bone_anim_keys[j] + + else: + frame_range = float(context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j-1][1]) + frame_range_fac1 = (context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j][1]) / frame_range + frame_range_fac2 = 1.0 - frame_range_fac1 + + if abs(((context_bone_anim_keys[j-1][0]*frame_range_fac1 + context_bone_anim_keys[j+1][0]*frame_range_fac2)) - context_bone_anim_keys[j][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + del context_bone_anim_keys[j] + else: + j-=1 + + # keep the index below the list length + if j > len(context_bone_anim_keys)-2: + j = len(context_bone_anim_keys)-2 if len(context_bone_anim_keys) == 2 and context_bone_anim_keys[0][0] == context_bone_anim_keys[1][0]: # This axis has no moton, its okay to skip KeyCount and Keys in this case @@ -2639,8 +2659,7 @@ Takes: {''') if frame != context_bone_anim_keys[0][1]: # not the first file.write(',') # frame is alredy one less then blenders frame - file.write('\n\t\t\t\t\t\t\t%i,%.15f,C,n' % (fbx_time(frame), val )) - #file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val )) + file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val )) if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0') elif i==1: file.write('\n\t\t\t\t\t\tColor: 0,1,0') @@ -2919,7 +2938,7 @@ def fbx_ui(): Draw.BeginAlign() GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw) if GLOBALS['ANIM_OPTIMIZE'].val: - GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 3, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)') + GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)') Draw.EndAlign() Draw.BeginAlign() @@ -2997,7 +3016,7 @@ def write_ui(): # animation opts GLOBALS['ANIM_ENABLE'] = Draw.Create(1) GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1) - GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(6) # decimal places + GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action # batch export options diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 828435b813a..6758824611c 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -512,8 +512,7 @@ class BL_Shader(PyObjectPlus): def delSource(): """ - TODO - Description - + Clear the shader. Use this method before the source is changed with L{setSource}. """ def getFragmentProg(): """ @@ -997,39 +996,56 @@ class KX_BlenderMaterial(PyObjectPlus): # , RAS_IPolyMaterial) """ KX_BlenderMaterial - All placeholders have a __ prefix """ - def __getShader(val): + def getShader(): """ - TODO - Description + Returns the material's shader. - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @rtype: L{BL_Shader} + @return: the material's shader """ - def __setBlending(val): + def setBlending(src, dest): """ - TODO - Description + Set the pixel color arithmetic functions. - @param val: the starting frame of the animation - @type val: float + @param src: Specifies how the red, green, blue, + and alpha source blending factors are computed. + @type src: GL_ZERO, + GL_ONE, + GL_SRC_COLOR, + GL_ONE_MINUS_SRC_COLOR, + GL_DST_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_SRC_ALPHA_SATURATE + + + @param dest: Specifies how the red, green, blue, + and alpha destination blending factors are computed. + @type dest: GL_ZERO, + GL_ONE, + GL_SRC_COLOR, + GL_ONE_MINUS_SRC_COLOR, + GL_DST_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_SRC_ALPHA_SATURATE + + """ + def getMaterialIndex(): + """ + Returns the material's index. @rtype: integer - @return: TODO Description - """ - def __getMaterialIndex(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @return: the material's index """ class KX_CDActuator(SCA_IActuator): @@ -1419,28 +1435,13 @@ class KX_ConstraintWrapper(PyObjectPlus): """ KX_ConstraintWrapper - All placeholders have a __ prefix """ - def __getConstraintId(val): + def getConstraintId(val): """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float + Returns the contraint's ID @rtype: integer - @return: TODO Description - """ - - def __testMethod(val): - """ - TODO - Description - - @param val: the starting frame of the animation - @type val: float - - @rtype: integer - @return: TODO Description + @return: the constraint's ID """ class KX_GameActuator(SCA_IActuator): From 5f78efe19cdea2f508fff41a1723477489d7ac03 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 May 2009 00:10:25 +0000 Subject: [PATCH 232/444] print warnings when python attributes and methods conflict with game properties. --- .../Converter/KX_ConvertProperties.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp index dfbc6f0c48d..e9984ee0525 100644 --- a/source/gameengine/Converter/KX_ConvertProperties.cpp +++ b/source/gameengine/Converter/KX_ConvertProperties.cpp @@ -129,6 +129,22 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan // done with propval, release it propval->Release(); } + + + /* Warn if we double up on attributes, this isnt quite right since it wont find inherited attributes however there arnt many */ + for(PyAttributeDef *attrdef = KX_GameObject::Attributes; attrdef->m_name; attrdef++) { + if(strcmp(prop->name, attrdef->m_name)==0) { + printf("Warning! user defined property name \"%s\" is also a python attribute for object \"%s\"\n\tUse ob[\"%s\"] syntax to avoid conflict\n", prop->name, object->id.name+2, prop->name); + break; + } + } + for(PyMethodDef *methdef = KX_GameObject::Methods; methdef->ml_name; methdef++) { + if(strcmp(prop->name, methdef->ml_name)==0) { + printf("Warning! user defined property name \"%s\" is also a python method for object \"%s\"\n\tUse ob[\"%s\"] syntax to avoid conflict\n", prop->name, object->id.name+2, prop->name); + break; + } + } + /* end warning check */ prop = prop->next; } From d2cff7307d26ada0dd34949d0a9fbb3c37c72f19 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 May 2009 02:21:50 +0000 Subject: [PATCH 233/444] [#18685] dark pixels created when during texture "full baking" fix/workaround - offset by a 500th of a pixel to avoid baking missing pixels that are between 2 faces, its still possible pixels could be between faces but much less likely then it is currently with pixel aligned UVs. --- source/blender/render/intern/source/rendercore.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 5dfb509939b..2793e238dc7 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2542,8 +2542,12 @@ static void shade_tface(BakeShade *bs) /* get pixel level vertex coordinates */ for(a=0; a<4; a++) { - vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f; - vec[a][1]= tface->uv[a][1]*(float)bs->recty - 0.5f; + /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests + * where a pixel gets inbetween 2 faces or the middle of a quad, + * camera aligned quads also have this problem but they are less common. + * Add a small offset to the UVs, fixes bug #18685 - Campbell */ + vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001); + vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002); } /* UV indices have to be corrected for possible quad->tria splits */ From d257586fe6d59f9a7c622b460fbe38a168fb5428 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 May 2009 07:59:44 +0000 Subject: [PATCH 234/444] BGE Py API scene.active_camera can now be set so you can more easily set the current camera from python scripts without using an actuator. ConvertPythonToCamera utility function to get a camera from a python string or KX_Camera type. --- source/gameengine/Ketsji/KX_Camera.cpp | 54 ++++++++++ source/gameengine/Ketsji/KX_Camera.h | 3 + source/gameengine/Ketsji/KX_GameObject.cpp | 4 +- source/gameengine/Ketsji/KX_Scene.cpp | 21 +++- source/gameengine/Ketsji/KX_Scene.h | 3 +- source/gameengine/Ketsji/KX_SceneActuator.cpp | 99 +++++-------------- source/gameengine/Ketsji/KX_SceneActuator.h | 2 +- source/gameengine/PyDoc/GameTypes.py | 41 ++++---- 8 files changed, 122 insertions(+), 105 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 3ea01cca5ca..df39faf8b22 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -933,3 +933,57 @@ PyObject* KX_Camera::pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF * PyObject* KX_Camera::pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { return PyInt_FromLong(INTERSECT); } + +bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix) +{ + if (value==NULL) { + PyErr_Format(PyExc_TypeError, "%s, python pointer NULL, should never happen", error_prefix); + *object = NULL; + return false; + } + + if (value==Py_None) { + *object = NULL; + + if (py_none_ok) { + return true; + } else { + PyErr_Format(PyExc_TypeError, "%s, expected KX_Camera or a KX_Camera name, None is invalid", error_prefix); + return false; + } + } + + if (PyString_Check(value)) { + STR_String value_str = PyString_AsString(value); + *object = KX_GetActiveScene()->FindCamera(value_str); + + if (*object) { + return true; + } else { + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, PyString_AsString(value)); + return false; + } + } + + if (PyObject_TypeCheck(value, &KX_Camera::Type)) { + *object = static_castBGE_PROXY_REF(value); + + /* sets the error */ + if (*object==NULL) { + PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix); + return false; + } + + return true; + } + + *object = NULL; + + if (py_none_ok) { + PyErr_Format(PyExc_TypeError, "%s, expect a KX_Camera, a string or None", error_prefix); + } else { + PyErr_Format(PyExc_TypeError, "%s, expect a KX_Camera or a string", error_prefix); + } + + return false; +} \ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index e99a0594701..ce8bbb8d656 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -41,6 +41,9 @@ #include "IntValue.h" #include "RAS_CameraData.h" +/* utility conversion function */ +bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix); + class KX_Camera : public KX_GameObject { Py_Header; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 4d01d96ced4..fe9fb8bb583 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1819,9 +1819,7 @@ PyObject* KX_GameObject::py_getattro_dict() { int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro method { - int ret; - - ret= py_setattro__internal(attr, value); + int ret= py_setattro__internal(attr, value); if (ret==PY_SET_ATTR_SUCCESS) { /* remove attribute in our own dict to avoid double ups */ diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 84c6d374386..e3622c211ff 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1703,13 +1703,27 @@ PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_ return self->GetActiveCamera()->GetProxy(); } + +int KX_Scene::pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_Scene* self= static_cast(self_v); + KX_Camera *camOb; + + if (!ConvertPythonToCamera(value, &camOb, false, "scene.active_camera = value: KX_Scene")) + return PY_SET_ATTR_FAIL; + + self->SetActiveCamera(camOb); + return PY_SET_ATTR_SUCCESS; +} + + PyAttributeDef KX_Scene::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects), KX_PYATTRIBUTE_RO_FUNCTION("objects_inactive", KX_Scene, pyattr_get_objects_inactive), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), KX_PYATTRIBUTE_RO_FUNCTION("cameras", KX_Scene, pyattr_get_cameras), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), - KX_PYATTRIBUTE_RO_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera), + KX_PYATTRIBUTE_RW_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera), KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend), KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling), KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius), @@ -1717,15 +1731,14 @@ PyAttributeDef KX_Scene::Attributes[] = { { NULL } //Sentinel }; - PyObject* KX_Scene::py_getattro__internal(PyObject *attr) { py_getattro_up(PyObjectPlus); } -int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *pyvalue) +int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *value) { - return PyObjectPlus::py_setattro(attr, pyvalue); + py_setattro_up(PyObjectPlus); } PyObject* KX_Scene::py_getattro(PyObject *attr) diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 128f8d23135..5191ea9f23f 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -566,11 +566,12 @@ public: static PyObject* pyattr_get_lights(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_cameras(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); + virtual int py_setattro(PyObject *attr, PyObject *value); virtual int py_delattro(PyObject *attr); virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); } diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 64edb6cd6d5..1b790ec9824 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -264,7 +264,7 @@ PyMethodDef KX_SceneActuator::Methods[] = //Deprecated functions ------> {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc}, {"setScene", (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc}, - {"setCamera", (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, (PY_METHODCHAR)SetCamera_doc}, + {"setCamera", (PyCFunction) KX_SceneActuator::sPySetCamera, METH_O, (PY_METHODCHAR)SetCamera_doc}, {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_NOARGS, (PY_METHODCHAR)GetUseRestart_doc}, {"getScene", (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (PY_METHODCHAR)GetScene_doc}, {"getCamera", (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (PY_METHODCHAR)GetCamera_doc}, @@ -308,51 +308,21 @@ int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_ KX_SceneActuator* actuator = static_cast(self); KX_Camera *camOb; - if(value==Py_None) - { - if (actuator->m_camera) - actuator->m_camera->UnregisterActuator(actuator); - - actuator->m_camera= NULL; - return 0; - } + if (!ConvertPythonToCamera(value, &camOb, true, "actu.camera = value: KX_SceneActuator")) + return PY_SET_ATTR_FAIL; - if (PyObject_TypeCheck(value, &KX_Camera::Type)) - { - KX_Camera *camOb= static_castBGE_PROXY_REF(value); - - if(camOb==NULL) - { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return 1; - } - - if (actuator->m_camera) - actuator->m_camera->UnregisterActuator(actuator); - + if (actuator->m_camera) + actuator->m_camera->UnregisterActuator(actuator); + + if(camOb==NULL) { + actuator->m_camera= NULL; + } + else { actuator->m_camera = camOb; actuator->m_camera->RegisterActuator(actuator); - return 0; } - - if (PyString_Check(value)) - { - char *camName = PyString_AsString(value); - - camOb = actuator->FindCamera(camName); - if (camOb) - { - if (actuator->m_camera) - actuator->m_camera->UnregisterActuator(actuator); - actuator->m_camera = camOb; - actuator->m_camera->RegisterActuator(actuator); - return 0; - } - PyErr_SetString(PyExc_TypeError, "not a valid camera name"); - return 1; - } - PyErr_SetString(PyExc_TypeError, "expected a string or a camera object reference"); - return 1; + + return PY_SET_ATTR_SUCCESS; } @@ -431,47 +401,24 @@ const char KX_SceneActuator::SetCamera_doc[] = "setCamera(camera)\n" "\t- camera: string\n" "\tSet the camera to switch to.\n" ; -PyObject* KX_SceneActuator::PySetCamera(PyObject* args) +PyObject* KX_SceneActuator::PySetCamera(PyObject* value) { ShowDeprecationWarning("setCamera()", "the camera property"); - PyObject *cam; - if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam)) - { - KX_Camera *new_camera; - - new_camera = static_castBGE_PROXY_REF(cam); - if(new_camera==NULL) - { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return NULL; - } - - if (m_camera) - m_camera->UnregisterActuator(this); - - m_camera= new_camera; - - m_camera->RegisterActuator(this); - Py_RETURN_NONE; - } - PyErr_Clear(); - - /* one argument: a scene, ignore the rest */ - char *camName; - if(!PyArg_ParseTuple(args, "s:setCamera", &camName)) - { + KX_Camera *camOb; + + if (!ConvertPythonToCamera(value, &camOb, true, "actu.setCamera(value): KX_SceneActuator")) return NULL; + + if (m_camera) + m_camera->UnregisterActuator(this); + + if(camOb==NULL) { + m_camera= NULL; } - - KX_Camera *camOb = FindCamera(camName); - if (camOb) - { - if (m_camera) - m_camera->UnregisterActuator(this); + else { m_camera = camOb; m_camera->RegisterActuator(this); } - Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 315e97e8f70..2412dd02590 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -108,7 +108,7 @@ class KX_SceneActuator : public SCA_IActuator /* 5. getScene: */ KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetScene); /* 6. setCamera: */ - KX_PYMETHOD_DOC_VARARGS(KX_SceneActuator,SetCamera); + KX_PYMETHOD_DOC_O(KX_SceneActuator,SetCamera); /* 7. getCamera: */ KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetCamera); diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 6758824611c..e560489f91f 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -235,7 +235,7 @@ class SCA_IController(SCA_ILogicBrick): """ Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. This for instance will always be true however you could compare with a previous state to see when the state was activated. - GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState() + GameLogic.getCurrentController().state & GameLogic.getCurrentController().owner.state @deprecated: Use the L{state} property @rtype: int """ @@ -2126,7 +2126,7 @@ class KX_LightObject(KX_GameObject): import GameLogic co = GameLogic.getCurrentController() - light = co.getOwner() + light = co.owner light.energy = 1.0 light.colour = [1.0, 0.0, 0.0] @@ -2187,8 +2187,8 @@ class KX_MeshProxy(SCA_IObject): The correct method of iterating over every L{KX_VertexProxy} in a game object:: import GameLogic - co = GameLogic.getcurrentController() - obj = co.getOwner() + co = GameLogic.getCurrentController() + obj = co.owner m_i = 0 mesh = obj.getMesh(m_i) # There can be more than one mesh... @@ -3177,9 +3177,9 @@ class KX_PolygonMaterial: self.pass_no = 0 return False - obj = GameLogic.getCurrentController().getOwner() + obj = GameLogic.getCurrentController().owner - mesh = obj.getMesh(0) + mesh = obj.meshes[0] for mat in mesh.materials: mat.setCustomMaterial(MyMaterial()) @@ -3596,8 +3596,8 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): ) co = GameLogic.getCurrentController() - obj = co.getOwner() - act = co.getActuator("LOD." + obj.name) + obj = co.owner + act = co.actuators["LOD." + obj.name] cam = GameLogic.getCurrentScene().active_camera def Depth(pos, plane): @@ -3684,7 +3684,7 @@ class KX_Scene(PyObjectPlus): # Get the depth of an object in the camera view. import GameLogic - obj = GameLogic.getCurrentController().getOwner() + obj = GameLogic.getCurrentController().owner cam = GameLogic.getCurrentScene().active_camera # Depth is negative and decreasing further from the camera @@ -3692,19 +3692,20 @@ class KX_Scene(PyObjectPlus): @bug: All attributes are read only at the moment. - @ivar name: The scene's name + @ivar name: The scene's name, (read-only). @type name: string - @ivar objects: A list of objects in the scene. + @ivar objects: A list of objects in the scene, (read-only). @type objects: L{CListValue} of L{KX_GameObject} - @ivar objects_inactive: A list of objects on background layers (used for the addObject actuator). + @ivar objects_inactive: A list of objects on background layers (used for the addObject actuator), (read-only). @type objects_inactive: L{CListValue} of L{KX_GameObject} - @ivar lights: A list of lights in the scene. + @ivar lights: A list of lights in the scene, (read-only). @type lights: L{CListValue} of L{KX_LightObject} - @ivar cameras: A list of cameras in the scene. + @ivar cameras: A list of cameras in the scene, (read-only). @type cameras: L{CListValue} of L{KX_Camera} - @ivar active_camera: The current active camera + @ivar active_camera: The current active camera. + @note: this can be set directly from python to avoid using the L{KX_SceneActuator} @type active_camera: L{KX_Camera} - @ivar suspended: True if the scene is suspended. + @ivar suspended: True if the scene is suspended, (read-only). @type suspended: boolean @ivar activity_culling: True if the scene is activity culling @type activity_culling: boolean @@ -5328,7 +5329,7 @@ class KX_Camera(KX_GameObject): Example:: import GameLogic co = GameLogic.getCurrentController() - cam = co.GetOwner() + cam = co.owner # A sphere of radius 4.0 located at [x, y, z] = [1.0, 1.0, 1.0] if (cam.sphereInsideFrustum([1.0, 1.0, 1.0], 4) != cam.OUTSIDE): @@ -5344,7 +5345,7 @@ class KX_Camera(KX_GameObject): Example:: import GameLogic co = GameLogic.getCurrentController() - cam = co.GetOwner() + cam = co.owner # Box to test... box = [] @@ -5374,7 +5375,7 @@ class KX_Camera(KX_GameObject): Example:: import GameLogic co = GameLogic.getCurrentController() - cam = co.GetOwner() + cam = co.owner # Test point [0.0, 0.0, 0.0] if (cam.pointInsideFrustum([0.0, 0.0, 0.0])): @@ -5451,7 +5452,7 @@ class KX_Camera(KX_GameObject): [1.0/cam.scaling[0], 1.0/cam.scaling[1], 1.0/cam.scaling[2], 1.0]) co = GameLogic.getCurrentController() - cam = co.getOwner() + cam = co.owner cam.setProjectionMatrix(Perspective(cam))) @type matrix: 4x4 matrix. From a74d2574ee5322dc29754fe2ac93e100fcf73633 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 14 May 2009 09:32:47 +0000 Subject: [PATCH 235/444] Bugfix #18725 Particles using group-duplication, with Metaballs in group, enter eternal loop in our code now. This is a non-supported case... metaball code doesn't support recursions. Added a provision in code to catch this case, and print an error in console to denote this. --- source/blender/blenkernel/intern/mball.c | 5 ++++- source/blender/blenkernel/intern/scene.c | 16 ++++++++++++++-- source/blender/makesdna/DNA_scene_types.h | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 79205814ae7..97226b5ec42 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -297,7 +297,10 @@ Object *find_basis_mball(Object *basis) splitIDname(basis->id.name+2, basisname, &basisnr); totelem= 0; - next_object(0, 0, 0); + /* XXX recursion check, see scene.c, just too simple code this next_object() */ + if(F_ERROR==next_object(0, 0, 0)) + return NULL; + while(next_object(1, &base, &ob)) { if (ob->type==OB_MBALL) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5def3577218..ed1a77d645e 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -402,16 +402,25 @@ int next_object(int val, Base **base, Object **ob) { static ListBase *duplilist= NULL; static DupliObject *dupob; - static int fase; + static int fase= F_START, in_next_object= 0; int run_again=1; /* init */ if(val==0) { fase= F_START; dupob= NULL; + + /* XXX particle systems with metas+dupligroups call this recursively */ + /* see bug #18725 */ + if(in_next_object) { + printf("ERROR: MetaBall generation called recursively, not supported\n"); + + return F_ERROR; + } } else { - + in_next_object= 1; + /* run_again is set when a duplilist has been ended */ while(run_again) { run_again= 0; @@ -493,6 +502,9 @@ int next_object(int val, Base **base, Object **ob) } } + /* reset recursion test */ + in_next_object= 0; + return fase; } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d26bdd469f6..ac73ccc498c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -788,6 +788,7 @@ typedef struct Scene { #define PROP_RANDOM 6 /* return flag next_object function */ +#define F_ERROR -1 #define F_START 0 #define F_SCENE 1 #define F_SET 2 From a1e73e55c7f745ef28bca21d3d9f6b251f4a3244 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 May 2009 10:59:38 +0000 Subject: [PATCH 236/444] updated BGE doc checker script for classes now being in GameTypes.py --- .../gameengine/PyDoc/bge_api_validate_py.txt | 32 ++++++------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/source/gameengine/PyDoc/bge_api_validate_py.txt b/source/gameengine/PyDoc/bge_api_validate_py.txt index 492dcef408b..ec92cc28770 100644 --- a/source/gameengine/PyDoc/bge_api_validate_py.txt +++ b/source/gameengine/PyDoc/bge_api_validate_py.txt @@ -50,13 +50,8 @@ if doc_dir not in sys.path: sys.path.append(doc_dir) -def check_attribute(type_mame, member): - filename = os.path.join(doc_dir, type_mame + '.py') - # print filename - - file = open(filename, 'rU') - - for l in file: +def check_attribute(class_ob, member): + for l in class_ob.__doc__.split('\n'): l = l.strip() ''' @@ -70,10 +65,8 @@ def check_attribute(type_mame, member): var = l.split()[1].split(':')[0] if var == member: - file.close() return True - file.close() return False @@ -85,19 +78,15 @@ print '\n\n\nChecking Docs' PRINT_OK = False +pymod = sys.modules['GameTypes'] +del sys.modules['GameTypes'] # temp remove +mod = __import__('GameTypes') # get the python module +reload(mod) # incase were editing it +sys.modules['GameTypes'] = pymod + for type_name in sorted(type_members.keys()): members = type_members[type_name] - try: - mod = __import__(type_name) - if PRINT_OK: - print "type: %s" % type_name - except: - print "missing: %s - %s" % (type_name, str(sorted(members))) - continue - - reload(mod) # incase were editing it - try: type_class = getattr(mod, type_name) except: @@ -110,7 +99,7 @@ for type_name in sorted(type_members.keys()): if PRINT_OK: print "\tfound: %s.%s" % (type_name, member) except: - if check_attribute(type_name, member): + if check_attribute(type_class, member): if PRINT_OK: print "\tfound attr: %s.%s" % (type_name, member) else: @@ -128,7 +117,7 @@ for mod_name, pymod in mods_dict.iteritems(): print pydoc.__file__ for member in sorted(dir(pymod)): - if hasattr(pydoc, member) or check_attribute(mod_name, member): + if hasattr(pydoc, member) or check_attribute(pydoc, member): if PRINT_OK: print "\tfound module attr: %s.%s" % (mod_name, member) else: @@ -142,4 +131,3 @@ sys.path.pop() # remove the pydoc dir from our import paths - From 34f99fa4b9e5a370ee208db247f56fcbea4e71f9 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 14 May 2009 11:36:52 +0000 Subject: [PATCH 237/444] Bugfix #18743 Render: raytracing materials with transp-shadow + SSS crashed --- source/blender/render/intern/source/rayshade.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 97ac8666181..f4dcbe9e186 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1274,7 +1274,7 @@ static void addAlphaLight(float *shadfac, float *col, float alpha, float filter) shadfac[3]= (1.0f-alpha)*shadfac[3]; } -static void ray_trace_shadow_tra(Isect *is, int thread, int depth, int traflag) +static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int traflag) { /* ray to lamp, find first face that intersects, check alpha properties, if it has col[3]>0.0f continue. so exit when alpha is full */ @@ -1291,10 +1291,14 @@ static void ray_trace_shadow_tra(Isect *is, int thread, int depth, int traflag) /* end warning! - Campbell */ shi.depth= 1; /* only used to indicate tracing */ - shi.mask= 1; - shi.thread= thread; + shi.mask= origshi->mask; + shi.thread= origshi->thread; shi.passflag= SCE_PASS_COMBINED; shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ + + shi.xs= origshi->xs; + shi.ys= origshi->ys; + shi.lay= origshi->lay; shade_ray(is, &shi, &shr); if (traflag & RAY_TRA) @@ -1310,7 +1314,7 @@ static void ray_trace_shadow_tra(Isect *is, int thread, int depth, int traflag) is->oborig= RAY_OBJECT_SET(&R, shi.obi); is->faceorig= (RayFace*)shi.vlr; - ray_trace_shadow_tra(is, thread, depth-1, traflag | RAY_TRA); + ray_trace_shadow_tra(is, origshi, depth-1, traflag | RAY_TRA); } } } @@ -1938,7 +1942,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * isec->col[0]= isec->col[1]= isec->col[2]= 1.0f; isec->col[3]= 1.0f; - ray_trace_shadow_tra(isec, shi->thread, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0); shadfac[0] += isec->col[0]; shadfac[1] += isec->col[1]; shadfac[2] += isec->col[2]; @@ -2036,7 +2040,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa isec->col[0]= isec->col[1]= isec->col[2]= 1.0f; isec->col[3]= 1.0f; - ray_trace_shadow_tra(isec, shi->thread, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0); shadfac[0] += isec->col[0]; shadfac[1] += isec->col[1]; shadfac[2] += isec->col[2]; @@ -2117,7 +2121,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) isec.col[0]= isec.col[1]= isec.col[2]= 1.0f; isec.col[3]= 1.0f; - ray_trace_shadow_tra(&isec, shi->thread, DEPTH_SHADOW_TRA, 0); + ray_trace_shadow_tra(&isec, shi, DEPTH_SHADOW_TRA, 0); QUATCOPY(shadfac, isec.col); } else if(RE_ray_tree_intersect(R.raytree, &isec)) shadfac[3]= 0.0f; From 003534513645576215092b79f1aa46e85c89e3bd Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 14 May 2009 12:36:07 +0000 Subject: [PATCH 238/444] Bugfix, sorta :) Removed option to choose rendering to yafray. New yafaray is better, and already is being linked as option on the blender.org download page. --- source/blender/blenloader/intern/readfile.c | 8 ++++++++ source/blender/src/buttons_scene.c | 10 +--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index cbf2516da77..6c5a5bd551c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8092,6 +8092,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main) wrld->occlusionRes = 128; } } + + if (main->versionfile < 249) { + Scene *sce; + for (sce= main->scene.first; sce; sce= sce->id.next) + sce->r.renderer= 0; + + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 577486135b4..d140001ba2d 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -2277,15 +2277,7 @@ static void render_panel_render(void) if(uiNewPanel(curarea, block, "Render", "Render", 320, 0, 318, 204)==0) return; uiBlockBeginAlign(block); - uiDefBut(block, BUT,B_DORENDER,"RENDER", 369, 164, 191,37, 0, 0, 0, 0, 0, "Render the current frame (F12)"); -#ifndef DISABLE_YAFRAY - /* yafray: on request, render engine menu is back again, and moved to Render panel */ - uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1", - 369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine"); -#else - uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0", - 369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine"); -#endif /* disable yafray */ + uiDefBut(block, BUT,B_DORENDER,"RENDER", 369, 142, 191,59, 0, 0, 0, 0, 0, "Render the current frame (F12)"); uiBlockBeginAlign(block); if((G.scene->r.scemode & R_FULL_SAMPLE) && (G.scene->r.scemode & R_EXR_TILE_FILE)) From d95a10999052ad308599cb0fbbe7ed4f59870c9c Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 14 May 2009 13:47:08 +0000 Subject: [PATCH 239/444] BGE modifier: generate correct physic shape, share static derived mesh, share display list. This commit completes the support for modifiers in the BGE. - The physic shape is generated according to the derived mesh. This is true for all types of shapes and all types of objects except soft body. - Optimization for static derived mesh (mesh with modifiers but no armature and no shape keys). Replicas will share the derived mesh and the display list: less memory and faster rendering. With this optimization, the static derived mesh will render as fast as if the modifiers were applied. Known Limits: - Sharing of mesh and display list is only possible between in-game replicas or dupligroup. If you want to instantiate multiple objects with modifiers, use dupligroup to ensure best memory and GPU utilization. - rayCast() will interact with the derived mesh as follow: Hit position and hit normal are the real values according to the derived mesh but the KX_PolyProxy object refers to the original mesh. You should use it only to retrieve the material. - Dynamic derived mesh have very poor performance: They use direct openGL calls for rendering (no support for display list and vertex array) and they dont't share the derived mesh memory. Always apply modifiers on dynamic mesh for best performance. - Time dependent modifiers are not supported. - Modifiers are not supported for Bullet soft body. --- .../PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj | 12 +- .../Converter/BL_BlenderDataConversion.cpp | 102 +++++---- .../gameengine/Converter/BL_MeshDeformer.cpp | 9 + source/gameengine/Converter/BL_MeshDeformer.h | 2 +- .../Converter/BL_ModifierDeformer.cpp | 73 ++++--- .../Converter/BL_ModifierDeformer.h | 5 + .../gameengine/Converter/BL_ShapeDeformer.cpp | 9 +- .../gameengine/Converter/BL_ShapeDeformer.h | 1 + .../gameengine/Converter/BL_SkinDeformer.cpp | 41 ++-- source/gameengine/Converter/BL_SkinDeformer.h | 2 + .../Ketsji/KX_ConvertPhysicsObject.h | 2 + .../Ketsji/KX_ConvertPhysicsObjects.cpp | 51 +++-- .../gameengine/Physics/Bullet/CMakeLists.txt | 3 + .../Physics/Bullet/CcdPhysicsController.cpp | 200 ++++++++++-------- .../Physics/Bullet/CcdPhysicsController.h | 5 +- source/gameengine/Physics/Bullet/Makefile | 2 + source/gameengine/Physics/Bullet/SConscript | 3 + source/gameengine/Rasterizer/RAS_Deformer.h | 10 +- .../RAS_ListRasterizer.cpp | 46 ++-- .../RAS_OpenGLRasterizer/RAS_ListRasterizer.h | 6 +- 20 files changed, 357 insertions(+), 227 deletions(-) diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj index e6991592d40..9f16283e1cd 100644 --- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj +++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj @@ -42,7 +42,7 @@ type) { case OB_MESH: - bb= ( (Mesh *)ob->data )->bb; - if(bb==0) + if (dm) + { + float min_r[3], max_r[3]; + INIT_MINMAX(min_r, max_r); + dm->getMinMax(dm, min_r, max_r); + size[0]= 0.5*fabs(max_r[0] - min_r[0]); + size[1]= 0.5*fabs(max_r[1] - min_r[1]); + size[2]= 0.5*fabs(max_r[2] - min_r[2]); + + center[0]= 0.5*(max_r[0] + min_r[0]); + center[1]= 0.5*(max_r[1] + min_r[1]); + center[2]= 0.5*(max_r[2] + min_r[2]); + return; + } else { - my_tex_space_mesh((struct Mesh *)ob->data); bb= ( (Mesh *)ob->data )->bb; + if(bb==0) + { + my_tex_space_mesh((struct Mesh *)ob->data); + bb= ( (Mesh *)ob->data )->bb; + } } break; case OB_CURVE: @@ -1498,7 +1514,10 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, } KX_BoxBounds bb; - my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends); + DerivedMesh* dm = NULL; + if (gameobj->GetDeformer()) + dm = gameobj->GetDeformer()->GetFinalMesh(); + my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends); if (blenderobject->gameflag & OB_BOUNDS) { switch (blenderobject->boundtype) @@ -1567,7 +1586,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, { #ifdef USE_BULLET case UseBullet: - KX_ConvertBulletObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop); + KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop); break; #endif @@ -1947,8 +1966,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, int activeLayerBitInfo = blenderscene->lay; - // templist to find Root Parents (object with no parents) - CListValue* templist = new CListValue(); + // list of all object converted, active and inactive CListValue* sumolist = new CListValue(); vector vec_parent_child; @@ -2048,9 +2066,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, gameobj->SetName(blenderobject->id.name); - // templist to find Root Parents (object with no parents) - templist->Add(gameobj->AddRef()); - // update children/parent hierarchy if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) { @@ -2243,9 +2258,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, gameobj->SetName(blenderobject->id.name); - // templist to find Root Parents (object with no parents) - templist->Add(gameobj->AddRef()); - // update children/parent hierarchy if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) { @@ -2398,8 +2410,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, for ( i=0;iGetCount();i++) { KX_GameObject* obj = static_cast(childrenlist->GetValue(i)); - if (templist->RemoveValue(obj)) - obj->Release(); if (sumolist->RemoveValue(obj)) obj->Release(); if (logicbrick_conversionlist->RemoveValue(obj)) @@ -2455,16 +2465,47 @@ void BL_ConvertBlenderObjects(struct Main* maggie, vec_parent_child.clear(); // find 'root' parents (object that has not parents in SceneGraph) - for (i=0;iGetCount();++i) + for (i=0;iGetCount();++i) { - KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i); + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); if (gameobj->GetSGNode()->GetSGParent() == 0) { parentlist->Add(gameobj->AddRef()); gameobj->NodeUpdateGS(0); } } - + + // create graphic controller for culling + if (kxscene->GetDbvtCulling()) + { + bool occlusion = false; + for (i=0; iGetCount();i++) + { + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); + if (gameobj->GetMeshCount() > 0) + { + MT_Point3 box[2]; + gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity()); + // box[0] is the min, box[1] is the max + bool isactive = objectlist->SearchValue(gameobj); + BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine); + if (gameobj->GetOccluder()) + occlusion = true; + } + } + if (occlusion) + kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes); + } + + // now that the scenegraph is complete, let's instantiate the deformers. + // We need that to create reusable derived mesh and physic shapes + for (i=0;iGetCount();++i) + { + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); + if (gameobj->GetDeformer()) + gameobj->GetDeformer()->UpdateBuckets(); + } + bool processCompoundChildren = false; // create physics information @@ -2498,28 +2539,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren); } - // create graphic controller for culling - if (kxscene->GetDbvtCulling()) - { - bool occlusion = false; - for (i=0; iGetCount();i++) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - if (gameobj->GetMeshCount() > 0) - { - MT_Point3 box[2]; - gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity()); - // box[0] is the min, box[1] is the max - bool isactive = objectlist->SearchValue(gameobj); - BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine); - if (gameobj->GetOccluder()) - occlusion = true; - } - } - if (occlusion) - kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes); - } - //set ini linearVel and int angularVel //rcruiz if (converter->addInitFromFrame) for (i=0;iGetCount();i++) @@ -2605,7 +2624,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } } - templist->Release(); sumolist->Release(); // convert global sound stuff diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index b6a59774636..b49544050d1 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -91,6 +91,15 @@ BL_MeshDeformer::~BL_MeshDeformer() delete [] m_transnors; } +void BL_MeshDeformer::ProcessReplica() +{ + m_transverts = NULL; + m_transnors = NULL; + m_tvtot = 0; + m_bDynamic=false; + m_lastDeformUpdate = -1; +} + void BL_MeshDeformer::Relink(GEN_Map*map) { void **h_obj = (*map)[m_gameobj]; diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 11ca3b00a1d..99ae5f9dea0 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -66,7 +66,7 @@ public: virtual bool Update(void){ return false; }; virtual bool UpdateBuckets(void){ return false; }; virtual RAS_Deformer* GetReplica(){return NULL;}; - virtual void ProcessReplica() {m_bDynamic=false;}; + virtual void ProcessReplica(); struct Mesh* GetMesh() { return m_bmesh; }; // virtual void InitDeform(double time){}; diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index 3c4c0c5caad..fe539f9a6c5 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -72,8 +72,11 @@ extern "C"{ BL_ModifierDeformer::~BL_ModifierDeformer() { if (m_dm) { - m_dm->needsFree = 1; - m_dm->release(m_dm); + // deformedOnly is used as a user counter + if (--m_dm->deformedOnly == 0) { + m_dm->needsFree = 1; + m_dm->release(m_dm); + } } }; @@ -90,7 +93,10 @@ void BL_ModifierDeformer::ProcessReplica() { /* Note! - This is not inherited from PyObjectPlus */ BL_ShapeDeformer::ProcessReplica(); - m_dm = NULL; + if (m_dm) + // by default try to reuse mesh, deformedOnly is used as a user count + m_dm->deformedOnly++; + // this will force an update and if the mesh cannot be reused, a new one will be created m_lastModifierUpdate = -1; } @@ -117,29 +123,40 @@ bool BL_ModifierDeformer::Update(void) bool bShapeUpdate = BL_ShapeDeformer::Update(); if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) { - /* execute the modifiers */ - Object* blendobj = m_gameobj->GetBlendObject(); - /* hack: the modifiers require that the mesh is attached to the object - It may not be the case here because of replace mesh actuator */ - Mesh *oldmesh = (Mesh*)blendobj->data; - blendobj->data = m_bmesh; - /* execute the modifiers */ - DerivedMesh *dm = mesh_create_derived_no_virtual(blendobj, m_transverts, CD_MASK_MESH); - /* restore object data */ - blendobj->data = oldmesh; - /* free the current derived mesh and replace, (dm should never be NULL) */ - if (m_dm != NULL) { - m_dm->needsFree = 1; + // static derived mesh are not updated + if (m_dm == NULL || m_bDynamic) { + /* execute the modifiers */ + Object* blendobj = m_gameobj->GetBlendObject(); + /* hack: the modifiers require that the mesh is attached to the object + It may not be the case here because of replace mesh actuator */ + Mesh *oldmesh = (Mesh*)blendobj->data; + blendobj->data = m_bmesh; + /* execute the modifiers */ + DerivedMesh *dm = mesh_create_derived_no_virtual(blendobj, m_transverts, CD_MASK_MESH); + /* restore object data */ + blendobj->data = oldmesh; + /* free the current derived mesh and replace, (dm should never be NULL) */ + if (m_dm != NULL) { + // HACK! use deformedOnly as a user counter + if (--m_dm->deformedOnly == 0) { + m_dm->needsFree = 1; + m_dm->release(m_dm); + } + } + m_dm = dm; + // get rid of temporary data + m_dm->needsFree = 0; m_dm->release(m_dm); - } - m_dm = dm; - /* update the graphic controller */ - PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController(); - if (ctrl) { - float min_r[3], max_r[3]; - INIT_MINMAX(min_r, max_r); - m_dm->getMinMax(m_dm, min_r, max_r); - ctrl->setLocalAabb(min_r, max_r); + // HACK! use deformedOnly as a user counter + m_dm->deformedOnly = 1; + /* update the graphic controller */ + PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController(); + if (ctrl) { + float min_r[3], max_r[3]; + INIT_MINMAX(min_r, max_r); + m_dm->getMinMax(m_dm, min_r, max_r); + ctrl->setLocalAabb(min_r, max_r); + } } m_lastModifierUpdate=m_gameobj->GetLastFrame(); bShapeUpdate = true; @@ -156,10 +173,10 @@ bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat) int nmat = m_pMeshObject->NumMaterials(); for (int imat=0; imatGetMeshMaterial(imat); - RAS_MeshSlot *slot = *mmat->m_slots[(void*)m_gameobj]; - if(!slot) + RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj]; + if(!slot || !*slot) continue; - slot->m_pDerivedMesh = m_dm; + (*slot)->m_pDerivedMesh = m_dm; } return true; } diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h index 465c287a88b..d5a1caeb91f 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.h +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -86,6 +86,11 @@ public: { m_lastModifierUpdate = -1.0; }; + virtual struct DerivedMesh* GetFinalMesh() + { + return m_dm; + } + protected: double m_lastModifierUpdate; diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index e04d4dad015..12ef3ff84f1 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -77,6 +77,12 @@ RAS_Deformer *BL_ShapeDeformer::GetReplica() return result; } +void BL_ShapeDeformer::ProcessReplica() +{ + BL_SkinDeformer::ProcessReplica(); + m_lastShapeUpdate = -1; +} + bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma) { IpoCurve *icu; @@ -163,7 +169,8 @@ bool BL_ShapeDeformer::Update(void) // check for armature deform bSkinUpdate = BL_SkinDeformer::Update(); - if (!bSkinUpdate && bShapeUpdate) { + // non dynamic deformer = Modifer without armature and shape keys, no need to create storage + if (!bSkinUpdate && bShapeUpdate && m_bDynamic) { // this means that there is no armature, we still need to copy the vertex to m_transverts // and update the normal (was not done after shape key calculation) diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index 1ec7bfdf74a..949e5e1e3ad 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -67,6 +67,7 @@ public: }; virtual RAS_Deformer *GetReplica(); + virtual void ProcessReplica(); virtual ~BL_ShapeDeformer(); bool Update (void); diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index e92c3b29543..a13f78e1b27 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -127,24 +127,26 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) if (!Update()) return false; - // the vertex cache is unique to this deformer, no need to update it - // if it wasn't updated! We must update all the materials at once - // because we will not get here again for the other material - nmat = m_pMeshObject->NumMaterials(); - for (imat=0; imatGetMeshMaterial(imat); - if(!mmat->m_slots[(void*)m_gameobj]) - continue; + if (m_transverts) { + // the vertex cache is unique to this deformer, no need to update it + // if it wasn't updated! We must update all the materials at once + // because we will not get here again for the other material + nmat = m_pMeshObject->NumMaterials(); + for (imat=0; imatGetMeshMaterial(imat); + if(!mmat->m_slots[(void*)m_gameobj]) + continue; - slot = *mmat->m_slots[(void*)m_gameobj]; + slot = *mmat->m_slots[(void*)m_gameobj]; - // for each array - for(slot->begin(it); !slot->end(it); slot->next(it)) { - // for each vertex - // copy the untransformed data from the original mvert - for(i=it.startvertex; ibegin(it); !slot->end(it); slot->next(it)) { + // for each vertex + // copy the untransformed data from the original mvert + for(i=it.startvertex; iSetMesh(meshobj, true,false); + shapeInfo->SetMesh(meshobj, dm,true,false); bm = shapeInfo->CreateBulletShape(); break; } case KX_BOUNDMESH: { - - if (!ci.m_mass ||objprop->m_softbody) - { - // mesh shapes can be shared, check first if we already have a shape on that mesh - class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false); - if (sharedShapeInfo != NULL) - { - delete shapeInfo; - shapeInfo = sharedShapeInfo; - shapeInfo->AddRef(); - } else - { - shapeInfo->SetMesh(meshobj, false,false); - } + bool useGimpact = (ci.m_mass && !objprop->m_softbody); - // Soft bodies require welding. Only avoid remove doubles for non-soft bodies! - if (objprop->m_softbody) - { - shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI - } - - bm = shapeInfo->CreateBulletShape(); - //no moving concave meshes, so don't bother calculating inertia - //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); + // mesh shapes can be shared, check first if we already have a shape on that mesh + class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact); + if (sharedShapeInfo != NULL) + { + delete shapeInfo; + shapeInfo = sharedShapeInfo; + shapeInfo->AddRef(); } else { - shapeInfo->SetMesh(meshobj, false,true); - bm = shapeInfo->CreateBulletShape(); + shapeInfo->SetMesh(meshobj, dm, false,useGimpact); } + // Soft bodies require welding. Only avoid remove doubles for non-soft bodies! + if (objprop->m_softbody) + { + shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI + } + + bm = shapeInfo->CreateBulletShape(); + //should we compute inertia for dynamic shape? + //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); + break; } } diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt index ec2cdede683..02f2aa635af 100644 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ b/source/gameengine/Physics/Bullet/CMakeLists.txt @@ -32,6 +32,7 @@ SET(INC ../../../../extern/bullet2/src ../../../../extern/glew/include ../../../../intern/moto/include + ../../../../intern/guardedalloc ../../../kernel/gen_system ../../../../intern/string ../../../../intern/SoundSystem @@ -41,6 +42,8 @@ SET(INC ../../GameLogic ../../SceneGraph ../../../../source/blender/makesdna + ../../../../source/blender/blenlib + ../../../../source/blender/blenkernel ${PYTHON_INC} ) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 961e9096442..01e8aa2560f 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -35,6 +35,10 @@ subject to the following restrictions: #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +extern "C"{ +#include "BKE_cdderivedmesh.h" +} + class BP_Proxy; ///todo: fill all the empty CcdPhysicsController methods, hook them up to the btRigidBody class @@ -1312,9 +1316,9 @@ void DefaultMotionState::calculateWorldTransformations() // Shape constructor std::map CcdShapeConstructionInfo::m_meshShapeMap; -CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, bool polytope) +CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope, bool gimpact) { - if (polytope) + if (polytope || dm || gimpact) // not yet supported return NULL; @@ -1324,9 +1328,9 @@ CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mes return NULL; } -bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bool useGimpact) +bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope,bool useGimpact) { - int numpolys; + int numpolys, numverts; m_useGimpact = useGimpact; @@ -1335,6 +1339,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo assert(IsUnused()); m_shapeType = PHY_SHAPE_NONE; m_meshObject = NULL; + bool free_dm = false; // No mesh object or mesh has no polys if (!meshobj || meshobj->HasColliderPolygon()==false) { @@ -1344,12 +1349,21 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo return false; } - numpolys = meshobj->NumPolygons(); + if (!dm) { + free_dm = true; + dm = CDDM_from_mesh(meshobj->GetMesh(), NULL); + } + + MVert *mvert = dm->getVertArray(dm); + MFace *mface = dm->getFaceArray(dm); + numpolys = dm->getNumFaces(dm); + numverts = dm->getNumVerts(dm); + int* index = (int*)dm->getFaceDataArray(dm, CD_ORIGINDEX); m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH; /* Convert blender geometry into bullet mesh, need these vars for mapping */ - vector vert_tag_array(meshobj->GetMesh()->totvert, false); + vector vert_tag_array(numverts, false); unsigned int tot_bt_verts= 0; unsigned int orig_index; int i; @@ -1359,19 +1373,16 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo // Tag verts we're using for (int p2=0; p2GetPolygon(p2); + MFace* mf = &mface[p2]; + RAS_Polygon* poly = meshobj->GetPolygon(index[p2]); // only add polygons that have the collision flag set if (poly->IsCollider()) { - for(i=0; iVertexCount(); i++) { - orig_index= poly->GetVertex(i)->getOrigIndex(); - if (vert_tag_array[orig_index]==false) - { - vert_tag_array[orig_index]= true; - tot_bt_verts++; - } - } + if (vert_tag_array[mf->v1]==false) {vert_tag_array[mf->v1]= true;tot_bt_verts++;} + if (vert_tag_array[mf->v2]==false) {vert_tag_array[mf->v2]= true;tot_bt_verts++;} + if (vert_tag_array[mf->v3]==false) {vert_tag_array[mf->v3]= true;tot_bt_verts++;} + if (mf->v4 && vert_tag_array[mf->v4]==false) {vert_tag_array[mf->v4]= true;tot_bt_verts++;} } } @@ -1381,51 +1392,69 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo for (int p2=0; p2GetPolygon(p2); + MFace* mf = &mface[p2]; + RAS_Polygon* poly= meshobj->GetPolygon(index[p2]); // only add polygons that have the collisionflag set if (poly->IsCollider()) { - for(i=0; iVertexCount(); i++) { - RAS_TexVert *v= poly->GetVertex(i); - orig_index= v->getOrigIndex(); - - if (vert_tag_array[orig_index]==true) - { - const float* vtx = v->getXYZ(); - vert_tag_array[orig_index]= false; - - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; - } + if (vert_tag_array[mf->v1]==true) + { + const float* vtx = mvert[mf->v1].co; + vert_tag_array[mf->v1]= false; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; + } + if (vert_tag_array[mf->v2]==true) + { + const float* vtx = mvert[mf->v2].co; + vert_tag_array[mf->v2]= false; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; + } + if (vert_tag_array[mf->v3]==true) + { + const float* vtx = mvert[mf->v3].co; + vert_tag_array[mf->v3]= false; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; + } + if (mf->v4 && vert_tag_array[mf->v4]==true) + { + const float* vtx = mvert[mf->v4].co; + vert_tag_array[mf->v4]= false; + *bt++ = vtx[0]; + *bt++ = vtx[1]; + *bt++ = vtx[2]; } } } } else { unsigned int tot_bt_tris= 0; - vector vert_remap_array(meshobj->GetMesh()->totvert, 0); + vector vert_remap_array(numverts, 0); // Tag verts we're using for (int p2=0; p2GetPolygon(p2); + MFace* mf = &mface[p2]; + RAS_Polygon* poly= meshobj->GetPolygon(index[p2]); // only add polygons that have the collision flag set if (poly->IsCollider()) { - for(i=0; iVertexCount(); i++) { - orig_index= poly->GetVertex(i)->getOrigIndex(); - if (vert_tag_array[orig_index]==false) - { - vert_tag_array[orig_index]= true; - vert_remap_array[orig_index]= tot_bt_verts; - tot_bt_verts++; - } - } - - tot_bt_tris += (i==4 ? 2:1); /* a quad or a tri */ + if (vert_tag_array[mf->v1]==false) + {vert_tag_array[mf->v1]= true;vert_remap_array[mf->v1]= tot_bt_verts;tot_bt_verts++;} + if (vert_tag_array[mf->v2]==false) + {vert_tag_array[mf->v2]= true;vert_remap_array[mf->v2]= tot_bt_verts;tot_bt_verts++;} + if (vert_tag_array[mf->v3]==false) + {vert_tag_array[mf->v3]= true;vert_remap_array[mf->v3]= tot_bt_verts;tot_bt_verts++;} + if (mf->v4 && vert_tag_array[mf->v4]==false) + {vert_tag_array[mf->v4]= true;vert_remap_array[mf->v4]= tot_bt_verts;tot_bt_verts++;} + tot_bt_tris += (mf->v4 ? 2:1); /* a quad or a tri */ } } @@ -1437,76 +1466,67 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo int *poly_index_pt= &m_polygonIndexArray[0]; int *tri_pt= &m_triFaceArray[0]; - for (int p2=0; p2GetPolygon(p2); + MFace* mf = &mface[p2]; + RAS_Polygon* poly= meshobj->GetPolygon(index[p2]); // only add polygons that have the collisionflag set if (poly->IsCollider()) { - RAS_TexVert *v1= poly->GetVertex(0); - RAS_TexVert *v2= poly->GetVertex(1); - RAS_TexVert *v3= poly->GetVertex(2); - int i1= v1->getOrigIndex(); - int i2= v2->getOrigIndex(); - int i3= v3->getOrigIndex(); - const float* vtx; + MVert *v1= &mvert[mf->v1]; + MVert *v2= &mvert[mf->v2]; + MVert *v3= &mvert[mf->v3]; // the face indicies - tri_pt[0]= vert_remap_array[i1]; - tri_pt[1]= vert_remap_array[i2]; - tri_pt[2]= vert_remap_array[i3]; + tri_pt[0]= vert_remap_array[mf->v1]; + tri_pt[1]= vert_remap_array[mf->v2]; + tri_pt[2]= vert_remap_array[mf->v3]; tri_pt= tri_pt+3; // m_polygonIndexArray - *poly_index_pt= p2; + *poly_index_pt= index[p2]; poly_index_pt++; // the vertex location - if (vert_tag_array[i1]==true) { /* *** v1 *** */ - vert_tag_array[i1]= false; - vtx = v1->getXYZ(); - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; + if (vert_tag_array[mf->v1]==true) { /* *** v1 *** */ + vert_tag_array[mf->v1]= false; + *bt++ = v1->co[0]; + *bt++ = v1->co[1]; + *bt++ = v1->co[2]; } - if (vert_tag_array[i2]==true) { /* *** v2 *** */ - vert_tag_array[i2]= false; - vtx = v2->getXYZ(); - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; + if (vert_tag_array[mf->v2]==true) { /* *** v2 *** */ + vert_tag_array[mf->v2]= false; + *bt++ = v2->co[0]; + *bt++ = v2->co[1]; + *bt++ = v2->co[2]; } - if (vert_tag_array[i3]==true) { /* *** v3 *** */ - vert_tag_array[i3]= false; - vtx = v3->getXYZ(); - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; + if (vert_tag_array[mf->v3]==true) { /* *** v3 *** */ + vert_tag_array[mf->v3]= false; + *bt++ = v3->co[0]; + *bt++ = v3->co[1]; + *bt++ = v3->co[2]; } - if (poly->VertexCount()==4) + if (mf->v4) { - RAS_TexVert *v4= poly->GetVertex(3); - int i4= v4->getOrigIndex(); + MVert *v4= &mvert[mf->v4]; - tri_pt[0]= vert_remap_array[i1]; - tri_pt[1]= vert_remap_array[i3]; - tri_pt[2]= vert_remap_array[i4]; + tri_pt[0]= vert_remap_array[mf->v1]; + tri_pt[1]= vert_remap_array[mf->v3]; + tri_pt[2]= vert_remap_array[mf->v4]; tri_pt= tri_pt+3; // m_polygonIndexArray - *poly_index_pt= p2; + *poly_index_pt= index[p2]; poly_index_pt++; // the vertex location - if (vert_tag_array[i4]==true) { /* *** v4 *** */ - vert_tag_array[i4]= false; - vtx = v4->getXYZ(); - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; + if (vert_tag_array[mf->v4]==true) { /* *** v4 *** */ + vert_tag_array[mf->v4]= false; + *bt++ = v4->co[0]; + *bt++ = v4->co[1]; + *bt++ = v4->co[2]; } } } @@ -1538,7 +1558,13 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo #endif m_meshObject = meshobj; - if (!polytope) + if (free_dm) { + dm->release(dm); + dm = NULL; + } + + // sharing only on static mesh at present, if you change that, you must also change in FindMesh + if (!polytope && !dm && !useGimpact) { // triangle shape can be shared, store the mesh object in the map m_meshShapeMap.insert(std::pair(meshobj,this)); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 4ab478b2106..315e2bdf429 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -36,6 +36,7 @@ extern bool gDisableDeactivation; class CcdPhysicsEnvironment; class btMotionState; class RAS_MeshObject; +struct DerivedMesh; class btCollisionShape; @@ -59,7 +60,7 @@ class CcdShapeConstructionInfo public: - static CcdShapeConstructionInfo* FindMesh(RAS_MeshObject* mesh, bool polytope); + static CcdShapeConstructionInfo* FindMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope, bool gimpact); CcdShapeConstructionInfo() : m_shapeType(PHY_SHAPE_NONE), @@ -139,7 +140,7 @@ public: return true; } - bool SetMesh(RAS_MeshObject* mesh, bool polytope,bool useGimpact); + bool SetMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope,bool useGimpact); RAS_MeshObject* GetMesh(void) { return m_meshObject; diff --git a/source/gameengine/Physics/Bullet/Makefile b/source/gameengine/Physics/Bullet/Makefile index 48e537bb6a3..19b17de275a 100644 --- a/source/gameengine/Physics/Bullet/Makefile +++ b/source/gameengine/Physics/Bullet/Makefile @@ -51,4 +51,6 @@ CPPFLAGS += -I../../Expressions CPPFLAGS += -I../../GameLogic CPPFLAGS += -I../../SceneGraph CPPFLAGS += -I../../../../source/blender/makesdna +CPPFLAGS += -I../../../../source/blender/blenkernel +CPPFLAGS += -I../../../../source/blender/blenlib diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index 115ab8bf730..c517d8b5d9d 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -14,7 +14,10 @@ incs += ' #source/gameengine/Expressions' incs += ' #source/gameengine/GameLogic' incs += ' #source/gameengine/SceneGraph' incs += ' #source/blender/makesdna' +incs += ' #source/blender/blenkernel' +incs += ' #source/blender/blenlib' incs += ' #intern/SoundSystem' +incs += ' #intern/guardedalloc' incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index bb8e3750485..9dc656ba56a 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -34,12 +34,15 @@ #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning #endif //WIN32 +#include #include "GEN_Map.h" +struct DerivedMesh; + class RAS_Deformer { public: - RAS_Deformer() : m_pMesh(0), m_bDynamic(false) {}; + RAS_Deformer() : m_pMesh(NULL), m_bDynamic(false) {}; virtual ~RAS_Deformer(){}; virtual void Relink(GEN_Map*map)=0; virtual bool Apply(class RAS_IPolyMaterial *polymat)=0; @@ -60,6 +63,11 @@ public: { return m_bDynamic; } + virtual struct DerivedMesh* GetFinalMesh() + { + return NULL; + } + protected: class RAS_MeshObject *m_pMesh; bool m_bDynamic; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index f5324c6fbc9..014169f8838 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -118,16 +118,24 @@ RAS_ListRasterizer::~RAS_ListRasterizer() void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list) { - if (list->m_flag & LIST_STANDALONE) - return ; - - RAS_ArrayLists::iterator it = mArrayLists.begin(); - while(it != mArrayLists.end()) { - if (it->second == list) { - mArrayLists.erase(it); - break; + if (list->m_flag & LIST_DERIVEDMESH) { + RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin(); + while(it != mDerivedMeshLists.end()) { + if (it->second == list) { + mDerivedMeshLists.erase(it); + break; + } + it++; + } + } else { + RAS_ArrayLists::iterator it = mArrayLists.begin(); + while(it != mArrayLists.end()) { + if (it->second == list) { + mArrayLists.erase(it); + break; + } + it++; } - it++; } } @@ -143,9 +151,15 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms) if(!localSlot) { if (ms.m_pDerivedMesh) { // that means that we draw based on derived mesh, a display list is possible - // but it's unique to this mesh slot - localSlot = new RAS_ListSlot(this); - localSlot->m_flag |= LIST_STANDALONE; + // Note that we come here only for static derived mesh + RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.find(ms.m_pDerivedMesh); + if(it == mDerivedMeshLists.end()) { + localSlot = new RAS_ListSlot(this); + localSlot->m_flag |= LIST_DERIVEDMESH; + mDerivedMeshLists.insert(std::pair(ms.m_pDerivedMesh, localSlot)); + } else { + localSlot = static_cast(it->second->AddRef()); + } } else { RAS_ArrayLists::iterator it = mArrayLists.find(ms.m_displayArrays); if(it == mArrayLists.end()) { @@ -162,12 +176,12 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms) void RAS_ListRasterizer::ReleaseAlloc() { - RAS_ArrayLists::iterator it = mArrayLists.begin(); - while(it != mArrayLists.end()) { + for(RAS_ArrayLists::iterator it = mArrayLists.begin();it != mArrayLists.end();++it) delete it->second; - it++; - } mArrayLists.clear(); + for (RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin();it != mDerivedMeshLists.end();++it) + delete it->second; + mDerivedMeshLists.clear(); } void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index 912f28af6aa..fe358808e4a 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -34,16 +34,20 @@ enum RAS_ListSlotFlags { LIST_BEGIN =16, LIST_END =32, LIST_REGEN =64, - LIST_STANDALONE =128, + LIST_DERIVEDMESH=128, }; +struct DerivedMesh; + typedef std::map RAS_ArrayLists; +typedef std::map RAS_DerivedMeshLists; class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer { bool mUseVertexArrays; bool mATI; RAS_ArrayLists mArrayLists; + RAS_DerivedMeshLists mDerivedMeshLists; RAS_ListSlot* FindOrAdd(class RAS_MeshSlot& ms); void ReleaseAlloc(); From 23251ba286dd6af4101e61371925b25e8ea00fec Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 14 May 2009 18:32:27 +0000 Subject: [PATCH 240/444] Fix for bug #18622 Snapping has to be reinit after changing mode during transform. Needs to be fixed in 2.5 too, but a tad differently. --- source/blender/src/transform.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index a1abc5ea6bb..f0ae37e8d87 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -740,6 +740,7 @@ static void transformEvent(unsigned short event, short val) { resetTransRestrictions(&Trans); restoreTransObjects(&Trans); initTranslation(&Trans); + initSnapping(&Trans); Trans.redraw = 1; } break; @@ -749,6 +750,7 @@ static void transformEvent(unsigned short event, short val) { resetTransRestrictions(&Trans); restoreTransObjects(&Trans); initResize(&Trans); + initSnapping(&Trans); Trans.redraw = 1; } break; @@ -766,6 +768,7 @@ static void transformEvent(unsigned short event, short val) { restoreTransObjects(&Trans); initRotation(&Trans); } + initSnapping(&Trans); Trans.redraw = 1; } break; From a20a2ebb9f5cb0854793464c805043acf81101ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 May 2009 21:06:48 +0000 Subject: [PATCH 241/444] [#18749] BGE: Crash on joysticksensor.getAxisValue() negative index would be used when the joystick was not found, crashing python api, initialize these as 0 now. --- source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index c300baa9bd4..c32ff303aea 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -220,12 +220,17 @@ int SCA_Joystick::GetNumberOfHats() bool SCA_Joystick::CreateJoystickDevice(void) { #ifdef DISABLE_SDL + m_isinit = true; + m_axismax = m_buttonmax = m_hatmax = 0; return false; #else if(m_isinit == false){ if (m_joyindex>=SDL_NumJoysticks()) { // don't print a message, because this is done anyway //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)"); + + // Need this so python args can return empty lists + m_axismax = m_buttonmax = m_hatmax = 0; return false; } @@ -237,12 +242,14 @@ bool SCA_Joystick::CreateJoystickDevice(void) /* must run after being initialized */ m_axismax = SDL_JoystickNumAxes(m_private->m_joystick); - if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX; /* very unlikely */ - m_buttonmax = SDL_JoystickNumButtons(m_private->m_joystick); m_hatmax = SDL_JoystickNumHats(m_private->m_joystick); + if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX; /* very unlikely */ + else if (m_axismax < 0) m_axismax = 0; + if(m_buttonmax<0) m_buttonmax= 0; + if(m_hatmax<0) m_buttonmax= 0; } return true; #endif From 0e423e5bb61cdce77aa6cd527f6bf2521b9b33c6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 May 2009 23:06:05 +0000 Subject: [PATCH 242/444] BGE PyAPI [#18701] Issues with camera.pointInsideFrustum method - note in docs that the projection matrix is not correct for first logic tick. Renamed... KX_Camera.isViewport -> KX_Camera.useViewport KX_Lamp.quat_attenuation -> KX_Lamp.quad_attenuation Deprecated KX_Camera.getProjectionMatrix(), KX_Camera.setProjectionMatrix() for projection_matrix attr Added most missing docs reported by the doc-checker script --- source/gameengine/Ketsji/KX_Camera.cpp | 17 +- source/gameengine/Ketsji/KX_Camera.h | 4 +- source/gameengine/Ketsji/KX_Light.cpp | 2 +- source/gameengine/PyDoc/GameLogic.py | 156 +++++++------ source/gameengine/PyDoc/GameTypes.py | 298 +++++++++++++------------ 5 files changed, 256 insertions(+), 221 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index df39faf8b22..0d2e68243f8 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -476,13 +476,13 @@ PyMethodDef KX_Camera::Methods[] = { KX_PYMETHODTABLE_O(KX_Camera, pointInsideFrustum), KX_PYMETHODTABLE_NOARGS(KX_Camera, getCameraToWorld), KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera), - KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix), - KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix), KX_PYMETHODTABLE(KX_Camera, setViewport), KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop), // DEPRECATED KX_PYMETHODTABLE_O(KX_Camera, enableViewport), + KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix), + KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix), {NULL,NULL} //Sentinel }; @@ -496,9 +496,9 @@ PyAttributeDef KX_Camera::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("near", KX_Camera, pyattr_get_near, pyattr_set_near), KX_PYATTRIBUTE_RW_FUNCTION("far", KX_Camera, pyattr_get_far, pyattr_set_far), - KX_PYATTRIBUTE_RW_FUNCTION("isViewport", KX_Camera, pyattr_get_is_viewport, pyattr_set_is_viewport), + KX_PYATTRIBUTE_RW_FUNCTION("useViewport", KX_Camera, pyattr_get_use_viewport, pyattr_set_use_viewport), - KX_PYATTRIBUTE_RO_FUNCTION("projection_matrix", KX_Camera, pyattr_get_projection_matrix), + KX_PYATTRIBUTE_RW_FUNCTION("projection_matrix", KX_Camera, pyattr_get_projection_matrix, pyattr_set_projection_matrix), KX_PYATTRIBUTE_RO_FUNCTION("modelview_matrix", KX_Camera, pyattr_get_modelview_matrix), KX_PYATTRIBUTE_RO_FUNCTION("camera_to_world", KX_Camera, pyattr_get_camera_to_world), KX_PYATTRIBUTE_RO_FUNCTION("world_to_camera", KX_Camera, pyattr_get_world_to_camera), @@ -693,6 +693,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getProjectionMatrix, "\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n" ) { + ShowDeprecationWarning("getProjectionMatrix()", "the projection_matrix property"); return PyObjectFrom(GetProjectionMatrix()); /* new ref */ } @@ -738,6 +739,8 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, setProjectionMatrix, "\tcam = co.getOwner()\n" "\tcam.setProjectionMatrix(Perspective(-1.0, 1.0, -1.0, 1.0, 0.1, 1))\n") { + ShowDeprecationWarning("setProjectionMatrix(mat)", "the projection_matrix property"); + MT_Matrix4x4 mat; if (!PyMatTo(value, mat)) { @@ -871,18 +874,18 @@ int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, P } -PyObject* KX_Camera::pyattr_get_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +PyObject* KX_Camera::pyattr_get_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Camera* self= static_cast(self_v); return PyBool_FromLong(self->GetViewport()); } -int KX_Camera::pyattr_set_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +int KX_Camera::pyattr_set_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_Camera* self= static_cast(self_v); int param = PyObject_IsTrue( value ); if (param == -1) { - PyErr_SetString(PyExc_AttributeError, "camera.isViewport = bool: KX_Camera, expected True or False"); + PyErr_SetString(PyExc_AttributeError, "camera.useViewport = bool: KX_Camera, expected True or False"); return 1; } self->EnableViewport((bool)param); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index ce8bbb8d656..c00741bf43f 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -287,8 +287,8 @@ public: static PyObject* pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); - static PyObject* pyattr_get_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); - static int pyattr_set_is_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 3af34c39123..df7691d016b 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -235,7 +235,7 @@ PyAttributeDef KX_LightObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("color", KX_LightObject, pyattr_get_color, pyattr_set_color), KX_PYATTRIBUTE_RW_FUNCTION("colour", KX_LightObject, pyattr_get_color, pyattr_set_color), KX_PYATTRIBUTE_FLOAT_RW("lin_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att1), - KX_PYATTRIBUTE_FLOAT_RW("quat_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att2), + KX_PYATTRIBUTE_FLOAT_RW("quad_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att2), KX_PYATTRIBUTE_FLOAT_RW("spotsize", 1, 180, KX_LightObject, m_lightobj.m_spotsize), KX_PYATTRIBUTE_FLOAT_RW("spotblend", 0, 1, KX_LightObject, m_lightobj.m_spotblend), KX_PYATTRIBUTE_RO_FUNCTION("SPOT", KX_LightObject, pyattr_get_typeconst), diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index a0be06e8830..9b87842f7e0 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -104,17 +104,14 @@ Documentation for the GameLogic Module. @var KX_TRUE: True value used by some modules. @var KX_FALSE: False value used by some modules. -@group Property Sensor: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, KX_PROPSENSOR_EXPRESSION +@group Property Sensor: KX_PROPSENSOR_* @var KX_PROPSENSOR_EQUAL: Activate when the property is equal to the sensor value. @var KX_PROPSENSOR_NOTEQUAL: Activate when the property is not equal to the sensor value. @var KX_PROPSENSOR_INTERVAL: Activate when the property is between the specified limits. @var KX_PROPSENSOR_CHANGED: Activate when the property changes @var KX_PROPSENSOR_EXPRESSION: Activate when the expression matches - - - -@group Constraint Actuator: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ, KX_CONSTRAINTACT_DIRNX, KX_CONSTRAINTACT_DIRNY, KX_CONSTRAINTACT_DIRPX, KX_CONSTRAINTACT_DIRPY, KX_CONSTRAINTACT_ORIX, KX_CONSTRAINTACT_ORIY, KX_CONSTRAINTACT_ORIZ +@group Constraint Actuator: KX_CONSTRAINTACT_* @var KX_CONSTRAINTACT_LOCX: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_LOCY: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_LOCZ: See L{KX_ConstraintActuator} @@ -129,7 +126,7 @@ Documentation for the GameLogic Module. @var KX_CONSTRAINTACT_ORIY: See L{KX_ConstraintActuator} @var KX_CONSTRAINTACT_ORIZ: See L{KX_ConstraintActuator} -@group IPO Actuator: KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND, KX_IPOACT_FROM_PROP +@group IPO Actuator: KX_IPOACT_* @var KX_IPOACT_PLAY: See L{KX_IpoActuator} @var KX_IPOACT_PINGPONG: See L{KX_IpoActuator} @var KX_IPOACT_FLIPPER: See L{KX_IpoActuator} @@ -137,7 +134,7 @@ Documentation for the GameLogic Module. @var KX_IPOACT_LOOPEND: See L{KX_IpoActuator} @var KX_IPOACT_FROM_PROP: See L{KX_IpoActuator} -@group Random Distributions: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL +@group Random Distributions: KX_RANDOMACT_* @var KX_RANDOMACT_BOOL_CONST: See L{SCA_RandomActuator} @var KX_RANDOMACT_BOOL_UNIFORM: See L{SCA_RandomActuator} @var KX_RANDOMACT_BOOL_BERNOUILLI: See L{SCA_RandomActuator} @@ -149,14 +146,14 @@ Documentation for the GameLogic Module. @var KX_RANDOMACT_FLOAT_NORMAL: See L{SCA_RandomActuator} @var KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL: See L{SCA_RandomActuator} -@group Action Actuator: KX_ACTIONACT_PLAY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND, KX_ACTIONACT_PROPERTY +@group Action Actuator: KX_ACTIONACT_* @var KX_ACTIONACT_PLAY: See L{BL_ActionActuator} @var KX_ACTIONACT_FLIPPER: See L{BL_ActionActuator} @var KX_ACTIONACT_LOOPSTOP: See L{BL_ActionActuator} @var KX_ACTIONACT_LOOPEND: See L{BL_ActionActuator} @var KX_ACTIONACT_PROPERTY: See L{BL_ActionActuator} -@group Sound Actuator: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP +@group Sound Actuator: KX_SOUNDACT_* @var KX_SOUNDACT_PLAYSTOP: See L{KX_SoundActuator} @var KX_SOUNDACT_PLAYEND: See L{KX_SoundActuator} @var KX_SOUNDACT_LOOPSTOP: See L{KX_SoundActuator} @@ -164,7 +161,7 @@ Documentation for the GameLogic Module. @var KX_SOUNDACT_LOOPBIDIRECTIONAL: See L{KX_SoundActuator} @var KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: See L{KX_SoundActuator} -@group Radar Sensor: KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z +@group Radar Sensor: KX_RADAR_* @var KX_RADAR_AXIS_POS_X: See L{KX_RadarSensor} @var KX_RADAR_AXIS_POS_Y: See L{KX_RadarSensor} @var KX_RADAR_AXIS_POS_Z: See L{KX_RadarSensor} @@ -172,7 +169,7 @@ Documentation for the GameLogic Module. @var KX_RADAR_AXIS_NEG_Y: See L{KX_RadarSensor} @var KX_RADAR_AXIS_NEG_Z: See L{KX_RadarSensor} -@group Ray Sensor: KX_RAY_AXIS_POS_X, KX_RAY_AXIS_POS_Y, KX_RAY_AXIS_POS_Z, KX_RAY_AXIS_NEG_X, KX_RAY_AXIS_NEG_Y, KX_RAY_AXIS_NEG_Z +@group Ray Sensor: KX_RAY_* @var KX_RAY_AXIS_POS_X: See L{KX_RaySensor} @var KX_RAY_AXIS_POS_Y: See L{KX_RaySensor} @var KX_RAY_AXIS_POS_Z: See L{KX_RaySensor} @@ -180,44 +177,44 @@ Documentation for the GameLogic Module. @var KX_RAY_AXIS_NEG_Y: See L{KX_RaySensor} @var KX_RAY_AXIS_NEG_Z: See L{KX_RaySensor} -@group Dynamic Actuator: KX_DYN_RESTORE_DYNAMICS, KX_DYN_DISABLE_DYNAMICS, KX_DYN_ENABLE_RIGID_BODY, KX_DYN_DISABLE_RIGID_BODY, KX_DYN_SET_MASS +@group Dynamic Actuator: KX_DYN_* @var KX_DYN_RESTORE_DYNAMICS: See L{KX_SCA_DynamicActuator} @var KX_DYN_DISABLE_DYNAMICS: See L{KX_SCA_DynamicActuator} @var KX_DYN_ENABLE_RIGID_BODY: See L{KX_SCA_DynamicActuator} @var KX_DYN_DISABLE_RIGID_BODY: See L{KX_SCA_DynamicActuator} @var KX_DYN_SET_MASS: See L{KX_SCA_DynamicActuator} -@group Game Actuator: KX_GAME_LOAD, KX_GAME_START, KX_GAME_RESTART, KX_GAME_QUIT, KX_GAME_SAVECFG, KX_GAME_LOADCFG -@var KX_Game_LOAD: See L{KX_GameActuator} -@var KX_Game_START: See L{KX_GameActuator} -@var KX_Game_RESTART: See L{KX_GameActuator} -@var KX_Game_QUIT: See L{KX_GameActuator} -@var KX_Game_SAVECFG: See L{KX_GameActuator} -@var KX_Game_LOADCFG: See L{KX_GameActuator} +@group Game Actuator: KX_GAME_* +@var KX_GAME_LOAD: See L{KX_GameActuator} +@var KX_GAME_START: See L{KX_GameActuator} +@var KX_GAME_RESTART: See L{KX_GameActuator} +@var KX_GAME_QUIT: See L{KX_GameActuator} +@var KX_GAME_SAVECFG: See L{KX_GameActuator} +@var KX_GAME_LOADCFG: See L{KX_GameActuator} -@group Scene Actuator: KX_SCENE_RESTART, KX_SCENE_SET_SCENE, KX_SCENE_SET_CAMERA, KX_SCENE_ADD_FRONT_SCENE, KX_SCENE_ADD_BACK_SCENE, KX_SCENE_REMOVE_SCENE, KX_SCENE_SUSPEND, KX_SCENE_RESUME -KX_SCENE_RESTART: See L{KX_SceneActuator} -KX_SCENE_SET_SCENE: See L{KX_SceneActuator} -KX_SCENE_SET_CAMERA: See L{KX_SceneActuator} -KX_SCENE_ADD_FRONT_SCENE: See L{KX_SceneActuator} -KX_SCENE_ADD_BACK_SCENE: See L{KX_SceneActuator} -KX_SCENE_REMOVE_SCENE: See L{KX_SceneActuator} -KX_SCENE_SUSPEND: See L{KX_SceneActuator} -KX_SCENE_RESUME: See L{KX_SceneActuator} +@group Scene Actuator: KX_SCENE_* +@var KX_SCENE_RESTART: See L{KX_SceneActuator} +@var KX_SCENE_SET_SCENE: See L{KX_SceneActuator} +@var KX_SCENE_SET_CAMERA: See L{KX_SceneActuator} +@var KX_SCENE_ADD_FRONT_SCENE: See L{KX_SceneActuator} +@var KX_SCENE_ADD_BACK_SCENE: See L{KX_SceneActuator} +@var KX_SCENE_REMOVE_SCENE: See L{KX_SceneActuator} +@var KX_SCENE_SUSPEND: See L{KX_SceneActuator} +@var KX_SCENE_RESUME: See L{KX_SceneActuator} -@group Input Status: KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED +@group Input Status: KX_INPUT_* @var KX_INPUT_NONE: See L{SCA_MouseSensor} @var KX_INPUT_JUST_ACTIVATED: See L{SCA_MouseSensor} @var KX_INPUT_ACTIVE: See L{SCA_MouseSensor} @var KX_INPUT_JUST_RELEASED: See L{SCA_MouseSensor} -@group Mouse Buttons: KX_MOUSE_BUT_LEFT, KX_MOUSE_BUT_MIDDLE, KX_MOUSE_BUT_RIGHT +@group Mouse Buttons: KX_MOUSE_BUT_* @var KX_MOUSE_BUT_LEFT: See L{SCA_MouseSensor} @var KX_MOUSE_BUT_MIDDLE: See L{SCA_MouseSensor} @var KX_MOUSE_BUT_RIGHT: See L{SCA_MouseSensor} -@group States: KX_STATE1, KX_STATE10, KX_STATE11, KX_STATE12, KX_STATE13, KX_STATE14, KX_STATE15, KX_STATE16, KX_STATE17, KX_STATE18, KX_STATE19, KX_STATE2, KX_STATE20, KX_STATE21, KX_STATE22, KX_STATE23, KX_STATE24, KX_STATE25, KX_STATE26, KX_STATE27, KX_STATE28, KX_STATE29, KX_STATE3, KX_STATE30, KX_STATE4, KX_STATE5, KX_STATE6, KX_STATE7, KX_STATE8, KX_STATE9, KX_STATE_OP_CLR, KX_STATE_OP_CPY, KX_STATE_OP_NEG, KX_STATE_OP_SET +@group States: KX_STATE* @var KX_STATE1: @var KX_STATE10: @var KX_STATE11: @@ -253,40 +250,7 @@ KX_SCENE_RESUME: See L{KX_SceneActuator} @var KX_STATE_OP_NEG: @var KX_STATE_OP_SET: -@group UNSORTED: BL_DST_ALPHA, BL_DST_COLOR, BL_ONE, BL_ONE_MINUS_DST_ALPHA, BL_ONE_MINUS_DST_COLOR, BL_ONE_MINUS_SRC_ALPHA, BL_ONE_MINUS_SRC_COLOR, BL_SRC_ALPHA, BL_SRC_ALPHA_SATURATE, BL_SRC_COLOR, BL_ZERO, CAM_POS, CONSTANT_TIMER, KX_ACT_CONSTRAINT_DISTANCE, KX_ACT_CONSTRAINT_DOROTFH, KX_ACT_CONSTRAINT_FHNX, KX_ACT_CONSTRAINT_FHNY, KX_ACT_CONSTRAINT_FHNZ, KX_ACT_CONSTRAINT_FHPX, KX_ACT_CONSTRAINT_FHPY, KX_ACT_CONSTRAINT_FHPZ, KX_ACT_CONSTRAINT_LOCAL, KX_ACT_CONSTRAINT_MATERIAL, KX_ACT_CONSTRAINT_NORMAL, KX_ACT_CONSTRAINT_PERMANENT, MODELMATRIX, MODELMATRIX_INVERSE, MODELMATRIX_INVERSETRANSPOSE, MODELMATRIX_TRANSPOSE, MODELVIEWMATRIX, MODELVIEWMATRIX_INVERSE, MODELVIEWMATRIX_INVERSETRANSPOSE, MODELVIEWMATRIX_TRANSPOSE, RAS_2DFILTER_BLUR, RAS_2DFILTER_CUSTOMFILTER, RAS_2DFILTER_DILATION, RAS_2DFILTER_DISABLED, RAS_2DFILTER_ENABLED, RAS_2DFILTER_EROSION, RAS_2DFILTER_GRAYSCALE, RAS_2DFILTER_INVERT, RAS_2DFILTER_LAPLACIAN, RAS_2DFILTER_MOTIONBLUR, RAS_2DFILTER_NOFILTER, RAS_2DFILTER_PREWITT, RAS_2DFILTER_SEPIA, RAS_2DFILTER_SHARPEN, RAS_2DFILTER_SOBEL, SHD_TANGENT, VIEWMATRIX, VIEWMATRIX_INVERSE, VIEWMATRIX_INVERSETRANSPOSE, VIEWMATRIX_TRANSPOSE -@var BL_DST_ALPHA: -@var BL_DST_COLOR: -@var BL_ONE: -@var BL_ONE_MINUS_DST_ALPHA: -@var BL_ONE_MINUS_DST_COLOR: -@var BL_ONE_MINUS_SRC_ALPHA: -@var BL_ONE_MINUS_SRC_COLOR: -@var BL_SRC_ALPHA: -@var BL_SRC_ALPHA_SATURATE: -@var BL_SRC_COLOR: -@var BL_ZERO: -@var CAM_POS: -@var CONSTANT_TIMER: -@var KX_ACT_CONSTRAINT_DISTANCE: -@var KX_ACT_CONSTRAINT_DOROTFH: -@var KX_ACT_CONSTRAINT_FHNX: -@var KX_ACT_CONSTRAINT_FHNY: -@var KX_ACT_CONSTRAINT_FHNZ: -@var KX_ACT_CONSTRAINT_FHPX: -@var KX_ACT_CONSTRAINT_FHPY: -@var KX_ACT_CONSTRAINT_FHPZ: -@var KX_ACT_CONSTRAINT_LOCAL: -@var KX_ACT_CONSTRAINT_MATERIAL: -@var KX_ACT_CONSTRAINT_NORMAL: -@var KX_ACT_CONSTRAINT_PERMANENT: -@var MODELMATRIX: -@var MODELMATRIX_INVERSE: -@var MODELMATRIX_INVERSETRANSPOSE: -@var MODELMATRIX_TRANSPOSE: -@var MODELVIEWMATRIX: -@var MODELVIEWMATRIX_INVERSE: -@var MODELVIEWMATRIX_INVERSETRANSPOSE: -@var MODELVIEWMATRIX_TRANSPOSE: +@group 2D Filter: RAS_2DFILTER_* @var RAS_2DFILTER_BLUR: @var RAS_2DFILTER_CUSTOMFILTER: @var RAS_2DFILTER_DILATION: @@ -302,11 +266,54 @@ KX_SCENE_RESUME: See L{KX_SceneActuator} @var RAS_2DFILTER_SEPIA: @var RAS_2DFILTER_SHARPEN: @var RAS_2DFILTER_SOBEL: -@var SHD_TANGENT: + +@group Constraint Actuator: KX_ACT_CONSTRAINT_* +@var KX_ACT_CONSTRAINT_DISTANCE: +@var KX_ACT_CONSTRAINT_DOROTFH: +@var KX_ACT_CONSTRAINT_FHNX: +@var KX_ACT_CONSTRAINT_FHNY: +@var KX_ACT_CONSTRAINT_FHNZ: +@var KX_ACT_CONSTRAINT_FHPX: +@var KX_ACT_CONSTRAINT_FHPY: +@var KX_ACT_CONSTRAINT_FHPZ: +@var KX_ACT_CONSTRAINT_LOCAL: +@var KX_ACT_CONSTRAINT_MATERIAL: +@var KX_ACT_CONSTRAINT_NORMAL: +@var KX_ACT_CONSTRAINT_PERMANENT: + +@group Parent Actuator: KX_PARENT_* +@var KX_PARENT_REMOVE: +@var KX_PARENT_SET: + +@group Shader: MODELMATRIX*, MODELVIEWMATRIX*, VIEWMATRIX*, CAM_POS, CONSTANT_TIMER @var VIEWMATRIX: @var VIEWMATRIX_INVERSE: @var VIEWMATRIX_INVERSETRANSPOSE: @var VIEWMATRIX_TRANSPOSE: +@var MODELMATRIX: +@var MODELMATRIX_INVERSE: +@var MODELMATRIX_INVERSETRANSPOSE: +@var MODELMATRIX_TRANSPOSE: +@var MODELVIEWMATRIX: +@var MODELVIEWMATRIX_INVERSE: +@var MODELVIEWMATRIX_INVERSETRANSPOSE: +@var MODELVIEWMATRIX_TRANSPOSE: +@var CAM_POS: Current camera position +@var CONSTANT_TIMER: Current camera position +@var SHD_TANGENT: Current camera position + +@group Blender Material: BL_* +@var BL_DST_ALPHA: +@var BL_DST_COLOR: +@var BL_ONE: +@var BL_ONE_MINUS_DST_ALPHA: +@var BL_ONE_MINUS_DST_COLOR: +@var BL_ONE_MINUS_SRC_ALPHA: +@var BL_ONE_MINUS_SRC_COLOR: +@var BL_SRC_ALPHA: +@var BL_SRC_ALPHA_SATURATE: +@var BL_SRC_COLOR: +@var BL_ZERO: @group Deprecated: addActiveActuator """ @@ -337,8 +344,9 @@ def getSceneList(): """ def addActiveActuator(actuator, activate): """ - Activates the given actuator. (B{deprecated}) + Activates the given actuator. + @deprecated: Use L{SCA_PythonController.activate} and L{SCA_PythonController.deactivate} instead. @type actuator: L{SCA_IActuator} or the actuator name as a string. @type activate: boolean @param activate: whether to activate or deactivate the given actuator. @@ -356,10 +364,6 @@ def sendMessage(subject, body="", to="", message_from=""): @param message_from: The name of the object that the message is coming from (optional) @type message_from: string """ -def getRandomFloat(): - """ - Returns a random floating point value in the range [0...1) - """ def setGravity(gravity): """ Sets the world gravity. @@ -429,6 +433,8 @@ def setPhysicsTicRate(ticrate): @param ticrate: The new update frequency (in Hz). @type ticrate: float """ + +#{ Utility functions def getAverageFrameRate(): """ Gets the estimated average framerate @@ -436,7 +442,6 @@ def getAverageFrameRate(): @return: The estimed average framerate in frames per second @rtype: float """ - def expandPath(path): """ Converts a blender internal path into a proper file system path. @@ -465,4 +470,9 @@ def getBlendFileList(path = "//"): def PrintGLInfo(): """ Prints GL Extension Info into the console - """ \ No newline at end of file + """ +def getRandomFloat(): + """ + Returns a random floating point value in the range [0...1) + """ +#} diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index e560489f91f..e6f5b90b5ce 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -44,9 +44,15 @@ class PyObjectPlus: class CValue(PyObjectPlus): """ - This class has no python functions + This class is a basis for other classes. """ - pass + def getName(): + """ + Returns the name of the CValue. + + @note: in most cases the CValue's subclasses will override this function. + @rtype: string + """ class CPropValue(CValue): """ @@ -60,9 +66,9 @@ class SCA_ILogicBrick(CValue): @ivar executePriority: This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first). @type executePriority: int - @ivar owner: The game object this logic brick is attached to (read only). + @ivar owner: The game object this logic brick is attached to (read-only). @type owner: L{KX_GameObject} or None in exceptional cases. - @ivar name: The name of this logic brick (read only). + @ivar name: The name of this logic brick (read-only). @type name: string @group Deprecated: getOwner, setExecutePriority, getExecutePriority """ @@ -72,7 +78,7 @@ class SCA_ILogicBrick(CValue): """ Gets the game object associated with this logic brick. - @deprecated: Use the L{owner} property instead. + @deprecated: Use the L{owner} attribute instead. @rtype: L{KX_GameObject} """ @@ -83,7 +89,7 @@ class SCA_ILogicBrick(CValue): This determines the order controllers are evaluated, and actuators are activated. Bricks with lower priority will be executed first. - @deprecated: Use the L{executePriority} property instead. + @deprecated: Use the L{executePriority} attribute instead. @type priority: integer @param priority: the priority of this logic brick. """ @@ -91,7 +97,7 @@ class SCA_ILogicBrick(CValue): """ Gets the execution priority of this logic brick. - @deprecated: Use the L{executePriority} property instead. + @deprecated: Use the L{executePriority} attribute instead. @rtype: integer @return: this logic bricks current priority. """ @@ -113,17 +119,23 @@ class SCA_ISensor(SCA_ILogicBrick): @type useNegPulseMode: boolean @ivar frequency: The frequency for pulse mode sensors. @type frequency: int - @ivar level: Flag to set whether to detect level or edge transition when entering a state. + @ivar level: Option whether to detect level or edge transition when entering a state. It makes a difference only in case of logic state transition (state actuator). A level detector will immediately generate a pulse, negative or positive depending on the sensor condition, as soon as the state is activated. A edge detector will wait for a state change before generating a pulse. + note: mutually exclusive with L{tap}, enabling will disable L{tap}. @type level: boolean + @ivar tap: When enabled only sensors that are just activated will send a positive event, + after this they will be detected as negative by the controllers. + This will make a key thats held act as if its only tapped for an instant. + note: mutually exclusive with L{level}, enabling will disable L{level}. + @type tap: boolean @ivar invert: Flag to set if this sensor activates on positive or negative events. @type invert: boolean - @ivar triggered: True if this sensor brick is in a positive state. (Read only) + @ivar triggered: True if this sensor brick is in a positive state. (read-only) @type triggered: boolean - @ivar positive: True if this sensor brick is in a positive state. (Read only) + @ivar positive: True if this sensor brick is in a positive state. (read-only) @type positive: boolean @group Deprecated: isPositive, isTriggered, getUsePosPulseMode, setUsePosPulseMode, getFrequency, setFrequency, getUseNegPulseMode, setUseNegPulseMode, getInvert, setInvert, getLevel, setLevel """ @@ -1453,7 +1465,13 @@ class KX_GameActuator(SCA_IActuator): @ivar file: the new .blend file to load @type file: string. @ivar mode: The mode of this actuator - @type mode: int from 0 to 5 L{GameLogic.Game Actuator} + @type mode: Constant in... + - L{GameLogic.KX_GAME_LOAD} + - L{GameLogic.KX_GAME_START} + - L{GameLogic.KX_GAME_RESTART} + - L{GameLogic.KX_GAME_QUIT} + - L{GameLogic.KX_GAME_SAVECFG} + - L{GameLogic.KX_GAME_LOADCFG} """ def getFile(): """ @@ -1478,7 +1496,7 @@ class KX_GameObject(SCA_IObject): Properties assigned to game objects are accessible as attributes of this class. - note: Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the L{invalid} attribute to check. - @ivar name: The object's name. (Read only) + @ivar name: The object's name. (read-only) - note: Currently (Blender 2.49) the prefix "OB" is added to all objects name. This may change in blender 2.5. @type name: string. @ivar mass: The object's mass @@ -1495,7 +1513,7 @@ class KX_GameObject(SCA_IObject): @type linVelocityMax: float @ivar localInertia: the object's inertia vector in local coordinates. Read only. @type localInertia: list [ix, iy, iz] - @ivar parent: The object's parent object. (Read only) + @ivar parent: The object's parent object. (read-only) @type parent: L{KX_GameObject} or None @ivar visible: visibility flag. - note: Game logic will still run for invisible objects. @@ -2409,9 +2427,9 @@ class KX_TouchSensor(SCA_ISensor): @type useMaterial: boolean @ivar pulseCollisions: The last collided object. @type pulseCollisions: bool - @ivar objectHit: The last collided object. (Read Only) + @ivar objectHit: The last collided object. (read-only) @type objectHit: L{KX_GameObject} or None - @ivar objectHitList: A list of colliding objects. (Read Only) + @ivar objectHitList: A list of colliding objects. (read-only) @type objectHitList: L{CListValue} of L{KX_GameObject} """ @@ -2486,21 +2504,21 @@ class KX_NetworkMessageActuator(SCA_IActuator): """ Messages will only be sent to objects with the given property name. - @deprecated: Use the L{propName} property instead. + @deprecated: Use the L{propName} attribute instead. @type name: string """ def setSubject(subject): """ Sets the subject field of the message. - @deprecated: Use the L{subject} property instead. + @deprecated: Use the L{subject} attribute instead. @type subject: string """ def setBodyType(bodytype): """ Sets the type of body to send. - @deprecated: Use the L{usePropBody} property instead. + @deprecated: Use the L{usePropBody} attribute instead. @type bodytype: boolean @param bodytype: True to send the value of a property, False to send the body text. """ @@ -2508,7 +2526,7 @@ class KX_NetworkMessageActuator(SCA_IActuator): """ Sets the message body. - deprecated: Use the L{body} property instead. + deprecated: Use the L{body} attribute instead. @type body: string @param body: if the body type is True, this is the name of the property to send. if the body type is False, this is the text to send. @@ -2536,7 +2554,7 @@ class KX_NetworkMessageSensor(SCA_ISensor): """ Change the message subject text that this sensor is listening to. - @deprecated: Use the L{subject} property instead. + @deprecated: Use the L{subject} attribute instead. @type subject: string @param subject: the new message subject to listen for. """ @@ -2545,28 +2563,28 @@ class KX_NetworkMessageSensor(SCA_ISensor): """ Get the number of messages received since the last frame. - @deprecated: Use the L{frameMessageCount} property instead. + @deprecated: Use the L{frameMessageCount} attribute instead. @rtype: integer """ def getBodies(): """ Gets the list of message bodies. - @deprecated: Use the L{bodies} property instead. + @deprecated: Use the L{bodies} attribute instead. @rtype: list """ def getSubject(): """ Gets the message subject this sensor is listening for from the Subject: field. - @deprecated: Use the L{subject} property instead. + @deprecated: Use the L{subject} attribute instead. @rtype: string """ def getSubjects(): """ Gets the list of message subjects received. - @deprecated: Use the L{subjects} property instead. + @deprecated: Use the L{subjects} attribute instead. @rtype: list """ @@ -2579,7 +2597,7 @@ class KX_ObjectActuator(SCA_IActuator): @ivar force: The force applied by the actuator @type force: list [x, y, z] @ivar useLocalForce: A flag specifying if the force is local - @type force: bool + @type useLocalForce: bool @ivar torque: The torque applied by the actuator @type torque: list [x, y, z] @ivar useLocalTorque: A flag specifying if the torque is local @@ -3186,16 +3204,16 @@ class KX_PolygonMaterial: print mat.texture @ivar texture: Texture name - @type texture: string (read only) + @type texture: string (read-only) @ivar gl_texture: OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture) - @type gl_texture: integer (read only) + @type gl_texture: integer (read-only) @ivar material: Material name - @type material: string (read only) + @type material: string (read-only) @ivar tface: Texture face properties - @type tface: CObject (read only) + @type tface: CObject (read-only) @ivar tile: Texture is tiling @type tile: boolean @@ -3330,10 +3348,10 @@ class KX_RadarSensor(KX_NearSensor): @ivar coneOrigin: The origin of the cone with which to test. The origin is in the middle of the cone. - (Read only) + (read-only) @type coneOrigin: list of floats [x, y, z] @ivar coneTarget: The center of the bottom face of the cone with which to test. - (Read only) + (read-only) @type coneTarget: list of floats [x, y, z] @ivar distance: The height of the cone with which to test. @type distance: float @@ -3401,28 +3419,28 @@ class KX_RaySensor(SCA_ISensor): """ Returns the game object that was hit by this ray. - @deprecated: Use the L{hitObject} property instead. + @deprecated: Use the L{hitObject} attribute instead. @rtype: KX_GameObject """ def getHitPosition(): """ Returns the position (in worldcoordinates) where the object was hit by this ray. - @deprecated: Use the L{hitPosition} property instead. + @deprecated: Use the L{hitPosition} attribute instead. @rtype: list [x, y, z] """ def getHitNormal(): """ Returns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray. - @deprecated: Use the L{hitNormal} property instead. + @deprecated: Use the L{hitNormal} attribute instead. @rtype: list [nx, ny, nz] """ def getRayDirection(): """ Returns the direction from the ray (in worldcoordinates) - @deprecated: Use the L{rayDirection} property instead. + @deprecated: Use the L{rayDirection} attribute instead. @rtype: list [dx, dy, dz] """ @@ -3431,7 +3449,7 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): Edit Object Actuator (in Add Object Mode) @ivar object: the object this actuator adds. @type object: KX_GameObject or None - @ivar objectLastCreated: the last added object from this actuator (read only). + @ivar objectLastCreated: the last added object from this actuator (read-only). @type objectLastCreated: KX_GameObject or None @ivar time: the lifetime of added objects, in frames. @type time: integer @@ -3560,12 +3578,12 @@ class KX_SCA_DynamicActuator(SCA_IActuator): - 3 = disable rigid body - 4 = set mass - @deprecated: Use the L{operation} property instead. + @deprecated: Use the L{operation} attribute instead. """ def getOperation(): """ return the type of operation - @deprecated: Use the L{operation} property instead. + @deprecated: Use the L{operation} attribute instead. """ class KX_SCA_EndObjectActuator(SCA_IActuator): @@ -3638,7 +3656,7 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): Sets the name of the mesh that will replace the current one. When the name is None it will unset the mesh value so no action is taken. - @deprecated: Use the L{mesh} property instead. + @deprecated: Use the L{mesh} attribute instead. @type name: string or None """ def getMesh(): @@ -3647,7 +3665,7 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): Returns None if no mesh has been scheduled to be added. - @deprecated: Use the L{mesh} property instead. + @deprecated: Use the L{mesh} attribute instead. @rtype: string or None """ def instantReplaceMesh(): @@ -3703,7 +3721,7 @@ class KX_Scene(PyObjectPlus): @ivar cameras: A list of cameras in the scene, (read-only). @type cameras: L{CListValue} of L{KX_Camera} @ivar active_camera: The current active camera. - @note: this can be set directly from python to avoid using the L{KX_SceneActuator} + note: this can be set directly from python to avoid using the L{KX_SceneActuator}. @type active_camera: L{KX_Camera} @ivar suspended: True if the scene is suspended, (read-only). @type suspended: boolean @@ -3711,6 +3729,8 @@ class KX_Scene(PyObjectPlus): @type activity_culling: boolean @ivar activity_culling_radius: The distance outside which to do activity culling. Measured in manhattan distance. @type activity_culling_radius: float + @ivar dbvt_culling: True when Dynamic Bounding box Volume Tree is set (read-only). + @type dbvt_culling: bool @group Deprecated: getLightList, getObjectList, getName """ @@ -3718,21 +3738,21 @@ class KX_Scene(PyObjectPlus): """ Returns the list of lights in the scene. - @deprecated: Use the L{lights} property instead. + @deprecated: Use the L{lights} attribute instead. @rtype: list [L{KX_LightObject}] """ def getObjectList(): """ Returns the list of objects in the scene. - @deprecated: Use the L{objects} property instead. + @deprecated: Use the L{objects} attribute instead. @rtype: list [L{KX_GameObject}] """ def getName(): """ Returns the name of the scene. - @deprecated: Use the L{name} property instead. + @deprecated: Use the L{name} attribute instead. @rtype: string """ @@ -3775,14 +3795,14 @@ class KX_SceneActuator(SCA_IActuator): """ Set flag to True to restart the scene. - @deprecated: Use the L{useRestart} property instead. + @deprecated: Use the L{useRestart} attribute instead. @type flag: boolean """ def setScene(scene): """ Sets the name of the scene to change to/overlay/underlay/remove/suspend/resume. - @deprecated: use the L{scene} property instead. + @deprecated: use the L{scene} attribute instead. @type scene: string """ def setCamera(camera): @@ -3791,14 +3811,14 @@ class KX_SceneActuator(SCA_IActuator): Camera can be either a L{KX_Camera} or the name of the camera. - @deprecated: use the L{camera} property instead. + @deprecated: use the L{camera} attribute instead. @type camera: L{KX_Camera} or string """ def getUseRestart(): """ Returns True if the scene will be restarted. - @deprecated: use the L{useRestart} property instead. + @deprecated: use the L{useRestart} attribute instead. @rtype: boolean """ def getScene(): @@ -3807,14 +3827,14 @@ class KX_SceneActuator(SCA_IActuator): Returns an empty string ("") if no scene has been set. - @deprecated: use the L{scene} property instead. + @deprecated: use the L{scene} attribute instead. @rtype: string """ def getCamera(): """ Returns the name of the camera to change to. - @deprecated: use the L{camera} property instead. + @deprecated: use the L{camera} attribute instead. @rtype: string """ @@ -3866,14 +3886,14 @@ class KX_SoundActuator(SCA_IActuator): """ Sets the filename of the sound this actuator plays. - @deprecated: Use the L{filename} property instead. + @deprecated: Use the L{filename} attribute instead. @type filename: string """ def getFilename(): """ Returns the filename of the sound this actuator plays. - @deprecated: Use the L{filename} property instead. + @deprecated: Use the L{filename} attribute instead. @rtype: string """ def startSound(): @@ -3892,7 +3912,7 @@ class KX_SoundActuator(SCA_IActuator): """ Sets the gain (volume) of the sound - @deprecated: Use the L{volume} property instead. + @deprecated: Use the L{volume} attribute instead. @type gain: float @param gain: 0.0 (quiet) <= gain <= 1.0 (loud) """ @@ -3900,21 +3920,21 @@ class KX_SoundActuator(SCA_IActuator): """ Gets the gain (volume) of the sound. - @deprecated: Use the L{volume} property instead. + @deprecated: Use the L{volume} attribute instead. @rtype: float """ def setPitch(pitch): """ Sets the pitch of the sound. - @deprecated: Use the L{pitch} property instead. + @deprecated: Use the L{pitch} attribute instead. @type pitch: float """ def getPitch(): """ Returns the pitch of the sound. - @deprecated: Use the L{pitch} property instead. + @deprecated: Use the L{pitch} attribute instead. @rtype: float """ def setRollOffFactor(rolloff): @@ -3924,14 +3944,14 @@ class KX_SoundActuator(SCA_IActuator): Rolloff defines the rate of attenuation as the sound gets further away. Higher rolloff factors shorten the distance at which the sound can be heard. - @deprecated: Use the L{rollOffFactor} property instead. + @deprecated: Use the L{rollOffFactor} attribute instead. @type rolloff: float """ def getRollOffFactor(): """ Returns the rolloff factor for the sound. - @deprecated: Use the L{rollOffFactor} property instead. + @deprecated: Use the L{rollOffFactor} attribute instead. @rtype: float """ def setLooping(loop): @@ -3946,21 +3966,21 @@ class KX_SoundActuator(SCA_IActuator): - Bidirection Stop 5 - Bidirection End 6 - @deprecated: Use the L{looping} property instead. + @deprecated: Use the L{looping} attribute instead. @type loop: integer """ def getLooping(): """ Returns the current loop mode of the actuator. - @deprecated: Use the L{looping} property instead. + @deprecated: Use the L{looping} attribute instead. @rtype: integer """ def setPosition(x, y, z): """ Sets the position this sound will come from. - @deprecated: Use the L{position} property instead. + @deprecated: Use the L{position} attribute instead. @type x: float @param x: The x coordinate of the sound. @type y: float @@ -3974,7 +3994,7 @@ class KX_SoundActuator(SCA_IActuator): The sound's pitch is determined from the velocity. - @deprecated: Use the L{velocity} property instead. + @deprecated: Use the L{velocity} attribute instead. @type vx: float @param vx: The vx coordinate of the sound. @type vy: float @@ -3990,14 +4010,14 @@ class KX_SoundActuator(SCA_IActuator): | o11, o12, o13 | | o21, o22, o23 | | o31, o32, o33 | - @deprecated: Use the L{orientation} property instead. + @deprecated: Use the L{orientation} attribute instead. """ def setType(mode): """ Sets the operation mode of the actuator. - @deprecated: Use the L{type} property instead. + @deprecated: Use the L{type} attribute instead. @param mode: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP @type mode: integer """ @@ -4006,7 +4026,7 @@ class KX_SoundActuator(SCA_IActuator): """ Returns the operation mode of the actuator. - @deprecated: Use the L{type} property instead. + @deprecated: Use the L{type} attribute instead. @rtype: integer @return: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP """ @@ -4036,7 +4056,7 @@ class KX_StateActuator(SCA_IActuator): Set the type of bit operation to be applied on object state mask. Use setMask() to specify the bits that will be modified. - @deprecated: Use the L{operation} property instead. + @deprecated: Use the L{operation} attribute instead. @param op: bit operation (0=Copy, 1=Add, 2=Substract, 3=Invert) @type op: integer """ @@ -4047,7 +4067,7 @@ class KX_StateActuator(SCA_IActuator): the bits that are 0 are will be left unmodified expect for the Copy operation which copies the value to the object state. - @deprecated: Use the L{mask} property instead. + @deprecated: Use the L{mask} attribute instead. @param mask: bits that will be modified @type mask: integer """ @@ -4075,7 +4095,7 @@ class KX_TrackToActuator(SCA_IActuator): """ Sets the object to track. - @deprecated: Use the L{object} property instead. + @deprecated: Use the L{object} attribute instead. @type object: L{KX_GameObject}, string or None @param object: Either a reference to a game object or the name of the object to track. """ @@ -4083,7 +4103,7 @@ class KX_TrackToActuator(SCA_IActuator): """ Returns the name of the object to track. - @deprecated: Use the L{object} property instead. + @deprecated: Use the L{object} attribute instead. @type name_only: bool @param name_only: optional argument, when 0 return a KX_GameObject @rtype: string, KX_GameObject or None if no object is set @@ -4092,14 +4112,14 @@ class KX_TrackToActuator(SCA_IActuator): """ Sets the time in frames with which to delay the tracking motion. - @deprecated: Use the L{time} property instead. + @deprecated: Use the L{time} attribute instead. @type time: integer """ def getTime(): """ Returns the time in frames with which the tracking motion is delayed. - @deprecated: Use the L{time} property instead. + @deprecated: Use the L{time} attribute instead. @rtype: integer """ def setUse3D(use3d): @@ -4107,7 +4127,7 @@ class KX_TrackToActuator(SCA_IActuator): DEPRECATED: Use the property. Sets the tracking motion to use 3D. - @deprecated: Use the L{use3D} property instead. + @deprecated: Use the L{use3D} attribute instead. @type use3d: boolean @param use3d: - True: allow the tracking motion to extend in the z-direction. - False: lock the tracking motion to the x-y plane. @@ -4116,7 +4136,7 @@ class KX_TrackToActuator(SCA_IActuator): """ Returns True if the tracking motion will track in the z direction. - @deprecated: Use the L{use3D} property instead. + @deprecated: Use the L{use3D} attribute instead. @rtype: boolean """ @@ -4440,7 +4460,7 @@ class KX_VisibilityActuator(SCA_IActuator): """ Sets whether the actuator makes its parent object visible or invisible. - @deprecated: Use the L{visibility} property instead. + @deprecated: Use the L{visibility} attribute instead. @param visible: - True: Makes its parent visible. - False: Makes its parent invisible. """ @@ -4509,7 +4529,7 @@ class SCA_ActuatorSensor(SCA_ISensor): """ Return the Actuator with which the sensor operates. - @deprecated: Use the L{actuator} property instead. + @deprecated: Use the L{actuator} attribute instead. @rtype: string """ def setActuator(name): @@ -4517,7 +4537,7 @@ class SCA_ActuatorSensor(SCA_ISensor): Sets the Actuator with which to operate. If there is no Actuator of this name, the function has no effect. - @deprecated: Use the L{actuator} property instead. + @deprecated: Use the L{actuator} attribute instead. @param name: actuator name @type name: string """ @@ -4553,7 +4573,7 @@ class SCA_DelaySensor(SCA_ISensor): """ Set the initial delay before the positive trigger. - @deprecated: Use the L{delay} property instead. + @deprecated: Use the L{delay} attribute instead. @param delay: length of the initial OFF period as number of frame, 0 for immediate trigger @type delay: integer """ @@ -4562,7 +4582,7 @@ class SCA_DelaySensor(SCA_ISensor): Set the duration of the ON pulse after initial delay and the generation of the positive trigger. If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. - @deprecated: Use the L{duration} property instead. + @deprecated: Use the L{duration} attribute instead. @param duration: length of the ON period in number of frame after the initial OFF period @type duration: integer """ @@ -4570,7 +4590,7 @@ class SCA_DelaySensor(SCA_ISensor): """ Set if the sensor repeat mode. - @deprecated: Use the L{repeat} property instead. + @deprecated: Use the L{repeat} attribute instead. @param repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. @type repeat: integer """ @@ -4578,21 +4598,21 @@ class SCA_DelaySensor(SCA_ISensor): """ Return the delay parameter value. - @deprecated: Use the L{delay} property instead. + @deprecated: Use the L{delay} attribute instead. @rtype: integer """ def getDuration(): """ Return the duration parameter value - @deprecated: Use the L{duration} property instead. + @deprecated: Use the L{duration} attribute instead. @rtype: integer """ def getRepeat(): """ Return the repeat parameter value - @deprecated: Use the L{repeat} property instead. + @deprecated: Use the L{repeat} attribute instead. @rtype: KX_TRUE or KX_FALSE """ @@ -4652,14 +4672,14 @@ class SCA_JoystickSensor(SCA_ISensor): """ Returns the joystick index to use (from 1 to 8). - @deprecated: Use the L{index} property instead. + @deprecated: Use the L{index} attribute instead. @rtype: integer """ def setIndex(index): """ Sets the joystick index to use. - @deprecated: Use the L{index} property instead. + @deprecated: Use the L{index} attribute instead. @param index: The index of this joystick sensor, Clamped between 1 and 8. @type index: integer @note: This is only useful when you have more then 1 joystick connected to your computer - multiplayer games. @@ -4668,14 +4688,14 @@ class SCA_JoystickSensor(SCA_ISensor): """ Returns the current axis this sensor reacts to. See L{getAxisValue()} for the current axis state. - @deprecated: Use the L{axis} property instead. + @deprecated: Use the L{axis} attribute instead. @rtype: list @return: 2 values returned are [axisIndex, axisDirection] - see L{setAxis()} for their purpose. @note: When the "All Events" toggle is set, this option has no effect. """ def setAxis(axisIndex, axisDirection): """ - @deprecated: Use the L{axis} property instead. + @deprecated: Use the L{axis} attribute instead. @param axisIndex: Set the axis index to use when detecting axis movement. @type axisIndex: integer from 1 to 2 @param axisDirection: Set the axis direction used for detecting motion. 0:right, 1:up, 2:left, 3:down. @@ -4686,7 +4706,7 @@ class SCA_JoystickSensor(SCA_ISensor): """ Returns the state of the joysticks axis. See differs to L{getAxis()} returning the current state of the joystick. - @deprecated: Use the L{axisPosition} property instead. + @deprecated: Use the L{axisPosition} attribute instead. @rtype: list @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. @@ -4699,14 +4719,14 @@ class SCA_JoystickSensor(SCA_ISensor): """ Get the axis threshold. See L{setThreshold()} for details. - @deprecated: Use the L{threshold} property instead. + @deprecated: Use the L{threshold} attribute instead. @rtype: integer """ def setThreshold(threshold): """ Set the axis threshold. - @deprecated: Use the L{threshold} property instead. + @deprecated: Use the L{threshold} attribute instead. @param threshold: Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. @type threshold: integer """ @@ -4714,7 +4734,7 @@ class SCA_JoystickSensor(SCA_ISensor): """ Returns the button index the sensor reacts to. See L{getButtonValue()} for a list of pressed buttons. - @deprecated: Use the L{button} property instead. + @deprecated: Use the L{button} attribute instead. @rtype: integer @note: When the "All Events" toggle is set, this option has no effect. """ @@ -4722,7 +4742,7 @@ class SCA_JoystickSensor(SCA_ISensor): """ Sets the button index the sensor reacts to when the "All Events" option is not set. - @deprecated: Use the L{button} property instead. + @deprecated: Use the L{button} attribute instead. @note: When the "All Events" toggle is set, this option has no effect. """ def getButtonValue(): @@ -4737,7 +4757,7 @@ class SCA_JoystickSensor(SCA_ISensor): Returns the current hat direction this sensor is set to. [hatNumber, hatDirection]. - @deprecated: Use the L{hat} property instead. + @deprecated: Use the L{hat} attribute instead. @rtype: list @note: When the "All Events" toggle is set, this option has no effect. """ @@ -4745,35 +4765,35 @@ class SCA_JoystickSensor(SCA_ISensor): """ Sets the hat index the sensor reacts to when the "All Events" option is not set. - @deprecated: Use the L{hat} property instead. + @deprecated: Use the L{hat} attribute instead. @type index: integer """ def getNumAxes(): """ Returns the number of axes for the joystick at this index. - @deprecated: Use the L{numAxis} property instead. + @deprecated: Use the L{numAxis} attribute instead. @rtype: integer """ def getNumButtons(): """ Returns the number of buttons for the joystick at this index. - @deprecated: Use the L{numButtons} property instead. + @deprecated: Use the L{numButtons} attribute instead. @rtype: integer """ def getNumHats(): """ Returns the number of hats for the joystick at this index. - @deprecated: Use the L{numHats} property instead. + @deprecated: Use the L{numHats} attribute instead. @rtype: integer """ def isConnected(): """ Returns True if a joystick is detected at this joysticks index. - @deprecated: Use the L{connected} property instead. + @deprecated: Use the L{connected} attribute instead. @rtype: bool """ @@ -4795,7 +4815,7 @@ class SCA_KeyboardSensor(SCA_ISensor): @type targetProperty: string @ivar useAllKeys: Flag to determine whether or not to accept all keys. @type useAllKeys: boolean - @ivar events: a list of pressed keys that have either been pressed, or just released, or are active this frame. (read only). + @ivar events: a list of pressed keys that have either been pressed, or just released, or are active this frame. (read-only). - 'keycode' matches the values in L{GameKeys}. - 'status' uses... @@ -4822,7 +4842,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Returns the key code this sensor is looking for. - @deprecated: Use the L{key} property instead. + @deprecated: Use the L{key} attribute instead. @rtype: keycode from L{GameKeys} module """ @@ -4830,7 +4850,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Set the key this sensor should listen for. - @deprecated: Use the L{key} property instead. + @deprecated: Use the L{key} attribute instead. @type keycode: keycode from L{GameKeys} module """ @@ -4838,7 +4858,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Returns the key code for the first modifier this sensor is looking for. - @deprecated: Use the L{hold1} property instead. + @deprecated: Use the L{hold1} attribute instead. @rtype: keycode from L{GameKeys} module """ @@ -4846,7 +4866,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Sets the key code for the first modifier this sensor should look for. - @deprecated: Use the L{hold1} property instead. + @deprecated: Use the L{hold1} attribute instead. @type keycode: keycode from L{GameKeys} module """ @@ -4854,7 +4874,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Returns the key code for the second modifier this sensor is looking for. - @deprecated: Use the L{hold2} property instead. + @deprecated: Use the L{hold2} attribute instead. @rtype: keycode from L{GameKeys} module """ @@ -4862,7 +4882,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Sets the key code for the second modifier this sensor should look for. - @deprecated: Use the L{hold2} property instead. + @deprecated: Use the L{hold2} attribute instead. @type keycode: keycode from L{GameKeys} module """ @@ -4870,7 +4890,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Get a list of keys that have either been pressed, or just released this frame. - @deprecated: Use the L{events} property instead. + @deprecated: Use the L{events} attribute instead. @rtype: list of key status. [[keycode, status]] """ @@ -4878,7 +4898,7 @@ class SCA_KeyboardSensor(SCA_ISensor): """ Get a list of currently pressed keys that have either been pressed, or just released - @deprecated: Use the L{events} property instead. + @deprecated: Use the L{events} attribute instead. @rtype: list of key status. [[keycode, status]] """ @@ -4913,6 +4933,8 @@ class SCA_PropertyActuator(SCA_IActuator): @type property: string @ivar value: the value with which the actuator operates. @type value: string + @ivar type: TODO - add constants to game logic dict!. + @type type: iny """ def setProperty(prop): """ @@ -4920,7 +4942,7 @@ class SCA_PropertyActuator(SCA_IActuator): If there is no property of this name, the call is ignored. - @deprecated: Use the L{property} property instead. + @deprecated: Use the L{property} attribute instead. @type prop: string @param prop: The name of the property to set. """ @@ -4928,7 +4950,7 @@ class SCA_PropertyActuator(SCA_IActuator): """ Returns the name of the property on which to operate. - @deprecated: Use the L{property} property instead. + @deprecated: Use the L{property} attribute instead. @rtype: string """ def setValue(value): @@ -4938,14 +4960,14 @@ class SCA_PropertyActuator(SCA_IActuator): If the value is not compatible with the type of the property, the subsequent action is ignored. - @deprecated: Use the L{value} property instead. + @deprecated: Use the L{value} attribute instead. @type value: string """ def getValue(): """ Gets the value with which this actuator operates. - @deprecated: Use the L{value} property instead. + @deprecated: Use the L{value} attribute instead. @rtype: string """ @@ -4969,7 +4991,7 @@ class SCA_PropertySensor(SCA_ISensor): """ Gets when to activate this sensor. - @deprecated: Use the L{type} property instead. + @deprecated: Use the L{type} attribute instead. @return: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, or KX_PROPSENSOR_EXPRESSION. @@ -4979,7 +5001,7 @@ class SCA_PropertySensor(SCA_ISensor): """ Set the type of check to perform. - @deprecated: Use the L{type} property instead. + @deprecated: Use the L{type} attribute instead. @type checktype: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, or KX_PROPSENSOR_EXPRESSION. @@ -4989,7 +5011,7 @@ class SCA_PropertySensor(SCA_ISensor): """ Return the property with which the sensor operates. - @deprecated: Use the L{property} property instead. + @deprecated: Use the L{property} attribute instead. @rtype: string @return: the name of the property this sensor is watching. """ @@ -4998,14 +5020,14 @@ class SCA_PropertySensor(SCA_ISensor): Sets the property with which to operate. If there is no property of that name, this call is ignored. - @deprecated: Use the L{property} property instead. + @deprecated: Use the L{property} attribute instead. @type name: string. """ def getValue(): """ Return the value with which the sensor compares to the value of the property. - @deprecated: Use the L{value} property instead. + @deprecated: Use the L{value} attribute instead. @rtype: string @return: the value of the property this sensor is watching. """ @@ -5015,7 +5037,7 @@ class SCA_PropertySensor(SCA_ISensor): is not compatible with the type of the property, the subsequent action is ignored. - @deprecated: Use the L{value} property instead. + @deprecated: Use the L{value} attribute instead. @type value: string """ @@ -5045,14 +5067,14 @@ class SCA_PythonController(SCA_IController): """ Gets the Python script this controller executes. - @deprecated: Use the L{script} property instead. + @deprecated: Use the L{script} attribute instead. @rtype: string """ def setScript(script): """ Sets the Python script this controller executes. - @deprecated: Use the L{script} property instead. + @deprecated: Use the L{script} attribute instead. @type script: string. """ @@ -5092,14 +5114,14 @@ class SCA_RandomActuator(SCA_IActuator): Equal seeds produce equal series. If the seed is 0, the generator will produce the same value on every call. - @deprecated: Use the L{seed} property instead. + @deprecated: Use the L{seed} attribute instead. @type seed: integer """ def getSeed(): """ Returns the initial seed of the generator. - @deprecated: Use the L{seed} property instead. + @deprecated: Use the L{seed} attribute instead. @rtype: integer """ def getPara1(): @@ -5109,7 +5131,7 @@ class SCA_RandomActuator(SCA_IActuator): Refer to the documentation of the generator types for the meaning of this value. - @deprecated: Use the L{para1} property instead. + @deprecated: Use the L{para1} attribute instead. @rtype: float """ def getPara2(): @@ -5119,14 +5141,14 @@ class SCA_RandomActuator(SCA_IActuator): Refer to the documentation of the generator types for the meaning of this value. - @deprecated: Use the L{para2} property instead. + @deprecated: Use the L{para2} attribute instead. @rtype: float """ def getDistribution(): """ Returns the type of random distribution. - @deprecated: Use the L{distribution} property instead. + @deprecated: Use the L{distribution} attribute instead. @rtype: distribution type @return: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, @@ -5139,7 +5161,7 @@ class SCA_RandomActuator(SCA_IActuator): If the generator and property types do not match, the assignment is ignored. - @deprecated: Use the L{property} property instead. + @deprecated: Use the L{property} attribute instead. @type property: string @param property: The name of the property to set. """ @@ -5147,7 +5169,7 @@ class SCA_RandomActuator(SCA_IActuator): """ Returns the name of the property to set. - @deprecated: Use the L{property} property instead. + @deprecated: Use the L{property} attribute instead. @rtype: string """ def setBoolConst(value): @@ -5289,37 +5311,33 @@ class KX_Camera(KX_GameObject): @type near: float @ivar far: The camera's far clip distance. @type far: float - @ivar perspective: True if this camera has a perspective transform. - - If perspective is False, this camera has an orthographic transform. - - Note that the orthographic transform is faked by multiplying the lens attribute - by 100.0 and translating the camera 100.0 along the z axis. - - This is the same as Blender. If you want a true orthographic transform, see L{setProjectionMatrix}. + @ivar perspective: True if this camera has a perspective transform, False for an orthographic projection. @type perspective: boolean @ivar frustum_culling: True if this camera is frustum culling. @type frustum_culling: boolean @ivar projection_matrix: This camera's 4x4 projection matrix. @type projection_matrix: 4x4 Matrix [[float]] - @ivar modelview_matrix: This camera's 4x4 model view matrix. (read only) + @ivar modelview_matrix: This camera's 4x4 model view matrix. (read-only) Regenerated every frame from the camera's position and orientation. @type modelview_matrix: 4x4 Matrix [[float]] - @ivar camera_to_world: This camera's camera to world transform. (read only) + @ivar camera_to_world: This camera's camera to world transform. (read-only) Regenerated every frame from the camera's position and orientation. @type camera_to_world: 4x4 Matrix [[float]] - @ivar world_to_camera: This camera's world to camera transform. (read only) + @ivar world_to_camera: This camera's world to camera transform. (read-only) Regenerated every frame from the camera's position and orientation. This is camera_to_world inverted. @type world_to_camera: 4x4 Matrix [[float]] + @ivar useViewport: True when the camera is used as a viewport, set True to enable a viewport for this camera. + @type useViewport: bool - @group Deprecated: enableViewport + @group Deprecated: enableViewport, getProjectionMatrix, setProjectionMatrix """ def sphereInsideFrustum(centre, radius): """ Tests the given sphere against the view frustum. + @note: when the camera is first initialized the result will be invalid because the projection matrix has not been set. @param centre: The centre of the sphere (in world coordinates.) @type centre: list [x, y, z] @param radius: the radius of the sphere @@ -5364,6 +5382,7 @@ class KX_Camera(KX_GameObject): else: # Box is outside the frustum ! + @note: when the camera is first initialized the result will be invalid because the projection matrix has not been set. @return: INSIDE, OUTSIDE or INTERSECT @type box: list @param box: Eight (8) corner points of the box (in world coordinates.) @@ -5384,6 +5403,7 @@ class KX_Camera(KX_GameObject): else: # Box is outside the frustum ! + @note: when the camera is first initialized the result will be invalid because the projection matrix has not been set. @rtype: boolean @return: True if the given point is inside this camera's viewing frustum. @type point: [x, y, z] @@ -5409,6 +5429,7 @@ class KX_Camera(KX_GameObject): """ Returns the camera's projection matrix. + @deprecated: Use the L{projection_matrix} attribute instead. @rtype: matrix (4x4 list) @return: the camera's projection matrix. """ @@ -5455,6 +5476,7 @@ class KX_Camera(KX_GameObject): cam = co.owner cam.setProjectionMatrix(Perspective(cam))) + @deprecated: Use the L{projection_matrix} attribute instead. @type matrix: 4x4 matrix. @param matrix: The new projection matrix for this camera. """ @@ -5463,7 +5485,7 @@ class KX_Camera(KX_GameObject): """ Use this camera to draw a viewport on the screen (for split screen games or overlay scenes). The viewport region is defined with L{setViewport}. - @deprecated: Use the L{isViewport} property instead. + @deprecated: Use the L{useViewport} attribute instead. @type viewport: bool @param viewport: the new viewport status """ From e8c0440660be3523f5d6dda300158225d93145f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 May 2009 02:03:27 +0000 Subject: [PATCH 243/444] minor change - mistake in joystick fix, util function for getting attrs from BGE types --- .../GameLogic/Joystick/SCA_Joystick.cpp | 2 +- source/gameengine/PyDoc/GameTypes.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index c32ff303aea..b19424f20e9 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -249,7 +249,7 @@ bool SCA_Joystick::CreateJoystickDevice(void) else if (m_axismax < 0) m_axismax = 0; if(m_buttonmax<0) m_buttonmax= 0; - if(m_hatmax<0) m_buttonmax= 0; + if(m_hatmax<0) m_hatmax= 0; } return true; #endif diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index e6f5b90b5ce..0240efa4eab 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -5504,3 +5504,19 @@ class KX_Camera(KX_GameObject): @type right: int @type top: int """ + +# Util func to extract all attrs +""" +import types +attrs = [] +for name, val in __builtins__.locals().items(): + if name.startswith('__'): + continue + if type(val) == types.ClassType: + for line in val.__doc__.split('\n'): + if '@ivar' in line: + attrs.append(name + '::' + line.split()[1].replace(':', '')) + +for a in attrs: + print a +""" \ No newline at end of file From b8657fd64895f9fcf7d5308b298e516c02faf110 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 May 2009 03:26:53 +0000 Subject: [PATCH 244/444] Name attributes added since 2.48a more consistently. BL_ActionActuator::blendin -> blendIn BL_ActionActuator::end -> frameEnd BL_ActionActuator::property -> propName BL_ActionActuator::start -> frameStart BL_ActionActuator::type -> mode BL_ShapeActionActuator::blendin -> blendIn BL_ShapeActionActuator::end -> frameEnd BL_ShapeActionActuator::frameProperty -> framePropName BL_ShapeActionActuator::property -> propName BL_ShapeActionActuator::start -> frameStart BL_ShapeActionActuator::type -> mode KX_CameraActuator::xy -> useXY KX_ConstraintActuator::property -> propName KX_GameActuator::file -> fileName KX_GameObject::localScaling -> localScaling KX_GameObject::worldScaling -> worldScaling KX_IpoActuator::endFrame -> frameEnd KX_IpoActuator::startFrame -> frameStart KX_IpoActuator::type -> mode KX_RaySensor::property -> propName KX_SCA_DynamicActuator::operation -> mode KX_Scene::objects_inactive -> objectsInactive KX_SoundActuator::filename -> fileName KX_SoundActuator::type -> mode KX_TouchSensor::objectHit -> hitObject KX_TouchSensor::objectHitList -> hitObjectList KX_TouchSensor::property -> propName KX_TouchSensor::pulseCollisions -> usePulseCollision KX_VisibilityActuator::occlusion -> useOcclusion KX_VisibilityActuator::recursion -> useRecursion SCA_2DFilterActuator::passNb -> passNumber SCA_PropertyActuator::property -> propName SCA_PropertyActuator::type -> mode SCA_PropertySensor::property -> propName SCA_PropertySensor::type -> mode SCA_RandomActuator::property -> propName --- .../Converter/BL_ActionActuator.cpp | 12 +- .../Converter/BL_ShapeActionActuator.cpp | 12 +- .../GameLogic/SCA_2DFilterActuator.cpp | 4 +- .../GameLogic/SCA_PropertyActuator.cpp | 8 +- .../GameLogic/SCA_PropertySensor.cpp | 12 +- .../GameLogic/SCA_RandomActuator.cpp | 6 +- .../gameengine/Ketsji/KX_CameraActuator.cpp | 4 +- .../Ketsji/KX_ConstraintActuator.cpp | 2 +- source/gameengine/Ketsji/KX_GameActuator.cpp | 6 +- source/gameengine/Ketsji/KX_GameObject.cpp | 4 +- source/gameengine/Ketsji/KX_IpoActuator.cpp | 23 +- source/gameengine/Ketsji/KX_RaySensor.cpp | 2 +- .../Ketsji/KX_SCA_DynamicActuator.cpp | 6 +- source/gameengine/Ketsji/KX_Scene.cpp | 2 +- source/gameengine/Ketsji/KX_SoundActuator.cpp | 16 +- source/gameengine/Ketsji/KX_TouchSensor.cpp | 16 +- .../Ketsji/KX_VisibilityActuator.cpp | 4 +- source/gameengine/PyDoc/GameLogic.py | 4 +- source/gameengine/PyDoc/GameTypes.py | 457 ++++++++++-------- .../gameengine/PyDoc/bge_api_validate_py.txt | 7 +- 20 files changed, 324 insertions(+), 283 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 145cb1f22de..d0a4a87af72 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -997,17 +997,17 @@ PyMethodDef BL_ActionActuator::Methods[] = { }; PyAttributeDef BL_ActionActuator::Attributes[] = { - KX_PYATTRIBUTE_FLOAT_RW("start", 0, MAXFRAMEF, BL_ActionActuator, m_startframe), - KX_PYATTRIBUTE_FLOAT_RW("end", 0, MAXFRAMEF, BL_ActionActuator, m_endframe), - KX_PYATTRIBUTE_FLOAT_RW("blendin", 0, MAXFRAMEF, BL_ActionActuator, m_blendin), + KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, MAXFRAMEF, BL_ActionActuator, m_startframe), + KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, MAXFRAMEF, BL_ActionActuator, m_endframe), + KX_PYATTRIBUTE_FLOAT_RW("blendIn", 0, MAXFRAMEF, BL_ActionActuator, m_blendin), KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ActionActuator, pyattr_get_action, pyattr_set_action), KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ActionActuator, m_priority), KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ActionActuator, m_localtime, CheckFrame), - KX_PYATTRIBUTE_STRING_RW("property", 0, 31, false, BL_ActionActuator, m_propname), - KX_PYATTRIBUTE_STRING_RW("frameProperty", 0, 31, false, BL_ActionActuator, m_framepropname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ActionActuator, m_propname), + KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ActionActuator, m_framepropname), KX_PYATTRIBUTE_BOOL_RW("useContinue", BL_ActionActuator, m_end_reset), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ActionActuator, m_blendframe, CheckBlendTime), - KX_PYATTRIBUTE_SHORT_RW_CHECK("type",0,100,false,BL_ActionActuator,m_playtype,CheckType), + KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ActionActuator,m_playtype,CheckType), { NULL } //Sentinel }; diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 29bbe9b3d7d..a24d83da90c 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -467,16 +467,16 @@ PyMethodDef BL_ShapeActionActuator::Methods[] = { }; PyAttributeDef BL_ShapeActionActuator::Attributes[] = { - KX_PYATTRIBUTE_FLOAT_RW("start", 0, MAXFRAMEF, BL_ShapeActionActuator, m_startframe), - KX_PYATTRIBUTE_FLOAT_RW("end", 0, MAXFRAMEF, BL_ShapeActionActuator, m_endframe), - KX_PYATTRIBUTE_FLOAT_RW("blendin", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendin), + KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, MAXFRAMEF, BL_ShapeActionActuator, m_startframe), + KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, MAXFRAMEF, BL_ShapeActionActuator, m_endframe), + KX_PYATTRIBUTE_FLOAT_RW("blendIn", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendin), KX_PYATTRIBUTE_RW_FUNCTION("action", BL_ShapeActionActuator, pyattr_get_action, pyattr_set_action), KX_PYATTRIBUTE_SHORT_RW("priority", 0, 100, false, BL_ShapeActionActuator, m_priority), KX_PYATTRIBUTE_FLOAT_RW_CHECK("frame", 0, MAXFRAMEF, BL_ShapeActionActuator, m_localtime, CheckFrame), - KX_PYATTRIBUTE_STRING_RW("property", 0, 31, false, BL_ShapeActionActuator, m_propname), - KX_PYATTRIBUTE_STRING_RW("frameProperty", 0, 31, false, BL_ShapeActionActuator, m_framepropname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, 31, false, BL_ShapeActionActuator, m_propname), + KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 31, false, BL_ShapeActionActuator, m_framepropname), KX_PYATTRIBUTE_FLOAT_RW_CHECK("blendTime", 0, MAXFRAMEF, BL_ShapeActionActuator, m_blendframe, CheckBlendTime), - KX_PYATTRIBUTE_SHORT_RW_CHECK("type",0,100,false,BL_ShapeActionActuator,m_playtype,CheckType), + KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",0,100,false,BL_ShapeActionActuator,m_playtype,CheckType), { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index 7682f6755ef..caed85b9938 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -149,8 +149,8 @@ PyMethodDef SCA_2DFilterActuator::Methods[] = { PyAttributeDef SCA_2DFilterActuator::Attributes[] = { KX_PYATTRIBUTE_STRING_RW("shaderText", 0, 64000, false, SCA_2DFilterActuator, m_shaderText), KX_PYATTRIBUTE_SHORT_RW("disableMotionBlur", 0, 1, true, SCA_2DFilterActuator, m_disableMotionBlur), - KX_PYATTRIBUTE_ENUM_RW("type",RAS_2DFilterManager::RAS_2DFILTER_ENABLED,RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS,false,SCA_2DFilterActuator,m_type), - KX_PYATTRIBUTE_INT_RW("passNb", 0, 100, true, SCA_2DFilterActuator, m_int_arg), + KX_PYATTRIBUTE_ENUM_RW("mode",RAS_2DFilterManager::RAS_2DFILTER_ENABLED,RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS,false,SCA_2DFilterActuator,m_type), + KX_PYATTRIBUTE_INT_RW("passNumber", 0, 100, true, SCA_2DFilterActuator, m_int_arg), KX_PYATTRIBUTE_FLOAT_RW("value", 0.0, 100.0, SCA_2DFilterActuator, m_float_arg), { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index 33dc83506f3..4faa4b55d4a 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -270,9 +270,9 @@ PyMethodDef SCA_PropertyActuator::Methods[] = { }; PyAttributeDef SCA_PropertyActuator::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty), + KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty), KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt), - KX_PYATTRIBUTE_INT_RW("type", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */ + KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */ { NULL } //Sentinel }; @@ -296,7 +296,7 @@ const char SCA_PropertyActuator::SetProperty_doc[] = "\tof this name, the call is ignored.\n"; PyObject* SCA_PropertyActuator::PySetProperty(PyObject* args, PyObject* kwds) { - ShowDeprecationWarning("setProperty()", "the 'property' property"); + ShowDeprecationWarning("setProperty()", "the 'propName' property"); /* Check whether the name exists first ! */ char *nameArg; if (!PyArg_ParseTuple(args, "s:setProperty", &nameArg)) { @@ -321,7 +321,7 @@ const char SCA_PropertyActuator::GetProperty_doc[] = "\tReturn the property on which the actuator operates.\n"; PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* args, PyObject* kwds) { - ShowDeprecationWarning("getProperty()", "the 'property' property"); + ShowDeprecationWarning("getProperty()", "the 'propName' property"); return PyString_FromString(m_propname); } diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index 2632cbd3dac..3b343af3cba 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -347,8 +347,8 @@ PyMethodDef SCA_PropertySensor::Methods[] = { }; PyAttributeDef SCA_PropertySensor::Attributes[] = { - KX_PYATTRIBUTE_INT_RW("type",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype), - KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty), + KX_PYATTRIBUTE_INT_RW("mode",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype), + KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty), KX_PYATTRIBUTE_STRING_RW_CHECK("value",0,100,false,SCA_PropertySensor,m_checkpropval,validValueForProperty), { NULL } //Sentinel }; @@ -372,7 +372,7 @@ const char SCA_PropertySensor::GetType_doc[] = "\tReturns the type of check this sensor performs.\n"; PyObject* SCA_PropertySensor::PyGetType() { - ShowDeprecationWarning("getType()", "the type property"); + ShowDeprecationWarning("getType()", "the mode property"); return PyInt_FromLong(m_checktype); } @@ -385,7 +385,7 @@ const char SCA_PropertySensor::SetType_doc[] = "\tSet the type of check to perform.\n"; PyObject* SCA_PropertySensor::PySetType(PyObject* args) { - ShowDeprecationWarning("setType()", "the type property"); + ShowDeprecationWarning("setType()", "the mode property"); int typeArg; if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) { @@ -406,7 +406,7 @@ const char SCA_PropertySensor::GetProperty_doc[] = "\tReturn the property with which the sensor operates.\n"; PyObject* SCA_PropertySensor::PyGetProperty() { - ShowDeprecationWarning("getProperty()", "the 'property' property"); + ShowDeprecationWarning("getProperty()", "the 'propName' property"); return PyString_FromString(m_checkpropname); } @@ -418,7 +418,7 @@ const char SCA_PropertySensor::SetProperty_doc[] = "\tof this name, the call is ignored.\n"; PyObject* SCA_PropertySensor::PySetProperty(PyObject* args) { - ShowDeprecationWarning("setProperty()", "the 'property' property"); + ShowDeprecationWarning("setProperty()", "the 'propName' property"); /* We should query whether the name exists. Or should we create a prop */ /* on the fly? */ char *propNameArg = NULL; diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index 2db871c77cf..ff957d8350e 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -370,7 +370,7 @@ PyAttributeDef SCA_RandomActuator::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RO("para1",SCA_RandomActuator,m_parameter1), KX_PYATTRIBUTE_FLOAT_RO("para2",SCA_RandomActuator,m_parameter2), KX_PYATTRIBUTE_ENUM_RO("distribution",SCA_RandomActuator,m_distribution), - KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_RandomActuator,m_propname,CheckProperty), + KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_RandomActuator,m_propname,CheckProperty), KX_PYATTRIBUTE_RW_FUNCTION("seed",SCA_RandomActuator,pyattr_get_seed,pyattr_set_seed), { NULL } //Sentinel }; @@ -477,7 +477,7 @@ const char SCA_RandomActuator::SetProperty_doc[] = "\tSet the property to which the random value is assigned. If the \n" "\tgenerator and property types do not match, the assignment is ignored.\n"; PyObject* SCA_RandomActuator::PySetProperty(PyObject* args) { - ShowDeprecationWarning("setProperty()", "the 'property' property"); + ShowDeprecationWarning("setProperty()", "the 'propName' property"); char *nameArg; if (!PyArg_ParseTuple(args, "s:setProperty", &nameArg)) { return NULL; @@ -501,7 +501,7 @@ const char SCA_RandomActuator::GetProperty_doc[] = "\tgenerator and property types do not match, the assignment is ignored.\n"; PyObject* SCA_RandomActuator::PyGetProperty() { - ShowDeprecationWarning("getProperty()", "the 'property' property"); + ShowDeprecationWarning("getProperty()", "the 'propName' property"); return PyString_FromString(m_propname); } diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 5f7197e31f1..b87d0ee4283 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -419,7 +419,7 @@ PyAttributeDef KX_CameraActuator::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RW("min",-MAXFLOAT,MAXFLOAT,KX_CameraActuator,m_minHeight), KX_PYATTRIBUTE_FLOAT_RW("max",-MAXFLOAT,MAXFLOAT,KX_CameraActuator,m_maxHeight), KX_PYATTRIBUTE_FLOAT_RW("height",-MAXFLOAT,MAXFLOAT,KX_CameraActuator,m_height), - KX_PYATTRIBUTE_BOOL_RW("xy",KX_CameraActuator,m_x), + KX_PYATTRIBUTE_BOOL_RW("useXY",KX_CameraActuator,m_x), KX_PYATTRIBUTE_RW_FUNCTION("object", KX_CameraActuator, pyattr_get_object, pyattr_set_object), {NULL} }; @@ -561,7 +561,7 @@ const char KX_CameraActuator::SetXY_doc[] = "\t1=x, 0=y\n"; PyObject* KX_CameraActuator::PySetXY(PyObject* args) { - ShowDeprecationWarning("setXY()", "the xy property"); + ShowDeprecationWarning("setXY()", "the useXY property"); int value; if(PyArg_ParseTuple(args,"i:setXY", &value)) { diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index c9cb8e1b942..6f66faaeafb 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -631,7 +631,7 @@ PyAttributeDef KX_ConstraintActuator::Attributes[] = { KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK("direction",-MAXFLOAT,MAXFLOAT,KX_ConstraintActuator,m_refDirection,3,pyattr_check_direction), KX_PYATTRIBUTE_INT_RW("option",0,0xFFFF,false,KX_ConstraintActuator,m_option), KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_ConstraintActuator,m_activeTime), - KX_PYATTRIBUTE_STRING_RW("property",0,32,true,KX_ConstraintActuator,m_property), + KX_PYATTRIBUTE_STRING_RW("propName",0,32,true,KX_ConstraintActuator,m_property), KX_PYATTRIBUTE_FLOAT_RW("min",-MAXFLOAT,MAXFLOAT,KX_ConstraintActuator,m_minimumBound), KX_PYATTRIBUTE_FLOAT_RW("distance",-MAXFLOAT,MAXFLOAT,KX_ConstraintActuator,m_minimumBound), KX_PYATTRIBUTE_FLOAT_RW("max",-MAXFLOAT,MAXFLOAT,KX_ConstraintActuator,m_maximumBound), diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 9588e14d360..7c18b03906e 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -252,7 +252,7 @@ PyMethodDef KX_GameActuator::Methods[] = }; PyAttributeDef KX_GameActuator::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW("file",0,100,false,KX_GameActuator,m_filename), + KX_PYATTRIBUTE_STRING_RW("fileName",0,100,false,KX_GameActuator,m_filename), KX_PYATTRIBUTE_INT_RW("mode", KX_GAME_NODEF+1, KX_GAME_MAX-1, true, KX_GameActuator, m_mode), { NULL } //Sentinel }; @@ -279,7 +279,7 @@ const char KX_GameActuator::GetFile_doc[] = "get the name of the file to start.\n"; PyObject* KX_GameActuator::PyGetFile(PyObject* args, PyObject* kwds) { - ShowDeprecationWarning("getFile()", "the file property"); + ShowDeprecationWarning("getFile()", "the fileName property"); return PyString_FromString(m_filename); } @@ -291,7 +291,7 @@ PyObject* KX_GameActuator::PySetFile(PyObject* args, PyObject* kwds) { char* new_file; - ShowDeprecationWarning("setFile()", "the file property"); + ShowDeprecationWarning("setFile()", "the fileName property"); if (!PyArg_ParseTuple(args, "s:setFile", &new_file)) { diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fe9fb8bb583..9196d1e0527 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1197,8 +1197,8 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_worldOrientation), KX_PYATTRIBUTE_RW_FUNCTION("localPosition", KX_GameObject, pyattr_get_localPosition, pyattr_set_localPosition), KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition), - KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), - KX_PYATTRIBUTE_RO_FUNCTION("worldScaling", KX_GameObject, pyattr_get_worldScaling), + KX_PYATTRIBUTE_RW_FUNCTION("localScale", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), + KX_PYATTRIBUTE_RO_FUNCTION("worldScale", KX_GameObject, pyattr_get_worldScaling), KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict), /* Experemental, dont rely on these yet */ diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index 5e1785e9c21..3ec0598ac03 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -445,9 +445,8 @@ PyParentObject KX_IpoActuator::Parents[] = { }; PyMethodDef KX_IpoActuator::Methods[] = { - {"set", (PyCFunction) KX_IpoActuator::sPySet, METH_VARARGS, (PY_METHODCHAR)Set_doc}, - // deprecated + {"set", (PyCFunction) KX_IpoActuator::sPySet, METH_VARARGS, (PY_METHODCHAR)Set_doc}, {"setProperty", (PyCFunction) KX_IpoActuator::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc}, {"setStart", (PyCFunction) KX_IpoActuator::sPySetStart, METH_VARARGS, (PY_METHODCHAR)SetStart_doc}, {"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart, METH_NOARGS, (PY_METHODCHAR)GetStart_doc}, @@ -465,11 +464,11 @@ PyMethodDef KX_IpoActuator::Methods[] = { }; PyAttributeDef KX_IpoActuator::Attributes[] = { - KX_PYATTRIBUTE_FLOAT_RW("startFrame", 0, 300000, KX_IpoActuator, m_startframe), - KX_PYATTRIBUTE_FLOAT_RW("endFrame", 0, 300000, KX_IpoActuator, m_endframe), + KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, 300000, KX_IpoActuator, m_startframe), + KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, 300000, KX_IpoActuator, m_endframe), KX_PYATTRIBUTE_STRING_RW("propName", 0, 64, false, KX_IpoActuator, m_propname), KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 64, false, KX_IpoActuator, m_framepropname), - KX_PYATTRIBUTE_INT_RW("type", KX_ACT_IPO_NODEF+1, KX_ACT_IPO_MAX-1, true, KX_IpoActuator, m_type), + KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_IPO_NODEF+1, KX_ACT_IPO_MAX-1, true, KX_IpoActuator, m_type), KX_PYATTRIBUTE_BOOL_RW("useIpoAsForce", KX_IpoActuator, m_ipo_as_force), KX_PYATTRIBUTE_BOOL_RW("useIpoAdd", KX_IpoActuator, m_ipo_add), KX_PYATTRIBUTE_BOOL_RW("useIpoLocal", KX_IpoActuator, m_ipo_local), @@ -501,7 +500,7 @@ const char KX_IpoActuator::Set_doc[] = "\tSet the properties of the actuator.\n"; PyObject* KX_IpoActuator::PySet(PyObject* args) { - ShowDeprecationWarning("set()", "a number properties"); + ShowDeprecationWarning("set()", "a range properties"); /* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND */ /* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe, */ @@ -563,7 +562,7 @@ const char KX_IpoActuator::SetStart_doc[] = "\tSet the frame from which the ipo starts playing.\n"; PyObject* KX_IpoActuator::PySetStart(PyObject* args) { - ShowDeprecationWarning("setStart()", "the startFrame property"); + ShowDeprecationWarning("setStart()", "the frameStart property"); float startArg; if(!PyArg_ParseTuple(args, "f:setStart", &startArg)) { @@ -579,7 +578,7 @@ const char KX_IpoActuator::GetStart_doc[] = "getStart()\n" "\tReturns the frame from which the ipo starts playing.\n"; PyObject* KX_IpoActuator::PyGetStart() { - ShowDeprecationWarning("getStart()", "the startFrame property"); + ShowDeprecationWarning("getStart()", "the frameStart property"); return PyFloat_FromDouble(m_startframe); } @@ -589,7 +588,7 @@ const char KX_IpoActuator::SetEnd_doc[] = "\t - frame: last frame to use (int)\n" "\tSet the frame at which the ipo stops playing.\n"; PyObject* KX_IpoActuator::PySetEnd(PyObject* args) { - ShowDeprecationWarning("setEnd()", "the endFrame property"); + ShowDeprecationWarning("setEnd()", "the frameEnd property"); float endArg; if(!PyArg_ParseTuple(args, "f:setEnd", &endArg)) { return NULL; @@ -604,7 +603,7 @@ const char KX_IpoActuator::GetEnd_doc[] = "getEnd()\n" "\tReturns the frame at which the ipo stops playing.\n"; PyObject* KX_IpoActuator::PyGetEnd() { - ShowDeprecationWarning("getEnd()", "the endFrame property"); + ShowDeprecationWarning("getEnd()", "the frameEnd property"); return PyFloat_FromDouble(m_endframe); } @@ -670,7 +669,7 @@ const char KX_IpoActuator::SetType_doc[] = "\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n" "\tSet the operation mode of the actuator.\n"; PyObject* KX_IpoActuator::PySetType(PyObject* args) { - ShowDeprecationWarning("setType()", "the type property"); + ShowDeprecationWarning("setType()", "the mode property"); int typeArg; if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) { @@ -689,7 +688,7 @@ const char KX_IpoActuator::GetType_doc[] = "getType()\n" "\tReturns the operation mode of the actuator.\n"; PyObject* KX_IpoActuator::PyGetType() { - ShowDeprecationWarning("getType()", "the type property"); + ShowDeprecationWarning("getType()", "the mode property"); return PyInt_FromLong(m_type); } diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index fdde5fdcf7b..78a61e9d95e 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -366,7 +366,7 @@ PyAttributeDef KX_RaySensor::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("useMaterial", KX_RaySensor, m_bFindMaterial), KX_PYATTRIBUTE_BOOL_RW("useXRay", KX_RaySensor, m_bXRay), KX_PYATTRIBUTE_FLOAT_RW("range", 0, 10000, KX_RaySensor, m_distance), - KX_PYATTRIBUTE_STRING_RW("property", 0, 100, false, KX_RaySensor, m_propertyname), + KX_PYATTRIBUTE_STRING_RW("propName", 0, 100, false, KX_RaySensor, m_propertyname), KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RaySensor, m_axis), KX_PYATTRIBUTE_FLOAT_ARRAY_RO("hitPosition", KX_RaySensor, m_hitPosition, 3), KX_PYATTRIBUTE_FLOAT_ARRAY_RO("rayDirection", KX_RaySensor, m_rayDirection, 3), diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index af5631b4403..3d3bc1265a0 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -91,7 +91,7 @@ PyMethodDef KX_SCA_DynamicActuator::Methods[] = { }; PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = { - KX_PYATTRIBUTE_SHORT_RW("operation",0,4,false,KX_SCA_DynamicActuator,m_dyn_operation), + KX_PYATTRIBUTE_SHORT_RW("mode",0,4,false,KX_SCA_DynamicActuator,m_dyn_operation), KX_PYATTRIBUTE_FLOAT_RW("mass",0.0,MAXFLOAT,KX_SCA_DynamicActuator,m_setmass), { NULL } //Sentinel }; @@ -122,7 +122,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation, "\t 3 = disable rigid body\n" "Change the dynamic status of the parent object.\n") { - ShowDeprecationWarning("setOperation()", "the operation property"); + ShowDeprecationWarning("setOperation()", "the mode property"); int dyn_operation; if (!PyArg_ParseTuple(args, "i:setOperation", &dyn_operation)) @@ -142,7 +142,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, "Returns the operation type of this actuator.\n" ) { - ShowDeprecationWarning("getOperation()", "the operation property"); + ShowDeprecationWarning("getOperation()", "the mode property"); return PyInt_FromLong((long)m_dyn_operation); } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index e3622c211ff..9502599603c 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1720,7 +1720,7 @@ int KX_Scene::pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *a PyAttributeDef KX_Scene::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects), - KX_PYATTRIBUTE_RO_FUNCTION("objects_inactive", KX_Scene, pyattr_get_objects_inactive), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), + KX_PYATTRIBUTE_RO_FUNCTION("objectsInactive", KX_Scene, pyattr_get_objects_inactive), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), KX_PYATTRIBUTE_RO_FUNCTION("cameras", KX_Scene, pyattr_get_cameras), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights), KX_PYATTRIBUTE_RW_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera), diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 07a880c950b..3a341f007e4 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -295,7 +295,7 @@ PyMethodDef KX_SoundActuator::Methods[] = { }; PyAttributeDef KX_SoundActuator::Attributes[] = { - KX_PYATTRIBUTE_RW_FUNCTION("filename", KX_SoundActuator, pyattr_get_filename, pyattr_set_filename), + KX_PYATTRIBUTE_RW_FUNCTION("fileName", KX_SoundActuator, pyattr_get_filename, pyattr_set_filename), KX_PYATTRIBUTE_RW_FUNCTION("volume", KX_SoundActuator, pyattr_get_gain, pyattr_set_gain), KX_PYATTRIBUTE_RW_FUNCTION("pitch", KX_SoundActuator, pyattr_get_pitch, pyattr_set_pitch), KX_PYATTRIBUTE_RW_FUNCTION("rollOffFactor", KX_SoundActuator, pyattr_get_rollOffFactor, pyattr_set_rollOffFactor), @@ -303,7 +303,7 @@ PyAttributeDef KX_SoundActuator::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("position", KX_SoundActuator, pyattr_get_position, pyattr_set_position), KX_PYATTRIBUTE_RW_FUNCTION("velocity", KX_SoundActuator, pyattr_get_velocity, pyattr_set_velocity), KX_PYATTRIBUTE_RW_FUNCTION("orientation", KX_SoundActuator, pyattr_get_orientation, pyattr_set_orientation), - KX_PYATTRIBUTE_ENUM_RW("type",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type), + KX_PYATTRIBUTE_ENUM_RW("mode",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type), { NULL } //Sentinel }; @@ -364,7 +364,7 @@ PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYAT char* name = objectname.Ptr(); if (!name) { - PyErr_SetString(PyExc_RuntimeError, "value = actuator.filename: KX_SoundActuator, unable to get sound filename"); + PyErr_SetString(PyExc_RuntimeError, "value = actuator.fileName: KX_SoundActuator, unable to get sound fileName"); return NULL; } else return PyString_FromString(name); @@ -565,7 +565,7 @@ int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRI PyObject* KX_SoundActuator::PySetFilename(PyObject* args) { char *soundName = NULL; - ShowDeprecationWarning("setFilename()", "the filename property"); + ShowDeprecationWarning("setFilename()", "the fileName property"); // void *soundPointer = NULL; /*unused*/ if (!PyArg_ParseTuple(args, "s", &soundName)) @@ -576,7 +576,7 @@ PyObject* KX_SoundActuator::PySetFilename(PyObject* args) PyObject* KX_SoundActuator::PyGetFilename() { - ShowDeprecationWarning("getFilename()", "the filename property"); + ShowDeprecationWarning("getFilename()", "the fileName property"); if (!m_soundObject) { return PyString_FromString(""); @@ -585,7 +585,7 @@ PyObject* KX_SoundActuator::PyGetFilename() char* name = objectname.Ptr(); if (!name) { - PyErr_SetString(PyExc_RuntimeError, "Unable to get sound filename"); + PyErr_SetString(PyExc_RuntimeError, "Unable to get sound fileName"); return NULL; } else return PyString_FromString(name); @@ -759,7 +759,7 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* args) PyObject* KX_SoundActuator::PySetType(PyObject* args) { int typeArg; - ShowDeprecationWarning("setType()", "the type property"); + ShowDeprecationWarning("setType()", "the mode property"); if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) { return NULL; @@ -775,7 +775,7 @@ PyObject* KX_SoundActuator::PySetType(PyObject* args) PyObject* KX_SoundActuator::PyGetType() { - ShowDeprecationWarning("getType()", "the type property"); + ShowDeprecationWarning("getType()", "the mode property"); return PyInt_FromLong(m_type); } // <----- diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 2c02d949c63..8c0d5596939 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -292,11 +292,11 @@ PyMethodDef KX_TouchSensor::Methods[] = { }; PyAttributeDef KX_TouchSensor::Attributes[] = { - KX_PYATTRIBUTE_STRING_RW("property",0,100,false,KX_TouchSensor,m_touchedpropname), + KX_PYATTRIBUTE_STRING_RW("propName",0,100,false,KX_TouchSensor,m_touchedpropname), KX_PYATTRIBUTE_BOOL_RW("useMaterial",KX_TouchSensor,m_bFindMaterial), - KX_PYATTRIBUTE_BOOL_RW("pulseCollisions",KX_TouchSensor,m_bTouchPulse), - KX_PYATTRIBUTE_RO_FUNCTION("objectHit", KX_TouchSensor, pyattr_get_object_hit), - KX_PYATTRIBUTE_RO_FUNCTION("objectHitList", KX_TouchSensor, pyattr_get_object_hit_list), + KX_PYATTRIBUTE_BOOL_RW("usePulseCollision",KX_TouchSensor,m_bTouchPulse), + KX_PYATTRIBUTE_RO_FUNCTION("hitObject", KX_TouchSensor, pyattr_get_object_hit), + KX_PYATTRIBUTE_RO_FUNCTION("hitObjectList", KX_TouchSensor, pyattr_get_object_hit_list), { NULL } //Sentinel }; @@ -325,7 +325,7 @@ const char KX_TouchSensor::SetProperty_doc[] = "\tmaterials."; PyObject* KX_TouchSensor::PySetProperty(PyObject* value) { - ShowDeprecationWarning("setProperty()", "the propertyName property"); + ShowDeprecationWarning("setProperty()", "the propName property"); char *nameArg= PyString_AsString(value); if (nameArg==NULL) { PyErr_SetString(PyExc_ValueError, "expected a "); @@ -342,6 +342,8 @@ const char KX_TouchSensor::GetProperty_doc[] = "\tgetTouchMaterial() to find out whether this sensor\n" "\tlooks for properties or materials."; PyObject* KX_TouchSensor::PyGetProperty() { + ShowDeprecationWarning("getProperty()", "the propName property"); + return PyString_FromString(m_touchedpropname); } @@ -350,7 +352,7 @@ const char KX_TouchSensor::GetHitObject_doc[] = ; PyObject* KX_TouchSensor::PyGetHitObject() { - ShowDeprecationWarning("getHitObject()", "the objectHit property"); + ShowDeprecationWarning("getHitObject()", "the hitObject property"); /* to do: do Py_IncRef if the object is already known in Python */ /* otherwise, this leaks memory */ if (m_hitObject) @@ -366,7 +368,7 @@ const char KX_TouchSensor::GetHitObjectList_doc[] = "\tbut only those matching the property/material condition.\n"; PyObject* KX_TouchSensor::PyGetHitObjectList() { - ShowDeprecationWarning("getHitObjectList()", "the objectHitList property"); + ShowDeprecationWarning("getHitObjectList()", "the hitObjectList property"); /* to do: do Py_IncRef if the object is already known in Python */ /* otherwise, this leaks memory */ /* Edit, this seems ok and not to leak memory - Campbell */ return m_colliders->GetProxy(); diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index 46a1db9378a..d848065ad73 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -136,8 +136,8 @@ KX_VisibilityActuator::Methods[] = { PyAttributeDef KX_VisibilityActuator::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("visibility", KX_VisibilityActuator, m_visible), - KX_PYATTRIBUTE_BOOL_RW("occlusion", KX_VisibilityActuator, m_occlusion), - KX_PYATTRIBUTE_BOOL_RW("recursion", KX_VisibilityActuator, m_recursive), + KX_PYATTRIBUTE_BOOL_RW("useOcclusion", KX_VisibilityActuator, m_occlusion), + KX_PYATTRIBUTE_BOOL_RW("useRecursion", KX_VisibilityActuator, m_recursive), { NULL } //Sentinel }; diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 9b87842f7e0..28fd95611bc 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -318,6 +318,8 @@ Documentation for the GameLogic Module. @group Deprecated: addActiveActuator """ +import GameTypes + # TODO # globalDict # error @@ -346,7 +348,7 @@ def addActiveActuator(actuator, activate): """ Activates the given actuator. - @deprecated: Use L{SCA_PythonController.activate} and L{SCA_PythonController.deactivate} instead. + @deprecated: Use L{GameTypes.SCA_PythonController.activate} and L{GameTypes.SCA_PythonController.deactivate} instead. @type actuator: L{SCA_IActuator} or the actuator name as a string. @type activate: boolean @param activate: whether to activate or deactivate the given actuator. diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 0240efa4eab..d58f9087a9f 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -70,10 +70,9 @@ class SCA_ILogicBrick(CValue): @type owner: L{KX_GameObject} or None in exceptional cases. @ivar name: The name of this logic brick (read-only). @type name: string - @group Deprecated: getOwner, setExecutePriority, getExecutePriority """ - - #--The following methods are deprecated-- + +#{ Deprecated def getOwner(): """ Gets the game object associated with this logic brick. @@ -101,7 +100,7 @@ class SCA_ILogicBrick(CValue): @rtype: integer @return: this logic bricks current priority. """ - +#} class SCA_IObject(CValue): """ @@ -137,7 +136,6 @@ class SCA_ISensor(SCA_ILogicBrick): @type triggered: boolean @ivar positive: True if this sensor brick is in a positive state. (read-only) @type positive: boolean - @group Deprecated: isPositive, isTriggered, getUsePosPulseMode, setUsePosPulseMode, getFrequency, setFrequency, getUseNegPulseMode, setUseNegPulseMode, getInvert, setInvert, getLevel, setLevel """ def reset(): @@ -146,8 +144,7 @@ class SCA_ISensor(SCA_ILogicBrick): The sensor is put in its initial state as if it was just activated. """ - - #--The following methods are deprecated-- +#{ Deprecated def isPositive(): """ True if this sensor brick is in a positive state. @@ -223,6 +220,7 @@ class SCA_ISensor(SCA_ILogicBrick): @param level: Detect level instead of edge? (KX_TRUE, KX_FALSE) @type level: boolean """ +#} class SCA_IController(SCA_ILogicBrick): """ @@ -239,10 +237,8 @@ class SCA_IController(SCA_ILogicBrick): - note: the sensors are not necessarily owned by the same object. - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. @type actuators: sequence supporting index/string lookups and iteration. - - @group Deprecated: getState, getSensors, getActuators, getSensor, getActuator """ - +#{ Deprecated def getState(): """ Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active. @@ -277,6 +273,7 @@ class SCA_IController(SCA_ILogicBrick): @type name: string @rtype: L{SCA_IActuator} """ +#} class SCA_IActuator(SCA_ILogicBrick): """ @@ -289,31 +286,31 @@ class BL_ActionActuator(SCA_IActuator): @ivar action: The name of the action to set as the current action. @type action: string - @ivar start: Specifies the starting frame of the animation. - @type start: float - @ivar end: Specifies the ending frame of the animation. - @type end: float - @ivar blendin: Specifies the number of frames of animation to generate when making transitions between actions. - @type blendin: float + @ivar frameStart: Specifies the starting frame of the animation. + @type frameStart: float + @ivar frameEnd: Specifies the ending frame of the animation. + @type frameEnd: float + @ivar blendIn: Specifies the number of frames of animation to generate when making transitions between actions. + @type blendIn: float @ivar priority: Sets the priority of this actuator. Actuators will lower priority numbers will override actuators with higher numbers. @type priority: integer @ivar frame: Sets the current frame for the animation. @type frame: float - @ivar property: Sets the property to be used in FromProp playback mode. - @type property: string + @ivar propName: Sets the property to be used in FromProp playback mode. + @type propName: string @ivar blendTime: Sets the internal frame timer. This property must be in - the range from 0.0 to blendin. + the range from 0.0 to blendIn. @type blendTime: float - @ivar type: The operation mode of the actuator. KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - @type type: integer + @ivar mode: The operation mode of the actuator. KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND + @type mode: integer @ivar useContinue: The actions continue option, True or False. When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. @type: boolean - @ivar frameProperty: The name of the property that is set to the current frame number. - @type frameProperty: string + @ivar framePropName: The name of the property that is set to the current frame number. + @type framePropName: string """ def setChannel(channel, matrix, mode = False): """ @@ -326,7 +323,7 @@ class BL_ActionActuator(SCA_IActuator): @type mode: boolean """ - #--The following methods are deprecated-- +#{ Deprecated def setAction(action, reset = True): """ Sets the current action. @@ -343,7 +340,7 @@ class BL_ActionActuator(SCA_IActuator): def setStart(start): """ Specifies the starting frame of the animation. - @deprecated: Use the L{start} property + @deprecated: Use the L{frameStart} property @param start: the starting frame of the animation @type start: float """ @@ -351,7 +348,7 @@ class BL_ActionActuator(SCA_IActuator): def setEnd(end): """ Specifies the ending frame of the animation. - @deprecated: use the L{end} property + @deprecated: use the L{frameEnd} property @param end: the ending frame of the animation @type end: float """ @@ -359,7 +356,7 @@ class BL_ActionActuator(SCA_IActuator): """ Specifies the number of frames of animation to generate when making transitions between actions. - @deprecated: use the L{blendin} property + @deprecated: use the L{blendIn} property @param blendin: the number of frames in transition. @type blendin: float """ @@ -417,7 +414,7 @@ class BL_ActionActuator(SCA_IActuator): """ Set the actions continue option True or False. see getContinue. - @deprecated: use the L{continue} property + @deprecated: use the L{useContinue} property @param cont: The continue option. @type cont: bool """ @@ -451,21 +448,21 @@ class BL_ActionActuator(SCA_IActuator): """ Returns the starting frame of the action. - @deprecated: use the L{start} property + @deprecated: use the L{frameStart} property @rtype: float """ def getEnd(): """ Returns the last frame of the action. - @deprecated: use the L{end} property + @deprecated: use the L{frameEnd} property @rtype: float """ def getBlendin(): """ Returns the number of interpolation animation frames to be generated when this actuator is triggered. - @deprecated: use the L{blendin} property + @deprecated: use the L{blendIn} property @rtype: float """ def getPriority(): @@ -492,7 +489,7 @@ class BL_ActionActuator(SCA_IActuator): """ def setFrameProperty(prop): """ - @deprecated: use the L{frameProperty} property + @deprecated: use the L{framePropName} property @param prop: A string specifying the property of the object that will be updated with the action frame number. @type prop: string """ @@ -500,9 +497,10 @@ class BL_ActionActuator(SCA_IActuator): """ Returns the name of the property that is set to the current frame number. - @deprecated: use the L{frameProperty} property + @deprecated: use the L{framePropName} property @rtype: string """ +#} class BL_Shader(PyObjectPlus): """ @@ -755,31 +753,32 @@ class BL_ShapeActionActuator(SCA_IActuator): @ivar action: The name of the action to set as the current shape action. @type action: string - @ivar start: Specifies the starting frame of the shape animation. - @type start: float - @ivar end: Specifies the ending frame of the shape animation. - @type end: float - @ivar blendin: Specifies the number of frames of animation to generate when making transitions between actions. - @type blendin: float + @ivar frameStart: Specifies the starting frame of the shape animation. + @type frameStart: float + @ivar frameEnd: Specifies the ending frame of the shape animation. + @type frameEnd: float + @ivar blendIn: Specifies the number of frames of animation to generate when making transitions between actions. + @type blendIn: float @ivar priority: Sets the priority of this actuator. Actuators will lower priority numbers will override actuators with higher numbers. @type priority: integer @ivar frame: Sets the current frame for the animation. @type frame: float - @ivar property: Sets the property to be used in FromProp playback mode. - @type property: string + @ivar propName: Sets the property to be used in FromProp playback mode. + @type propName: string @ivar blendTime: Sets the internal frame timer. This property must be in the range from 0.0 to blendin. @type blendTime: float - @ivar type: The operation mode of the actuator. + @ivar mode: The operation mode of the actuator. KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND - @type type: integer - @ivar frameProperty: The name of the property that is set to the current frame number. - @type frameProperty: string + @type mode: integer + @ivar framePropName: The name of the property that is set to the current frame number. + @type framePropName: string """ +#{ Deprecated def setAction(action, reset = True): """ Sets the current action. @@ -798,7 +797,7 @@ class BL_ShapeActionActuator(SCA_IActuator): """ Specifies the starting frame of the animation. - @deprecated: use the L{start} property + @deprecated: use the L{frameStart} property @param start: the starting frame of the animation @type start: float """ @@ -807,7 +806,7 @@ class BL_ShapeActionActuator(SCA_IActuator): """ Specifies the ending frame of the animation. - @deprecated: use the L{end} property + @deprecated: use the L{frameEnd} property @param end: the ending frame of the animation @type end: float """ @@ -816,7 +815,7 @@ class BL_ShapeActionActuator(SCA_IActuator): Specifies the number of frames of animation to generate when making transitions between actions. - @deprecated: use the L{blendin} property + @deprecated: use the L{blendIn} property @param blendin: the number of frames in transition. @type blendin: float """ @@ -891,21 +890,21 @@ class BL_ShapeActionActuator(SCA_IActuator): """ Returns the starting frame of the action. - @deprecated: use the L{start} property + @deprecated: use the L{frameStart} property @rtype: float """ def getEnd(): """ Returns the last frame of the action. - @deprecated: use the L{end} property + @deprecated: use the L{frameEnd} property @rtype: float """ def getBlendin(): """ Returns the number of interpolation animation frames to be generated when this actuator is triggered. - @deprecated: use the L{blendin} property + @deprecated: use the L{blendIn} property @rtype: float """ def getPriority(): @@ -932,7 +931,7 @@ class BL_ShapeActionActuator(SCA_IActuator): """ def setFrameProperty(prop): """ - @deprecated: use the L{frameProperty} property + @deprecated: use the L{framePropName} property @param prop: A string specifying the property of the object that will be updated with the action frame number. @type prop: string """ @@ -940,9 +939,10 @@ class BL_ShapeActionActuator(SCA_IActuator): """ Returns the name of the property that is set to the current frame number. - @deprecated: use the L{frameProperty} property + @deprecated: use the L{framePropName} property @rtype: string """ +#} class CListValue(CPropValue): """ @@ -1002,7 +1002,7 @@ class CListValue(CPropValue): This has the advantage that you can store the id in places you could not store a gameObject. Warning: the id is derived from a memory location and will be different each time the game engine starts. - """# + """ class KX_BlenderMaterial(PyObjectPlus): # , RAS_IPolyMaterial) """ @@ -1023,7 +1023,7 @@ class KX_BlenderMaterial(PyObjectPlus): # , RAS_IPolyMaterial) Set the pixel color arithmetic functions. @param src: Specifies how the red, green, blue, - and alpha source blending factors are computed. + and alpha source blending factors are computed. @type src: GL_ZERO, GL_ONE, GL_SRC_COLOR, @@ -1094,6 +1094,7 @@ class KX_CDActuator(SCA_IActuator): """ Plays the track selected. """ +#{ Deprecated def setGain(gain): """ Sets the gain (volume) of the CD. @@ -1110,6 +1111,7 @@ class KX_CDActuator(SCA_IActuator): @rtype: float @return: Between 0.0 (silent) and 1.0 (max volume) """ +#} class KX_CameraActuator(SCA_IActuator): """ @@ -1121,16 +1123,18 @@ class KX_CameraActuator(SCA_IActuator): @type max: float @ivar height: height to stay above the target object @type height: float - @ivar xy: axis this actuator is tracking, true=X, false=Y - @type xy: boolean + @ivar useXY: axis this actuator is tracking, true=X, false=Y + @type useXY: boolean @ivar object: the object this actuator tracks. @type object: KX_GameObject or None @author: snail """ +#{ Deprecated def getObject(name_only = 1): """ Returns the name of the object this actuator tracks. + @deprecated: Use the L{object} attribute instead. @type name_only: bool @param name_only: optional argument, when 0 return a KX_GameObject @rtype: string, KX_GameObject or None if no object is set @@ -1140,6 +1144,7 @@ class KX_CameraActuator(SCA_IActuator): """ Sets the object this actuator tracks. + @deprecated: Use the L{object} attribute instead. @param target: the object to track. @type target: L{KX_GameObject}, string or None """ @@ -1148,6 +1153,7 @@ class KX_CameraActuator(SCA_IActuator): """ Returns the minimum distance to target maintained by the actuator. + @deprecated: Use the L{min} attribute instead. @rtype: float """ @@ -1156,6 +1162,7 @@ class KX_CameraActuator(SCA_IActuator): Sets the minimum distance to the target object maintained by the actuator. + @deprecated: Use the L{min} attribute instead. @param distance: The minimum distance to maintain. @type distance: float """ @@ -1164,6 +1171,7 @@ class KX_CameraActuator(SCA_IActuator): """ Gets the maximum distance to stay from the target object. + @deprecated: Use the L{max} attribute instead. @rtype: float """ @@ -1171,6 +1179,7 @@ class KX_CameraActuator(SCA_IActuator): """ Sets the maximum distance to stay from the target object. + @deprecated: Use the L{max} attribute instead. @param distance: The maximum distance to maintain. @type distance: float """ @@ -1179,6 +1188,7 @@ class KX_CameraActuator(SCA_IActuator): """ Returns the height to stay above the target object. + @deprecated: Use the L{height} attribute instead. @rtype: float """ @@ -1186,6 +1196,7 @@ class KX_CameraActuator(SCA_IActuator): """ Sets the height to stay above the target object. + @deprecated: Use the L{height} attribute instead. @type height: float @param height: The height to stay above the target object. """ @@ -1194,6 +1205,7 @@ class KX_CameraActuator(SCA_IActuator): """ Sets the axis to get behind. + @deprecated: Use the L{useXY} attribute instead. @param xaxis: False to track Y axis, True to track X axis. @type xaxis: boolean """ @@ -1202,9 +1214,11 @@ class KX_CameraActuator(SCA_IActuator): """ Returns the axis this actuator is tracking. + @deprecated: Use the L{useXY} attribute instead. @return: True if tracking X axis, False if tracking Y axis. @rtype: boolean """ +#} class KX_ConstraintActuator(SCA_IActuator): """ @@ -1238,8 +1252,8 @@ class KX_ConstraintActuator(SCA_IActuator): If set to 0, the actuator is not limited in time. @type time: integer - @ivar property: the name of the property or material for the ray detection of the distance constraint. - @type property: string + @ivar propName: the name of the property or material for the ray detection of the distance constraint. + @type propName: string @ivar min: The lower bound of the constraint For the rotation and orientation constraint, it represents radiant @@ -1279,6 +1293,7 @@ class KX_ConstraintActuator(SCA_IActuator): KX_ACT_CONSTRAINT_FHNZ (21) : set force field along negative Z axis @type limit: integer """ +#{ Deprecated def setDamp(time): """ Sets the time this constraint is delayed. @@ -1442,6 +1457,7 @@ class KX_ConstraintActuator(SCA_IActuator): @rtype: float """ +#} class KX_ConstraintWrapper(PyObjectPlus): """ @@ -1462,8 +1478,8 @@ class KX_GameActuator(SCA_IActuator): Properties: - @ivar file: the new .blend file to load - @type file: string. + @ivar fileName: the new .blend file to load + @type fileName: string. @ivar mode: The mode of this actuator @type mode: Constant in... - L{GameLogic.KX_GAME_LOAD} @@ -1473,21 +1489,23 @@ class KX_GameActuator(SCA_IActuator): - L{GameLogic.KX_GAME_SAVECFG} - L{GameLogic.KX_GAME_LOADCFG} """ +#{ Deprecated def getFile(): """ Returns the filename of the new .blend file to load. - @deprecated: use the L{file} property + @deprecated: use the L{fileName} property @rtype: string """ def setFile(filename): """ Sets the new .blend file to load. - @deprecated: use the L{file} property + @deprecated: use the L{fileName} property @param filename: The file name this actuator will load. @type filename: string """ +#} class KX_GameObject(SCA_IObject): """ @@ -1530,16 +1548,16 @@ class KX_GameObject(SCA_IObject): @type orientation: 3x3 Matrix [[float]] On write: local orientation, on read: world orientation @ivar scaling: The object's scaling factor. list [sx, sy, sz] - deprecated: use L{localScaling} and L{worldScaling} + deprecated: use L{localScale} and L{worldScale} @type scaling: list [sx, sy, sz] On write: local scaling, on read: world scaling @ivar localOrientation: The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. @type localOrientation: 3x3 Matrix [[float]] @ivar worldOrientation: The object's world orientation. @type worldOrientation: 3x3 Matrix [[float]] - @ivar localScaling: The object's local scaling factor. - @type localScaling: list [sx, sy, sz] - @ivar worldScaling: The object's world scaling factor. Read-only - @type worldScaling: list [sx, sy, sz] + @ivar localScale: The object's local scaling factor. + @type localScale: list [sx, sy, sz] + @ivar worldScale: The object's world scaling factor. Read-only + @type worldScale: list [sx, sy, sz] @ivar localPosition: The object's local position. @type localPosition: list [x, y, z] @ivar worldPosition: The object's world position. @@ -2002,16 +2020,16 @@ class KX_IpoActuator(SCA_IActuator): """ IPO actuator activates an animation. - @ivar startFrame: Start frame. - @type startFrame: float - @ivar endFrame: End frame. - @type endFrame: float + @ivar frameStart: Start frame. + @type frameStart: float + @ivar frameEnd: End frame. + @type frameEnd: float @ivar propName: Use this property to define the Ipo position @type propName: string @ivar framePropName: Assign this property this action current frame number @type framePropName: string - @ivar type: Play mode for the ipo. (In GameLogic.KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND, KX_IPOACT_FROM_PROP) - @type type: int + @ivar mode: Play mode for the ipo. (In GameLogic.KX_IPOACT_PLAY, KX_IPOACT_PINGPONG, KX_IPOACT_FLIPPER, KX_IPOACT_LOOPSTOP, KX_IPOACT_LOOPEND, KX_IPOACT_FROM_PROP) + @type mode: int @ivar useIpoAsForce: Apply Ipo as a global or local force depending on the local option (dynamic objects only) @type useIpoAsForce: bool @ivar useIpoAdd: Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag @@ -2021,6 +2039,7 @@ class KX_IpoActuator(SCA_IActuator): @ivar useChildren: Update IPO on all children Objects as well @type useChildren: bool """ +#{ Deprecated def set(mode, startframe, endframe, force): """ Sets the properties of the actuator. @@ -2046,28 +2065,28 @@ class KX_IpoActuator(SCA_IActuator): """ Sets the frame from which the IPO starts playing. - @deprecated: use L{startFrame} + @deprecated: use L{frameStart} @type startframe: integer """ def getStart(): """ Returns the frame from which the IPO starts playing. - @deprecated: use L{startFrame} + @deprecated: use L{frameStart} @rtype: integer """ def setEnd(endframe): """ Sets the frame at which the IPO stops playing. - @deprecated: use L{endFrame} + @deprecated: use L{frameEnd} @type endframe: integer """ def getEnd(): """ Returns the frame at which the IPO stops playing. - @deprecated: use L{endFrame} + @deprecated: use L{frameEnd} @rtype: integer """ def setIpoAsForce(force): @@ -2133,6 +2152,7 @@ class KX_IpoActuator(SCA_IActuator): @deprecated: use L{useIpoLocal} """ +#} class KX_LightObject(KX_GameObject): """ @@ -2420,20 +2440,19 @@ class KX_TouchSensor(SCA_ISensor): """ Touch sensor detects collisions between objects. - @ivar property: The property or material to collide with. - @type property: string + @ivar propName: The property or material to collide with. + @type propName: string @ivar useMaterial: Determines if the sensor is looking for a property or material. KX_True = Find material; KX_False = Find property @type useMaterial: boolean - @ivar pulseCollisions: The last collided object. - @type pulseCollisions: bool - @ivar objectHit: The last collided object. (read-only) - @type objectHit: L{KX_GameObject} or None - @ivar objectHitList: A list of colliding objects. (read-only) - @type objectHitList: L{CListValue} of L{KX_GameObject} + @ivar usePulseCollision: The last collided object. + @type usePulseCollision: bool + @ivar hitObject: The last collided object. (read-only) + @type hitObject: L{KX_GameObject} or None + @ivar hitObjectList: A list of colliding objects. (read-only) + @type hitObjectList: L{CListValue} of L{KX_GameObject} """ - - #--The following methods are deprecated, please use properties instead. +#{ Deprecated def setProperty(name): """ Set the property or material to collide with. Use @@ -2457,7 +2476,7 @@ class KX_TouchSensor(SCA_ISensor): """ Returns the last object hit by this touch sensor. - @deprecated: use the L{objectHit} property + @deprecated: use the L{hitObject} property @rtype: L{KX_GameObject} """ def getHitObjectList(): @@ -2466,8 +2485,8 @@ class KX_TouchSensor(SCA_ISensor): Only objects that have the requisite material/property are listed. - @deprecated: use the L{objectHitList} property - @rtype: L{CListValue} of L{KX_GameObject} + @deprecated: use the L{hitObjectList} property + @rtype: L{CListValue} of L{hitObjectList} """ def getTouchMaterial(): """ @@ -2476,6 +2495,7 @@ class KX_TouchSensor(SCA_ISensor): @deprecated: use the L{useMaterial} property """ +#} class KX_NearSensor(KX_TouchSensor): """ @@ -3393,8 +3413,8 @@ class KX_RaySensor(SCA_ISensor): """ A ray sensor detects the first object in a given direction. - @ivar property: The property the ray is looking for. - @type property: string + @ivar propName: The property the ray is looking for. + @type propName: string @ivar range: The distance of the ray. @type range: float @ivar useMaterial: Whether or not to look for a material (false = property) @@ -3414,7 +3434,7 @@ class KX_RaySensor(SCA_ISensor): KX_RAY_AXIS_POS_X, KX_RAY_AXIS_POS_Y, KX_RAY_AXIS_POS_Z, KX_RAY_AXIS_NEG_X, KX_RAY_AXIS_NEG_Y, KX_RAY_AXIS_NEG_Z """ - +#{ Deprecated def getHitObject(): """ Returns the game object that was hit by this ray. @@ -3443,6 +3463,7 @@ class KX_RaySensor(SCA_ISensor): @deprecated: Use the L{rayDirection} attribute instead. @rtype: list [dx, dy, dz] """ +#} class KX_SCA_AddObjectActuator(SCA_IActuator): """ @@ -3562,13 +3583,14 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): class KX_SCA_DynamicActuator(SCA_IActuator): """ Dynamic Actuator. - @ivar operation: the type of operation of the actuator, 0-4 + @ivar mode: the type of operation of the actuator, 0-4 KX_DYN_RESTORE_DYNAMICS, KX_DYN_DISABLE_DYNAMICS, KX_DYN_ENABLE_RIGID_BODY, KX_DYN_DISABLE_RIGID_BODY, KX_DYN_SET_MASS - @type operation: integer + @type mode: integer @ivar mass: the mass value for the KX_DYN_SET_MASS operation @type mass: float """ +#{ Deprecated def setOperation(operation): """ Set the type of operation when the actuator is activated: @@ -3578,13 +3600,14 @@ class KX_SCA_DynamicActuator(SCA_IActuator): - 3 = disable rigid body - 4 = set mass - @deprecated: Use the L{operation} attribute instead. + @deprecated: Use the L{mode} attribute instead. """ def getOperation(): """ return the type of operation - @deprecated: Use the L{operation} attribute instead. + @deprecated: Use the L{mode} attribute instead. """ +#} class KX_SCA_EndObjectActuator(SCA_IActuator): """ @@ -3714,8 +3737,8 @@ class KX_Scene(PyObjectPlus): @type name: string @ivar objects: A list of objects in the scene, (read-only). @type objects: L{CListValue} of L{KX_GameObject} - @ivar objects_inactive: A list of objects on background layers (used for the addObject actuator), (read-only). - @type objects_inactive: L{CListValue} of L{KX_GameObject} + @ivar objectsInactive: A list of objects on background layers (used for the addObject actuator), (read-only). + @type objectsInactive: L{CListValue} of L{KX_GameObject} @ivar lights: A list of lights in the scene, (read-only). @type lights: L{CListValue} of L{KX_LightObject} @ivar cameras: A list of cameras in the scene, (read-only). @@ -3791,6 +3814,7 @@ class KX_SceneActuator(SCA_IActuator): @ivar mode: The mode of the actuator @type mode: int from 0 to 5 L{GameLogic.Scene Actuator} """ +#{ Deprecated def setUseRestart(flag): """ Set flag to True to restart the scene. @@ -3837,6 +3861,7 @@ class KX_SceneActuator(SCA_IActuator): @deprecated: use the L{camera} attribute instead. @rtype: string """ +#} class KX_SoundActuator(SCA_IActuator): """ @@ -3846,8 +3871,8 @@ class KX_SoundActuator(SCA_IActuator): the actuator to be activated - they act instantly provided that the actuator has been activated once at least. - @ivar filename: Sets the filename of the sound this actuator plays. - @type filename: string + @ivar fileName: Sets the filename of the sound this actuator plays. + @type fileName: string @ivar volume: Sets the volume (gain) of the sound. @type volume: float @@ -3871,31 +3896,17 @@ class KX_SoundActuator(SCA_IActuator): also use quaternion [float,float,float,float] or euler angles [float,float,float] @type orientation: 3x3 matrix [[float]] - @ivar type: Sets the operation mode of the actuator. You can use one of the following constant: + @ivar mode: Sets the operation mode of the actuator. You can use one of the following constant: - KX_SOUNDACT_PLAYSTOP (1) - KX_SOUNDACT_PLAYEND (2) - KX_SOUNDACT_LOOPSTOP (3) - KX_SOUNDACT_LOOPEND (4) - KX_SOUNDACT_LOOPBIDIRECTIONAL (5) - KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP (6) - @type type: integer - - @group Play Methods: startSound, pauseSound, stopSound + @type mode: integer """ - def setFilename(filename): - """ - Sets the filename of the sound this actuator plays. - - @deprecated: Use the L{filename} attribute instead. - @type filename: string - """ - def getFilename(): - """ - Returns the filename of the sound this actuator plays. - - @deprecated: Use the L{filename} attribute instead. - @rtype: string - """ + +#{ Play Methods def startSound(): """ Starts the sound. @@ -3908,6 +3919,23 @@ class KX_SoundActuator(SCA_IActuator): """ Stops the sound. """ +#} + +#{ Deprecated + def setFilename(filename): + """ + Sets the filename of the sound this actuator plays. + + @deprecated: Use the L{fileName} attribute instead. + @type filename: string + """ + def getFilename(): + """ + Returns the filename of the sound this actuator plays. + + @deprecated: Use the L{fileName} attribute instead. + @rtype: string + """ def setGain(gain): """ Sets the gain (volume) of the sound @@ -4030,6 +4058,7 @@ class KX_SoundActuator(SCA_IActuator): @rtype: integer @return: KX_SOUNDACT_PLAYSTOP, KX_SOUNDACT_PLAYEND, KX_SOUNDACT_LOOPSTOP, KX_SOUNDACT_LOOPEND, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP """ +#} class KX_StateActuator(SCA_IActuator): """ @@ -4451,11 +4480,12 @@ class KX_VisibilityActuator(SCA_IActuator): Visibility Actuator. @ivar visibility: whether the actuator makes its parent object visible or invisible @type visibility: boolean - @ivar occlusion: whether the actuator makes its parent object an occluder or not - @type occlusion: boolean - @ivar recursion: whether the visibility/occlusion should be propagated to all children of the object - @type recursion: boolean + @ivar useOcclusion: whether the actuator makes its parent object an occluder or not + @type useOcclusion: boolean + @ivar useRecursion: whether the visibility/occlusion should be propagated to all children of the object + @type useRecursion: boolean """ +#{ Deprecated def set(visible): """ Sets whether the actuator makes its parent object visible or invisible. @@ -4464,8 +4494,7 @@ class KX_VisibilityActuator(SCA_IActuator): @param visible: - True: Makes its parent visible. - False: Makes its parent invisible. """ -# -# Documentation for PyObjectPlus base class +#} class SCA_2DFilterActuator(SCA_IActuator): """ @@ -4483,7 +4512,7 @@ class SCA_2DFilterActuator(SCA_IActuator): @type shaderText: string @ivar disableMotionBlur: action on motion blur: 0=enable, 1=disable @type disableMotionBlur: integer - @ivar type: type of 2D filter, use one of the following constants: + @ivar mode: type of 2D filter, use one of the following constants: RAS_2DFILTER_ENABLED (-2) : enable the filter that was previously disabled RAS_2DFILTER_DISABLED (-1) : disable the filter that is currently active RAS_2DFILTER_NOFILTER (0) : disable and destroy the filter that is currently active @@ -4499,10 +4528,10 @@ class SCA_2DFilterActuator(SCA_IActuator): RAS_2DFILTER_SEPIA (10) RAS_2DFILTER_INVERT (11) RAS_2DFILTER_CUSTOMFILTER (12) : customer filter, the code code is set via shaderText property - @type type: integer - @ivar passNb: order number of filter in the stack of 2D filters. Filters are executed in increasing order of passNb. + @type mode: integer + @ivar passNumber: order number of filter in the stack of 2D filters. Filters are executed in increasing order of passNb. Only be one filter can be defined per passNb. - @type passNb: integer (0-100) + @type passNumber: integer (0-100) @ivar value: argument for motion blur filter @type value: float (0.0-100.0) """ @@ -4706,7 +4735,7 @@ class SCA_JoystickSensor(SCA_ISensor): """ Returns the state of the joysticks axis. See differs to L{getAxis()} returning the current state of the joystick. - @deprecated: Use the L{axisPosition} attribute instead. + @deprecated: Use the L{axisSingle} attribute instead. @rtype: list @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. @@ -4929,13 +4958,14 @@ class SCA_PropertyActuator(SCA_IActuator): Properties: - @ivar property: the property on which to operate. - @type property: string + @ivar propName: the property on which to operate. + @type propName: string @ivar value: the value with which the actuator operates. @type value: string - @ivar type: TODO - add constants to game logic dict!. - @type type: iny + @ivar mode: TODO - add constants to game logic dict!. + @type mode: int """ +#{ Deprecated def setProperty(prop): """ Set the property on which to operate. @@ -4970,6 +5000,7 @@ class SCA_PropertyActuator(SCA_IActuator): @deprecated: Use the L{value} attribute instead. @rtype: string """ +#} class SCA_PropertySensor(SCA_ISensor): """ @@ -4977,21 +5008,21 @@ class SCA_PropertySensor(SCA_ISensor): Properties: - @ivar type: type of check on the property: + @ivar mode: type of check on the property: KX_PROPSENSOR_EQUAL(1), KX_PROPSENSOR_NOTEQUAL(2), KX_PROPSENSOR_INTERVAL(3), KX_PROPSENSOR_CHANGED(4), KX_PROPSENSOR_EXPRESSION(5) - @type type: integer - @ivar property: the property with which the sensor operates. - @type property: string + @type mode: integer + @ivar propName: the property the sensor operates. + @type propName: string @ivar value: the value with which the sensor compares to the value of the property. @type value: string """ - +#{ Deprecated def getType(): """ Gets when to activate this sensor. - @deprecated: Use the L{type} attribute instead. + @deprecated: Use the L{mode} attribute instead. @return: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, or KX_PROPSENSOR_EXPRESSION. @@ -5001,7 +5032,7 @@ class SCA_PropertySensor(SCA_ISensor): """ Set the type of check to perform. - @deprecated: Use the L{type} attribute instead. + @deprecated: Use the L{mode} attribute instead. @type checktype: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL, KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED, or KX_PROPSENSOR_EXPRESSION. @@ -5011,7 +5042,7 @@ class SCA_PropertySensor(SCA_ISensor): """ Return the property with which the sensor operates. - @deprecated: Use the L{property} attribute instead. + @deprecated: Use the L{propName} attribute instead. @rtype: string @return: the name of the property this sensor is watching. """ @@ -5020,7 +5051,7 @@ class SCA_PropertySensor(SCA_ISensor): Sets the property with which to operate. If there is no property of that name, this call is ignored. - @deprecated: Use the L{property} attribute instead. + @deprecated: Use the L{propName} attribute instead. @type name: string. """ def getValue(): @@ -5040,6 +5071,7 @@ class SCA_PropertySensor(SCA_ISensor): @deprecated: Use the L{value} attribute instead. @type value: string """ +#} class SCA_PythonController(SCA_IController): """ @@ -5102,76 +5134,11 @@ class SCA_RandomActuator(SCA_IActuator): KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL @type distribution: integer, read-only - @ivar property: the name of the property to set with the random value. + @ivar propName: the name of the property to set with the random value. If the generator and property types do not match, the assignment is ignored. - @type property: string + @type propName: string """ - def setSeed(seed): - """ - Sets the seed of the random number generator. - - Equal seeds produce equal series. If the seed is 0, - the generator will produce the same value on every call. - - @deprecated: Use the L{seed} attribute instead. - @type seed: integer - """ - def getSeed(): - """ - Returns the initial seed of the generator. - - @deprecated: Use the L{seed} attribute instead. - @rtype: integer - """ - def getPara1(): - """ - Returns the first parameter of the active distribution. - - Refer to the documentation of the generator types for the meaning - of this value. - - @deprecated: Use the L{para1} attribute instead. - @rtype: float - """ - def getPara2(): - """ - Returns the second parameter of the active distribution. - - Refer to the documentation of the generator types for the meaning - of this value. - - @deprecated: Use the L{para2} attribute instead. - @rtype: float - """ - def getDistribution(): - """ - Returns the type of random distribution. - - @deprecated: Use the L{distribution} attribute instead. - @rtype: distribution type - @return: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, - KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, - KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, - KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL - """ - def setProperty(property): - """ - Set the property to which the random value is assigned. - - If the generator and property types do not match, the assignment is ignored. - - @deprecated: Use the L{property} attribute instead. - @type property: string - @param property: The name of the property to set. - """ - def getProperty(): - """ - Returns the name of the property to set. - - @deprecated: Use the L{property} attribute instead. - @rtype: string - """ def setBoolConst(value): """ Sets this generator to produce a constant boolean value. @@ -5249,6 +5216,74 @@ class SCA_RandomActuator(SCA_IActuator): @type half_life: float """ +#{ Deprecated + def setSeed(seed): + """ + Sets the seed of the random number generator. + + Equal seeds produce equal series. If the seed is 0, + the generator will produce the same value on every call. + + @deprecated: Use the L{seed} attribute instead. + @type seed: integer + """ + def getSeed(): + """ + Returns the initial seed of the generator. + + @deprecated: Use the L{seed} attribute instead. + @rtype: integer + """ + def getPara1(): + """ + Returns the first parameter of the active distribution. + + Refer to the documentation of the generator types for the meaning + of this value. + + @deprecated: Use the L{para1} attribute instead. + @rtype: float + """ + def getPara2(): + """ + Returns the second parameter of the active distribution. + + Refer to the documentation of the generator types for the meaning + of this value. + + @deprecated: Use the L{para2} attribute instead. + @rtype: float + """ + def getDistribution(): + """ + Returns the type of random distribution. + + @deprecated: Use the L{distribution} attribute instead. + @rtype: distribution type + @return: KX_RANDOMACT_BOOL_CONST, KX_RANDOMACT_BOOL_UNIFORM, KX_RANDOMACT_BOOL_BERNOUILLI, + KX_RANDOMACT_INT_CONST, KX_RANDOMACT_INT_UNIFORM, KX_RANDOMACT_INT_POISSON, + KX_RANDOMACT_FLOAT_CONST, KX_RANDOMACT_FLOAT_UNIFORM, KX_RANDOMACT_FLOAT_NORMAL, + KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL + """ + def setProperty(property): + """ + Set the property to which the random value is assigned. + + If the generator and property types do not match, the assignment is ignored. + + @deprecated: Use the L{propName} attribute instead. + @type property: string + @param property: The name of the property to set. + """ + def getProperty(): + """ + Returns the name of the property to set. + + @deprecated: Use the L{propName} attribute instead. + @rtype: string + """ +#} + class SCA_RandomSensor(SCA_ISensor): """ diff --git a/source/gameengine/PyDoc/bge_api_validate_py.txt b/source/gameengine/PyDoc/bge_api_validate_py.txt index ec92cc28770..ebd74c06bb3 100644 --- a/source/gameengine/PyDoc/bge_api_validate_py.txt +++ b/source/gameengine/PyDoc/bge_api_validate_py.txt @@ -51,7 +51,11 @@ if doc_dir not in sys.path: def check_attribute(class_ob, member): - for l in class_ob.__doc__.split('\n'): + doc = class_ob.__doc__ + if not doc: + return False + + for l in doc.split('\n'): l = l.strip() ''' @@ -130,4 +134,3 @@ for mod_name, pymod in mods_dict.iteritems(): sys.path.pop() # remove the pydoc dir from our import paths - From 009dea9577620d2ff0d0c95f0b4104237dea1abe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 15 May 2009 12:34:01 +0000 Subject: [PATCH 245/444] Bug/patch #18714: fix game engine sound on OS X Intel, patch by Ken Hursh and myself. * Get rid of dependency on ALUT. It is really only used to load a WAV file, and apparently crashing doing so on OS X Intel, (perhaps due to endian issues?). There was already own code for doing this on some system, so now it uses that. That code had it's own endian issues which are now fixed, along with better checks to avoid crashing on corrupt or unsupported files. * Also get rid of some unecessarily complicate #ifdefs. * According to the bug report OS X Intel OpenAL only works with static openal linking still (WITH_BF_STATICOPENAL for scons). --- config/irix6-config.py | 5 - config/linux2-config.py | 5 - .../SoundSystem/openal/SND_OpenALDevice.cpp | 300 ++++++++++-------- 3 files changed, 175 insertions(+), 135 deletions(-) diff --git a/config/irix6-config.py b/config/irix6-config.py index 2c57a2bba8a..e4c989952cf 100644 --- a/config/irix6-config.py +++ b/config/irix6-config.py @@ -24,11 +24,6 @@ BF_OPENAL_LIB = 'openal' BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' BF_OPENAL_LIBPATH = LIBDIR + '/lib' -# some distros have a separate libalut -# if you get linker complaints, you need to uncomment the line below -# BF_OPENAL_LIB = 'openal alut' -# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a' - BF_CXX = '/usr' WITH_BF_STATICCXX = 'false' BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a' diff --git a/config/linux2-config.py b/config/linux2-config.py index 6d207dc40e6..b0ff0b89d3d 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -28,11 +28,6 @@ BF_OPENAL_INC = '${BF_OPENAL}/include' BF_OPENAL_LIB = 'openal' BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' -# some distros have a separate libalut -# if you get linker complaints, you need to uncomment the line below -# BF_OPENAL_LIB = 'openal alut' -# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a' - BF_CXX = '/usr' WITH_BF_STATICCXX = False BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a' diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp index 3649cf6de5a..df02d11ae39 100644 --- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp +++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp @@ -43,11 +43,9 @@ #ifdef APPLE_FRAMEWORK_FIX #include #include -#include #else #include #include -#include #endif #include @@ -61,13 +59,12 @@ #include -/* untill openal gets unified we need this hack for non-windows systems */ -#if !defined(WIN32) && !defined(ALC_MAJOR_VERSION) +/*************************** ALUT replacement *****************************/ -#include +/* instead of relying on alut, we just implement our own + * WAV loading functions, hopefully more reliable */ -ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop); -ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq); +#include typedef struct /* WAV File-header */ { @@ -120,93 +117,189 @@ typedef struct /* WAV Chunk-header */ ALuint Size; } WAVChunkHdr_Struct; -ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop) +static void *SND_loadFileIntoMemory(const char *filename, int *len_r) +{ + FILE *fp= fopen(filename, "rb"); + void *data; + + if (!fp) { + *len_r= -1; + return NULL; + } + + fseek(fp, 0L, SEEK_END); + *len_r= ftell(fp); + fseek(fp, 0L, SEEK_SET); + + data= malloc(*len_r); + if (!data) { + *len_r= -1; + return NULL; + } + + if (fread(data, *len_r, 1, fp)!=1) { + *len_r= -1; + free(data); + return NULL; + } + + return data; +} + +#define TEST_SWITCH_INT(a) if(big_endian) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \ + s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; } + +#define TEST_SWITCH_SHORT(a) if(big_endian) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; } + +static int stream_read(void *out, ALbyte **stream, ALsizei size, ALsizei *memsize) +{ + if(size <= *memsize) { + memcpy(out, *stream, size); + return 1; + } + else { + memset(out, 0, size); + return 0; + } +} + +static int stream_skip(ALbyte **stream, ALsizei size, ALsizei *memsize) +{ + if(size <= *memsize) { + *stream += size; + *memsize -= size; + return 1; + } + else + return 0; +} + +ALvoid SND_alutLoadWAVMemory(ALbyte *memory,ALsizei memsize,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop) { WAVChunkHdr_Struct ChunkHdr; WAVFmtExHdr_Struct FmtExHdr; WAVFileHdr_Struct FileHdr; WAVSmplHdr_Struct SmplHdr; WAVFmtHdr_Struct FmtHdr; - ALbyte *Stream; + ALbyte *Stream= memory; + int test_endian= 1; + int big_endian= !((char*)&test_endian)[0]; *format=AL_FORMAT_MONO16; *data=NULL; *size=0; *freq=22050; *loop=AL_FALSE; - if (memory) + + if(!Stream) + return; + + stream_read(&FileHdr,&Stream,sizeof(WAVFileHdr_Struct),&memsize); + stream_skip(&Stream,sizeof(WAVFileHdr_Struct),&memsize); + + TEST_SWITCH_INT(FileHdr.Size); + FileHdr.Size=((FileHdr.Size+1)&~1)-4; + + while((FileHdr.Size!=0) && stream_read(&ChunkHdr,&Stream,sizeof(WAVChunkHdr_Struct),&memsize)) { - Stream=memory; - if (Stream) + TEST_SWITCH_INT(ChunkHdr.Size); + stream_skip(&Stream,sizeof(WAVChunkHdr_Struct),&memsize); + + if (!memcmp(ChunkHdr.Id,"fmt ",4)) { - memcpy(&FileHdr,Stream,sizeof(WAVFileHdr_Struct)); - Stream+=sizeof(WAVFileHdr_Struct); - FileHdr.Size=((FileHdr.Size+1)&~1)-4; - while ((FileHdr.Size!=0)&&(memcpy(&ChunkHdr,Stream,sizeof(WAVChunkHdr_Struct)))) + stream_read(&FmtHdr,&Stream,sizeof(WAVFmtHdr_Struct),&memsize); + + TEST_SWITCH_SHORT(FmtHdr.Format); + TEST_SWITCH_SHORT(FmtHdr.Channels); + TEST_SWITCH_INT(FmtHdr.SamplesPerSec); + TEST_SWITCH_INT(FmtHdr.BytesPerSec); + TEST_SWITCH_SHORT(FmtHdr.BlockAlign); + TEST_SWITCH_SHORT(FmtHdr.BitsPerSample); + + if (FmtHdr.Format==0x0001) { - Stream+=sizeof(WAVChunkHdr_Struct); - if (!memcmp(ChunkHdr.Id,"fmt ",4)) - { - memcpy(&FmtHdr,Stream,sizeof(WAVFmtHdr_Struct)); - if (FmtHdr.Format==0x0001) - { - *format=(FmtHdr.Channels==1? - (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16): - (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16)); - *freq=FmtHdr.SamplesPerSec; - Stream+=ChunkHdr.Size; - } - else - { - memcpy(&FmtExHdr,Stream,sizeof(WAVFmtExHdr_Struct)); - Stream+=ChunkHdr.Size; - } - } - else if (!memcmp(ChunkHdr.Id,"data",4)) - { - if (FmtHdr.Format==0x0001) - { - *size=ChunkHdr.Size; - *data=malloc(ChunkHdr.Size+31); - if (*data) memcpy(*data,Stream,ChunkHdr.Size); - memset(((char *)*data)+ChunkHdr.Size,0,31); - Stream+=ChunkHdr.Size; - } - else if (FmtHdr.Format==0x0011) - { - //IMA ADPCM - } - else if (FmtHdr.Format==0x0055) - { - //MP3 WAVE - } - } - else if (!memcmp(ChunkHdr.Id,"smpl",4)) - { - memcpy(&SmplHdr,Stream,sizeof(WAVSmplHdr_Struct)); - *loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE); - Stream+=ChunkHdr.Size; - } - else Stream+=ChunkHdr.Size; - Stream+=ChunkHdr.Size&1; - FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8); + *format=(FmtHdr.Channels==1? + (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16): + (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16)); + *freq=FmtHdr.SamplesPerSec; + } + else + { + stream_read(&FmtExHdr,&Stream,sizeof(WAVFmtExHdr_Struct),&memsize); + TEST_SWITCH_SHORT(FmtExHdr.Size); + TEST_SWITCH_SHORT(FmtExHdr.SamplesPerBlock); } } + else if (!memcmp(ChunkHdr.Id,"data",4)) + { + if (FmtHdr.Format==0x0001) + { + if((ALsizei)ChunkHdr.Size <= memsize) + { + *size=ChunkHdr.Size; + *data=malloc(ChunkHdr.Size+31); + + if (*data) { + stream_read(*data,&Stream,ChunkHdr.Size,&memsize); + memset(((char *)*data)+ChunkHdr.Size,0,31); + + if(FmtHdr.BitsPerSample == 16 && big_endian) { + int a, len= *size/2; + short *samples= (short*)*data; + + for(a=0; aGetBuffer(); void* data = NULL; -#ifndef __APPLE__ char loop = 'a'; -#endif int sampleformat, bitrate, numberofchannels; ALenum al_error = alGetError(); - -#ifdef OUDE_OPENAL - ALsizei samplerate, numberofsamples; // openal_2.12 -#else - int samplerate, numberofsamples; // openal_2.14+ -#endif + ALsizei samplerate, numberofsamples; // openal_2.14+ /* Give them some safe defaults just incase */ bitrate = numberofchannels = 0; + if (!(size && memlocation)) { + memlocation = SND_loadFileIntoMemory(samplename.Ptr(), &size); + freemem = true; + } + /* load the sample from memory? */ if (size && memlocation) { @@ -437,33 +514,14 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, bitrate = SND_GetBitRate(memlocation); /* load the sample into openal */ -#if defined(OUDE_OPENAL) || defined (__APPLE__) - alutLoadWAVMemory((char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate); // openal_2.12 -#else -#ifdef AL_VERSION_1_1 - float frequency = 0.0f; - data = alutLoadMemoryFromFileImage(memlocation, size, &sampleformat, &numberofsamples, &frequency); - samplerate = (int)frequency; -#else - alutLoadWAVMemory((signed char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+ - -#endif -#endif - /* put it in the buffer */ - alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate); - } - /* or from file? */ - else - { -#ifdef __APPLE__ - alutLoadWAVFile((ALbyte *)samplename.Ptr(), &sampleformat, &data, &numberofsamples, &samplerate); -#else - alutLoadWAVFile((ALbyte *)samplename.Ptr(), &sampleformat, &data, &numberofsamples, &samplerate, &loop); -#endif + SND_alutLoadWAVMemory((char*)memlocation, size, &sampleformat, &data, &numberofsamples, &samplerate, &loop); /* put it in the buffer */ alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate); } + if(freemem) + free(memlocation); + /* fill the waveslot with info */ al_error = alGetError(); if (al_error == AL_NO_ERROR && m_buffers[buffer]) @@ -486,11 +544,7 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, } /* and free the original stuff (copy was made in openal) */ -#if defined(OUDE_OPENAL) || defined (__APPLE__) || !defined(AL_VERSION_1_1) - alutUnloadWAV(sampleformat, data, numberofsamples, samplerate); -#else - free(data); -#endif + SND_alutUnloadWAV(sampleformat, data, numberofsamples, samplerate); } } else @@ -591,11 +645,7 @@ int SND_OpenALDevice::GetPlayState(int id) int alstate = 0; int result = 0; -#ifdef __APPLE__ alGetSourcei(m_sources[id], AL_SOURCE_STATE, &alstate); -#else - alGetSourceiv(m_sources[id], AL_SOURCE_STATE, &alstate); -#endif switch(alstate) { From 58db6df0696ab066b1cf4b37f4593fa03f65e099 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 15 May 2009 18:21:27 +0000 Subject: [PATCH 246/444] * Fix for compile error on MSVC. * Remove alut from makefiles and cmake. --- CMakeLists.txt | 14 -------------- intern/SoundSystem/openal/SND_OpenALDevice.cpp | 2 +- source/Makefile | 8 -------- 3 files changed, 1 insertion(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1340ec0f3b9..9ebbf1fbb54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,20 +99,6 @@ IF(UNIX) ENDIF(OPENAL_FOUND) ENDIF(WITH_OPENAL) - FIND_LIBRARY(ALUT_LIBRARY - NAMES alut - PATHS - /usr/local/lib - /usr/lib - /sw/lib - /opt/local/lib - /opt/csw/lib - /opt/lib - ) - IF(ALUT_LIBRARY) - SET(OPENAL_LIB ${OPENAL_LIB} ${ALUT_LIBRARY}) - ENDIF(ALUT_LIBRARY) - FIND_LIBRARY(INTL_LIBRARY NAMES intl PATHS diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp index df02d11ae39..6b0e863e73d 100644 --- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp +++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp @@ -514,7 +514,7 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, bitrate = SND_GetBitRate(memlocation); /* load the sample into openal */ - SND_alutLoadWAVMemory((char*)memlocation, size, &sampleformat, &data, &numberofsamples, &samplerate, &loop); + SND_alutLoadWAVMemory((ALbyte*)memlocation, size, &sampleformat, &data, &numberofsamples, &samplerate, &loop); /* put it in the buffer */ alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate); } diff --git a/source/Makefile b/source/Makefile index 7374ef3e7d6..d06105a0b9b 100644 --- a/source/Makefile +++ b/source/Makefile @@ -363,8 +363,6 @@ else NAN_SND_LIBS += $(OPENALSOUND) NAN_SND_LIBS += $(SDLSOUND) NAN_SND_LIBS += $(NAN_OPENAL)/lib/libopenal.a - ALUT = $(wildcard $(NAN_OPENAL)/lib/libalut.a) - NAN_SND_LIBS += $(ALUT) NAN_SND_LIBS += $(SOUNDSYSTEM) else ifeq ($(OS),windows) @@ -373,8 +371,6 @@ else NAN_SND_LIBS += $(OPENALSOUND) NAN_SND_LIBS += $(SDLSOUND) NAN_SND_LIBS += $(NAN_OPENAL)/lib/openal_static.lib - ALUT = $(wildcard $(NAN_OPENAL)/lib/alut_static.lib) - NAN_SND_LIBS += $(ALUT) NAN_SND_LIBS += $(SOUNDSYSTEM) else NAN_SND_LIBS = $(SOUNDSYSTEM) @@ -388,8 +384,6 @@ else NAN_SND_LIBS += $(DUMMYSOUND) NAN_SND_LIBS += $(OPENALSOUND) NAN_SND_LIBS += $(NAN_OPENAL)/lib/libopenal.a - ALUT = $(wildcard $(NAN_OPENAL)/lib/libalut.a) - NAN_SND_LIBS += $(ALUT) NAN_SND_LIBS += $(SOUNDSYSTEM) else ifeq ($(OS), solaris) @@ -398,8 +392,6 @@ else NAN_SND_LIBS += $(OPENALSOUND) NAN_SND_LIBS += $(SDLSOUND) NAN_SND_LIBS += $(NAN_OPENAL)/lib/libopenal.a - ALUT = $(wildcard $(NAN_OPENAL)/lib/libalut.a) - NAN_SND_LIBS += $(ALUT) NAN_SND_LIBS += $(SOUNDSYSTEM) else ifeq ($(OS), irix) From ef8f92ffe63d76ec40d28f31660b22e12e4650be Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 15 May 2009 20:51:32 +0000 Subject: [PATCH 247/444] BGE: fix a compatibility problem since logic patch with YoFrankie (and other games I guess). State actuators will now execute before any other actuators to make sure that the actuators link count are up to date when they execute. --- source/gameengine/GameLogic/SCA_IActuator.cpp | 21 ++++++++++++++++ source/gameengine/GameLogic/SCA_IActuator.h | 19 ++------------ .../gameengine/GameLogic/SCA_LogicManager.cpp | 10 -------- .../gameengine/GameLogic/SCA_LogicManager.h | 9 ++++++- source/gameengine/Ketsji/KX_StateActuator.cpp | 25 +++++++++++++++++++ source/gameengine/Ketsji/KX_StateActuator.h | 4 +++ 6 files changed, 60 insertions(+), 28 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index 5f71bb3f9e4..c2be36d5108 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -58,6 +58,27 @@ bool SCA_IActuator::Update() return false; } +void SCA_IActuator::Activate(SG_DList& head) +{ + if (QEmpty()) + { + InsertActiveQList(m_gameobj->m_activeActuators); + head.AddBack(&m_gameobj->m_activeActuators); + } +} + +void SCA_IActuator::Deactivate() +{ + if (QDelink()) + { + // the actuator was in the active list + if (m_gameobj->m_activeActuators.QEmpty()) + // the owner object has no more active actuators, remove it from the global list + m_gameobj->m_activeActuators.Delink(); + } +} + + void SCA_IActuator::ProcessReplica() { SCA_ILogicBrick::ProcessReplica(); diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 3055e1d946f..2bd92c343b9 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -118,23 +118,8 @@ public: /** * remove this actuator from the list of active actuators */ - void Deactivate() - { - if (QDelink()) - // the actuator was in the active list - if (m_gameobj->m_activeActuators.QEmpty()) - // the owner object has no more active actuators, remove it from the global list - m_gameobj->m_activeActuators.Delink(); - } - - void Activate(SG_DList& head) - { - if (QEmpty()) - { - InsertActiveQList(m_gameobj->m_activeActuators); - head.AddBack(&m_gameobj->m_activeActuators); - } - } + virtual void Deactivate(); + virtual void Activate(SG_DList& head); void LinkToController(SCA_IController* controller); void UnlinkController(class SCA_IController* cont); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index 74370f89cf2..7acec465921 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -312,16 +312,6 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I } } - -void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,bool event) -{ - actua->SetActive(true); - actua->Activate(m_activeActuators); - actua->AddEvent(event); -} - - - SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype) { // find an eventmanager of a certain type diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index 0d610c9cc46..fe7b40b3ba4 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -65,6 +65,7 @@ typedef std::map sensormap_t; */ #include "SCA_ILogicBrick.h" +#include "SCA_IActuator.h" class SCA_LogicManager @@ -103,7 +104,13 @@ public: void BeginFrame(double curtime, double fixedtime); void UpdateFrame(double curtime, bool frame); void EndFrame(); - void AddActiveActuator(SCA_IActuator* sensor,bool event); + void AddActiveActuator(SCA_IActuator* actua,bool event) + { + actua->SetActive(true); + actua->Activate(m_activeActuators); + actua->AddEvent(event); + } + void AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor); SCA_EventManager* FindEventManager(int eventmgrtype); diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index 2cbb42b3311..5f9730d7e10 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -55,6 +55,9 @@ KX_StateActuator::~KX_StateActuator( // intentionally empty } +// used to put state actuator to be executed before any other actuators +SG_QList KX_StateActuator::m_stateActuatorHead; + CValue* KX_StateActuator::GetReplica( void @@ -99,6 +102,28 @@ KX_StateActuator::Update() return false; } +void KX_StateActuator::Deactivate() +{ + if (QDelink()) + { + // the actuator was in the active list + if (m_stateActuatorHead.QEmpty()) + // no more state object active + m_stateActuatorHead.Delink(); + } +} + +void KX_StateActuator::Activate(SG_DList& head) +{ + // no need to sort the state actuators + if (m_stateActuatorHead.QAddBack(this)) + { + // add front to make sure it runs before other actuators + head.AddFront(&m_stateActuatorHead); + } +} + + /* ------------------------------------------------------------------------- */ /* Python functions */ /* ------------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index 7e7056bd6af..57303ad403f 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -46,6 +46,7 @@ class KX_StateActuator : public SCA_IActuator OP_NEG, OP_COUNT }; + static SG_QList m_stateActuatorHead; int m_operation; int m_mask; @@ -71,6 +72,9 @@ class KX_StateActuator : public SCA_IActuator virtual bool Update(); + virtual void Deactivate(); + virtual void Activate(SG_DList& head); + /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ From 83006e51f845b2c5c36539373e036be3efaddc16 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Fri, 15 May 2009 21:27:13 +0000 Subject: [PATCH 248/444] Scripts ------- Fix some typos in script tooltips and descriptions-- no code changes. --- release/scripts/envelope_symmetry.py | 2 +- release/scripts/import_web3d.py | 2 +- release/scripts/mesh_mirror_tool.py | 8 ++++---- release/scripts/mesh_poly_reduce_grid.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/release/scripts/envelope_symmetry.py b/release/scripts/envelope_symmetry.py index a52e622a65b..a72e8c060b4 100644 --- a/release/scripts/envelope_symmetry.py +++ b/release/scripts/envelope_symmetry.py @@ -4,7 +4,7 @@ Name: 'Envelope Symmetry' Blender: 234 Group: 'Animation' -Tooltip: 'Make envelope symetrical' +Tooltip: 'Make envelope symmetrical' """ __author__ = "Jonas Petersen" diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py index fc3b5262376..a5547506dc7 100644 --- a/release/scripts/import_web3d.py +++ b/release/scripts/import_web3d.py @@ -85,7 +85,7 @@ def imageConvertCompat(path): def vrmlFormat(data): ''' - Keep this as a valid vrml file, but format in a way we can pradict. + Keep this as a valid vrml file, but format in a way we can predict. ''' # Strip all commends - # not in strings - warning multiline strings are ignored. def strip_comment(l): diff --git a/release/scripts/mesh_mirror_tool.py b/release/scripts/mesh_mirror_tool.py index 33ce6936c7f..8e22e26cd53 100644 --- a/release/scripts/mesh_mirror_tool.py +++ b/release/scripts/mesh_mirror_tool.py @@ -3,7 +3,7 @@ Name: 'Mirror Vertex Locations & Weight' Blender: 241 Group: 'Mesh' -Tooltip: 'Snap Verticies to X mirrord locations and weights.' +Tooltip: 'Snap Verticies to X mirrored locations and weights.' """ __author__ = "Campbell Barton aka ideasman42" @@ -11,11 +11,11 @@ __url__ = ["www.blender.org", "blenderartists.org", "www.python.org"] __version__= '1.0' __bpydoc__= '''\ This script is used to mirror vertex locations and weights -It is usefull if you have a model that was made symetrical +It is useful if you have a model that was made symmetrical but has verts that have moved from their mirrored locations slightly, -casuing blenders X-Mirror options not to work. +causing blenders X-Mirror options not to work. -Weights can be mirrored too, this is usefull if you want to model 1 side of a mesh, copy the mesh and flip it. +Weights can be mirrored too, this is useful if you want to model 1 side of a mesh, copy the mesh and flip it. You can then use this script to mirror to the copy, even creating new flipped vertex groups, renaming group name left to right or .L to .R Vertex positions are mirrored by doing a locational lookup, diff --git a/release/scripts/mesh_poly_reduce_grid.py b/release/scripts/mesh_poly_reduce_grid.py index 3741a47723a..2903909027a 100644 --- a/release/scripts/mesh_poly_reduce_grid.py +++ b/release/scripts/mesh_poly_reduce_grid.py @@ -3,7 +3,7 @@ Name: 'Poly Reduce Selection (Unsubsurf)' Blender: 245 Group: 'Mesh' -Tooltip: 'pradictable mesh simplifaction maintaining face loops' +Tooltip: 'predictable mesh simplifaction maintaining face loops' """ from Blender import Scene, Mesh, Window, sys @@ -50,7 +50,7 @@ def my_mesh_util(me): for edkey, count in edge_count.iteritems(): - # Ignore verts that connect to edges with more then 2 faces. + # Ignore verts that connect to edges with more than 2 faces. if count != 2: vert_faces[edkey[0]] = None vert_faces[edkey[1]] = None From 006ad4aaacc36a7e7fd1a8cd96e60a5e74cbfedd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 16 May 2009 00:49:28 +0000 Subject: [PATCH 249/444] BGE Py API Bugfixes KX_GameObject.getVelocity() would set an error but nor return an error value when an non vector argument was given. KX_PythonSeq_Type was not initialized with PyType_Ready which could crash blender when inspecting the type. --- source/gameengine/Ketsji/KX_GameObject.cpp | 8 +------- source/gameengine/Ketsji/KX_PythonInitTypes.cpp | 4 ++++ source/gameengine/PyDoc/GameTypes.py | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 9196d1e0527..ae30aeb971c 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -2051,14 +2051,8 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* args) MT_Point3 point(0.0,0.0,0.0); PyObject* pypos = NULL; - if (PyArg_ParseTuple(args, "|O:getVelocity", &pypos)) - { - if (pypos) - PyVecTo(pypos, point); - } - else { + if (!PyArg_ParseTuple(args, "|O:getVelocity", &pypos) || (pypos && !PyVecTo(pypos, point))) return NULL; - } if (m_pPhysicsController1) { diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index cd21663f41d..83c4dcbb34c 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -51,6 +51,7 @@ #include "KX_PhysicsObjectWrapper.h" #include "KX_PolyProxy.h" #include "KX_PolygonMaterial.h" +#include "KX_PythonSeq.h" #include "KX_SCA_AddObjectActuator.h" #include "KX_SCA_EndObjectActuator.h" #include "KX_SCA_ReplaceMeshActuator.h" @@ -227,6 +228,9 @@ void initPyTypes(void) PyType_Ready_Attr(dict, SCA_XNORController); PyType_Ready_Attr(dict, SCA_XORController); PyType_Ready_Attr(dict, SCA_IController); + + /* Normal python type */ + PyType_Ready(&KX_PythonSeq_Type); } #endif \ No newline at end of file diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index d58f9087a9f..b5b0839c0f4 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -5544,7 +5544,7 @@ class KX_Camera(KX_GameObject): """ import types attrs = [] -for name, val in __builtins__.locals().items(): +for name, val in locals().items(): if name.startswith('__'): continue if type(val) == types.ClassType: @@ -5554,4 +5554,4 @@ for name, val in __builtins__.locals().items(): for a in attrs: print a -""" \ No newline at end of file +""" From b063d2f6212d181a9a766b2e1138336a11519463 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 16 May 2009 06:57:38 +0000 Subject: [PATCH 250/444] replace Py_BuildValue("OOO", Py_None, Py_None, Py_None) with a function that makes and fills the tuple, since some scripts call rayCast many times in a single logic tick, contrived benchmark shows this to be about 20% faster. --- source/gameengine/Ketsji/KX_GameObject.cpp | 40 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index ae30aeb971c..79519bfb491 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -2509,6 +2509,34 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, Py_RETURN_NONE; } +/* faster then Py_BuildValue since some scripts call raycast a lot */ +static PyObject *none_tuple_3() +{ + PyObject *ret= PyTuple_New(3); + PyTuple_SET_ITEM(ret, 0, Py_None); + PyTuple_SET_ITEM(ret, 1, Py_None); + PyTuple_SET_ITEM(ret, 2, Py_None); + + Py_INCREF(Py_None); + Py_INCREF(Py_None); + Py_INCREF(Py_None); + return ret; +} +static PyObject *none_tuple_4() +{ + PyObject *ret= PyTuple_New(4); + PyTuple_SET_ITEM(ret, 0, Py_None); + PyTuple_SET_ITEM(ret, 1, Py_None); + PyTuple_SET_ITEM(ret, 2, Py_None); + PyTuple_SET_ITEM(ret, 3, Py_None); + + Py_INCREF(Py_None); + Py_INCREF(Py_None); + Py_INCREF(Py_None); + Py_INCREF(Py_None); + return ret; +} + KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, "rayCast(to,from,dist,prop,face,xray,poly): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) of contact point with object within dist that matches prop.\n" " If no hit, return (None,None,None) or (None,None,None,None).\n" @@ -2576,12 +2604,14 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, if (dist != 0.0f) { MT_Vector3 toDir = toPoint-fromPoint; if (MT_fuzzyZero(toDir.length2())) { - return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + //return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + return none_tuple_3(); } toDir.normalize(); toPoint = fromPoint + (dist) * toDir; } else if (MT_fuzzyZero((toPoint-fromPoint).length2())) { - return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + //return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + return none_tuple_3(); } PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment(); @@ -2629,9 +2659,11 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, } // no hit if (poly) - return Py_BuildValue("OOOO", Py_None, Py_None, Py_None, Py_None); + //return Py_BuildValue("OOOO", Py_None, Py_None, Py_None, Py_None); + return none_tuple_4(); else - return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + //return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + return none_tuple_3(); } KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage, From 0f933eb84796d46debc7c19ae33c28f6f9c411cc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 16 May 2009 12:56:09 +0000 Subject: [PATCH 251/444] * Fix for another OpenAL compile error on MSVC. --- intern/SoundSystem/openal/SND_OpenALDevice.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp index 6b0e863e73d..424a05246ac 100644 --- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp +++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp @@ -645,7 +645,11 @@ int SND_OpenALDevice::GetPlayState(int id) int alstate = 0; int result = 0; +#ifdef __APPLE__ alGetSourcei(m_sources[id], AL_SOURCE_STATE, &alstate); +#else + alGetSourceiv(m_sources[id], AL_SOURCE_STATE, &alstate); +#endif switch(alstate) { From 10ed9a4f6456b32dae1fc5693a2319e8c2ad9692 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 16 May 2009 13:19:23 +0000 Subject: [PATCH 252/444] setting up the BGE Python sys.path for importing modules wasnt working for library paths. --- source/gameengine/Ketsji/KX_PythonInit.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 57f736a6c09..d32f3b1b8a2 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1611,13 +1611,15 @@ static void backupPySysPath(void) static void initPySysPath__append(PyObject *sys_path, char *filename) { PyObject *item; - char expanded[FILE_MAXDIR + FILE_MAXFILE] = "//"; + char expanded[FILE_MAXDIR + FILE_MAXFILE]; - BLI_convertstringcode(expanded, filename); + BLI_split_dirfile_basic(filename, expanded, NULL); /* get the dir part of filename only */ + BLI_convertstringcode(expanded, gp_GamePythonPath); item= PyString_FromString(expanded); if(PySequence_Index(sys_path, item) == -1) { + PyErr_Clear(); /* PySequence_Index sets a ValueError */ PyList_Insert(sys_path, 0, item); } From d1f71a34564bc594d1d2f2641459c24c70ba8fec Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sat, 16 May 2009 21:16:04 +0000 Subject: [PATCH 253/444] Bugfix: Changing ShadowBufferSize didn't update 3d view - reported by nudelZ via IRC (simple update call was missing) --- source/blender/src/buttons_shading.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index a129698cce3..79f95d1bf5f 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2447,7 +2447,8 @@ void do_lampbuts(unsigned short event) break; case B_SBUFF: la= G.buts->lockpoin; - la->bufsize = la->bufsize&=(~15); + la->bufsize = la->bufsize&=(~15); + BIF_preview_changed(ID_LA); allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWOOPS, 0); break; From cd3e447bb88ab72508fd7fc3b3221c6f42312905 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 16 May 2009 23:47:17 +0000 Subject: [PATCH 254/444] Same tooltip whether snap button is press or not (it used to have a different one when turned on). --- source/blender/src/header_view3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 6d72e434e67..cee20a57462 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -5848,7 +5848,7 @@ void view3d_buttons(void) uiBlockBeginAlign(block); if (G.scene->snap_flag & SCE_SNAP) { - uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)"); + uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)"); xco+= XIC; uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target"); xco+= XIC; From 6dad6bb9bf3a280b228cbd04d9180a35534afefb Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 17 May 2009 09:56:48 +0000 Subject: [PATCH 255/444] Bugfix #18756 Texture nodes: on file load, the preview render signal was ignored. Found out it ignores it all the way, inserting refreshes all over, not using the 'afterqueue'. Will live with that for now, in 2.5 it's nicer supported anyway. Just added another refresh line on the proper signal to make it look nice on file loads. --- source/blender/src/editnode.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index f0046a960e9..cfda82c055e 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -180,7 +180,7 @@ static void snode_handle_recalc(SpaceNode *snode) allqueue(REDRAWNODE, 1); } else if(snode->treetype==NTREE_TEXTURE) { - ntreeTexUpdatePreviews(snode->nodetree); + ntreeTexUpdatePreviews(snode->nodetree);/* XXX texture nodes should follow shader node methods (ton) */ BIF_preview_changed(ID_TE); } } @@ -550,7 +550,7 @@ void node_texture_default(Tex *tx) nodeAddLink(tx->nodetree, in, fromsock, out, tosock); ntreeSolveOrder(tx->nodetree); /* needed for pointers */ - ntreeTexUpdatePreviews(tx->nodetree); + ntreeTexUpdatePreviews(tx->nodetree);/* XXX texture nodes should follow shader node methods (ton) */ } /* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */ @@ -1301,7 +1301,7 @@ static void scale_node(SpaceNode *snode, bNode *node) allqueue(REDRAWNODE, 1); if(snode->nodetree->type == NTREE_TEXTURE) - ntreeTexUpdatePreviews(snode->nodetree); + ntreeTexUpdatePreviews(snode->nodetree);/* XXX texture nodes should follow shader node methods (ton) */ } /* ******************** rename ******************* */ @@ -1819,7 +1819,7 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy) if(snode->nodetree->type==NTREE_TEXTURE) { ntreeTexCheckCyclics(snode->edittree); - ntreeTexUpdatePreviews(snode->edittree); + ntreeTexUpdatePreviews(snode->edittree);/* XXX texture nodes should follow shader node methods (ton) */ } return node; @@ -2608,6 +2608,9 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) case RENDERPREVIEW: if(snode->treetype==NTREE_SHADER) shader_node_previewrender(sa, snode); + else if(snode->nodetree->type==NTREE_TEXTURE) + ntreeTexUpdatePreviews(snode->edittree); /* XXX texture nodes should follow shader node methods (ton) */ + break; case PADPLUSKEY: From d4116adf11678726a5af5f544a12b194ef2fbcb9 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 17 May 2009 10:30:13 +0000 Subject: [PATCH 256/444] Bugfix #18676 Texture "map to" Ambient did work now (previous fix) but not for ambient occlusion yet. --- source/blender/render/intern/source/shadeoutput.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 4c627056c1d..869cca0f7d0 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1007,9 +1007,9 @@ static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) /* pure AO, check for raytrace and world should have been done */ void ambient_occlusion(ShadeInput *shi) { - if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f) + if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->amb!=0.0f) sample_occ(&R, shi); - else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) + else if((R.r.mode & R_RAYTRACE) && shi->amb!=0.0f) ray_ao(shi, shi->ao); else shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f; @@ -1020,8 +1020,8 @@ void ambient_occlusion(ShadeInput *shi) void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff) { if((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX) { - if(shi->mat->amb!=0.0f) { - float f= R.wrld.aoenergy*shi->mat->amb; + if(shi->amb!=0.0f) { + float f= R.wrld.aoenergy*shi->amb; if (R.wrld.aomix==WO_AOADDSUB) { diff[0] = 2.0f*shi->ao[0]-1.0f; From 96aa60cee36dfb8a98501b6b9d4c88222b909c35 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 17 May 2009 12:25:06 +0000 Subject: [PATCH 257/444] cmake: apply ADD_SUBDIR patch. --- CMakeLists.txt | 12 +++---- extern/CMakeLists.txt | 15 +++++---- extern/bullet2/src/CMakeLists.txt | 5 ++- extern/verse/CMakeLists.txt | 2 +- extern/verse/dist/CMakeLists.txt | 2 +- intern/CMakeLists.txt | 17 ++++++++-- source/CMakeLists.txt | 7 ++-- source/blender/CMakeLists.txt | 25 +++++++++++--- source/blender/blenkernel/CMakeLists.txt | 2 +- source/blender/makesdna/CMakeLists.txt | 2 +- source/gameengine/CMakeLists.txt | 36 ++++++++++----------- source/gameengine/GamePlayer/CMakeLists.txt | 5 +-- 12 files changed, 79 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ebbf1fbb54..00d53282fed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -450,20 +450,18 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ") #----------------------------------------------------------------------------- # Libraries FILE(WRITE ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt "") -SUBDIRS( - intern - extern - source -) +ADD_SUBDIRECTORY(intern) +ADD_SUBDIRECTORY(extern) +ADD_SUBDIRECTORY(source) #----------------------------------------------------------------------------- # Blender Application -SUBDIRS(source/creator) +ADD_SUBDIRECTORY(source/creator) #----------------------------------------------------------------------------- # Blender Player IF(WITH_PLAYER) - SUBDIRS(blenderplayer) + ADD_SUBDIRECTORY(blenderplayer) ENDIF(WITH_PLAYER) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index b81efb52de9..eeb09491ce6 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -25,27 +25,28 @@ # ***** END GPL LICENSE BLOCK ***** IF(WITH_GAMEENGINE) - SUBDIRS(qhull solid) + ADD_SUBDIRECTORY(qhull) + ADD_SUBDIRECTORY(solid) ENDIF(WITH_GAMEENGINE) IF(WITH_BULLET) - SUBDIRS(bullet2) + ADD_SUBDIRECTORY(bullet2) ENDIF(WITH_BULLET) IF(WITH_INTERNATIONAL) - SUBDIRS(bFTGL) + ADD_SUBDIRECTORY(bFTGL) ENDIF(WITH_INTERNATIONAL) IF(WITH_VERSE) - SUBDIRS(verse) + ADD_SUBDIRECTORY(verse) ENDIF(WITH_VERSE) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SUBDIRS(binreloc) + ADD_SUBDIRECTORY(binreloc) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") -SUBDIRS(glew) +ADD_SUBDIRECTORY(glew) IF(WITH_OPENJPEG) - SUBDIRS(libopenjpeg) + ADD_SUBDIRECTORY(libopenjpeg) ENDIF(WITH_OPENJPEG) diff --git a/extern/bullet2/src/CMakeLists.txt b/extern/bullet2/src/CMakeLists.txt index 043fd3f6e7f..9b8a5a7e00e 100644 --- a/extern/bullet2/src/CMakeLists.txt +++ b/extern/bullet2/src/CMakeLists.txt @@ -1 +1,4 @@ -SUBDIRS( BulletCollision BulletDynamics LinearMath BulletSoftBody ) +ADD_SUBDIRECTORY(BulletCollision) +ADD_SUBDIRECTORY(BulletDynamics) +ADD_SUBDIRECTORY(LinearMath) +ADD_SUBDIRECTORY(BulletSoftBody ) diff --git a/extern/verse/CMakeLists.txt b/extern/verse/CMakeLists.txt index 318a550668e..90f727bbfdf 100644 --- a/extern/verse/CMakeLists.txt +++ b/extern/verse/CMakeLists.txt @@ -24,5 +24,5 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(dist) +ADD_SUBDIRECTORY(dist) diff --git a/extern/verse/dist/CMakeLists.txt b/extern/verse/dist/CMakeLists.txt index ae130df6410..f46099cb289 100644 --- a/extern/verse/dist/CMakeLists.txt +++ b/extern/verse/dist/CMakeLists.txt @@ -24,7 +24,7 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(mkprot_cmd) +ADD_SUBDIRECTORY(mkprot_cmd) SET(SRC_MKPROT_OUT v_gen_pack_init.c diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 81ef8c121d1..0858ec582a2 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -24,10 +24,21 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(SoundSystem string ghost guardedalloc bmfont moto container memutil decimation iksolver boolop opennl) +ADD_SUBDIRECTORY(SoundSystem) +ADD_SUBDIRECTORY(string) +ADD_SUBDIRECTORY(ghost) +ADD_SUBDIRECTORY(guardedalloc) +ADD_SUBDIRECTORY(bmfont) +ADD_SUBDIRECTORY(moto) +ADD_SUBDIRECTORY(container) +ADD_SUBDIRECTORY(memutil) +ADD_SUBDIRECTORY(decimation) +ADD_SUBDIRECTORY(iksolver) +ADD_SUBDIRECTORY(boolop) +ADD_SUBDIRECTORY(opennl) IF(WITH_ELBEEM) - SUBDIRS(elbeem) + ADD_SUBDIRECTORY(elbeem) ENDIF(WITH_ELBEEM) -SUBDIRS(bsp) +ADD_SUBDIRECTORY(bsp) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 04566ec3b0b..4764caddf6a 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -24,12 +24,13 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(blender kernel) +ADD_SUBDIRECTORY(blender) +ADD_SUBDIRECTORY(kernel) IF(WITH_GAMEENGINE) - SUBDIRS(gameengine) + ADD_SUBDIRECTORY(gameengine) ENDIF(WITH_GAMEENGINE) IF(WINDOWS) - SUBDIRS(icons) + ADD_SUBDIRECTORY(icons) ENDIF(WINDOWS) diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 007ee34e4e7..f65163ce26c 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -24,20 +24,35 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(avi nodes blenkernel blenlib blenloader blenpluginapi imbuf imbuf/intern/cineon gpu makesdna python radiosity readblenfile render src yafray) +ADD_SUBDIRECTORY(avi) +ADD_SUBDIRECTORY(nodes) +ADD_SUBDIRECTORY(blenkernel) +ADD_SUBDIRECTORY(blenlib) +ADD_SUBDIRECTORY(blenloader) +ADD_SUBDIRECTORY(blenpluginapi) +ADD_SUBDIRECTORY(imbuf) +ADD_SUBDIRECTORY(imbuf/intern/cineon) +ADD_SUBDIRECTORY(gpu) +ADD_SUBDIRECTORY(makesdna) +ADD_SUBDIRECTORY(python) +ADD_SUBDIRECTORY(radiosity) +ADD_SUBDIRECTORY(readblenfile) +ADD_SUBDIRECTORY(render) +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(yafray) IF(WITH_INTERNATIONAL) - SUBDIRS(ftfont) + ADD_SUBDIRECTORY(ftfont) ENDIF(WITH_INTERNATIONAL) IF(WITH_OPENEXR) - SUBDIRS(imbuf/intern/openexr) + ADD_SUBDIRECTORY(imbuf/intern/openexr) ENDIF(WITH_OPENEXR) IF(WITH_DDS) - SUBDIRS(imbuf/intern/dds) + ADD_SUBDIRECTORY(imbuf/intern/dds) ENDIF(WITH_DDS) IF(WITH_QUICKTIME) - SUBDIRS(quicktime) + ADD_SUBDIRECTORY(quicktime) ENDIF(WITH_QUICKTIME) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 27be1b45779..3a8058b2b21 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -66,7 +66,7 @@ IF(WITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(WITH_PLAYER) - SUBDIRS(bad_level_call_stubs) + ADD_SUBDIRECTORY(bad_level_call_stubs) ENDIF(WITH_PLAYER) BLENDERLIB(bf_blenkernel "${SRC}" "${INC}") diff --git a/source/blender/makesdna/CMakeLists.txt b/source/blender/makesdna/CMakeLists.txt index a1afa37e5e6..1f8ab831ba6 100644 --- a/source/blender/makesdna/CMakeLists.txt +++ b/source/blender/makesdna/CMakeLists.txt @@ -24,4 +24,4 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(intern) +ADD_SUBDIRECTORY(intern) diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt index 3ea788791e2..fd05858710d 100644 --- a/source/gameengine/CMakeLists.txt +++ b/source/gameengine/CMakeLists.txt @@ -24,25 +24,23 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS( - BlenderRoutines - Converter - Expressions - GameLogic - Ketsji - Ketsji/KXNetwork - Network - Network/LoopBackNetwork - Physics/common - Physics/Dummy - Rasterizer - Rasterizer/RAS_OpenGLRasterizer - SceneGraph - Physics/Bullet - Physics/Sumo - VideoTexture -) +ADD_SUBDIRECTORY(BlenderRoutines) +ADD_SUBDIRECTORY(Converter) +ADD_SUBDIRECTORY(Expressions) +ADD_SUBDIRECTORY(GameLogic) +ADD_SUBDIRECTORY(Ketsji) +ADD_SUBDIRECTORY(Ketsji/KXNetwork) +ADD_SUBDIRECTORY(Network) +ADD_SUBDIRECTORY(Network/LoopBackNetwork) +ADD_SUBDIRECTORY(Physics/common) +ADD_SUBDIRECTORY(Physics/Dummy) +ADD_SUBDIRECTORY(Rasterizer) +ADD_SUBDIRECTORY(Rasterizer/RAS_OpenGLRasterizer) +ADD_SUBDIRECTORY(SceneGraph) +ADD_SUBDIRECTORY(Physics/Bullet) +ADD_SUBDIRECTORY(Physics/Sumo) +ADD_SUBDIRECTORY(VideoTexture) IF(WITH_PLAYER) - SUBDIRS(GamePlayer) + ADD_SUBDIRECTORY(GamePlayer) ENDIF(WITH_PLAYER) diff --git a/source/gameengine/GamePlayer/CMakeLists.txt b/source/gameengine/GamePlayer/CMakeLists.txt index fc5912155cf..134f8fce3b2 100644 --- a/source/gameengine/GamePlayer/CMakeLists.txt +++ b/source/gameengine/GamePlayer/CMakeLists.txt @@ -24,8 +24,9 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(common ghost) +ADD_SUBDIRECTORY(common) +ADD_SUBDIRECTORY(ghost) IF(WITH_WEBPLUGIN) - SUBDIRS(xembed) + ADD_SUBDIRECTORY(xembed) ENDIF(WITH_WEBPLUGIN) From 3ea1c1b4b640b18e651de7eacb40bb7cc7a2f55f Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 17 May 2009 12:51:51 +0000 Subject: [PATCH 258/444] BGE: new sensor object to generalize Near and Radar sensor, static-static collision capbility. A new type of "Sensor" physics object is available in the GE for advanced collision management. It's called Sensor for its similarities with the physics objects that underlie the Near and Radar sensors. Like the Near and Radar object it is: - static and ghost - invisible by default - always active to ensure correct collision detection - capable of detecting both static and dynamic objects - ignoring collision with their parent - capable of broadphase filtering based on: * Actor option: the collisioning object must have the Actor flag set to be detected * property/material: as specified in the collision sensors attached to it Broadphase filtering is important for performance reason: the collision points will be computed only for the objects that pass the broahphase filter. - automatically removed from the simulation when no collision sensor is active on it Unlike the Near and Radar object it can: - take any shape, including triangle mesh - be made visible for debugging (just use the Visible actuator) - have multiple collision sensors using it Other than that, the sensor objects are ordinary objects. You can move them freely or parent them. When parented to a dynamic object, they can provide advanced collision control to this object. The type of collision capability depends on the shape: - box, sphere, cylinder, cone, convex hull provide volume detection. - triangle mesh provides surface detection but you can give some volume to the suface by increasing the margin in the Advanced Settings panel. The margin applies on both sides of the surface. Performance tip: - Sensor objects perform better than Near and Radar: they do less synchronizations because of the Scenegraph optimizations and they can have multiple collision sensors on them (with different property filtering for example). - Always prefer simple shape (box, sphere) to complex shape whenever possible. - Always use broadphase filtering (avoid collision sensor with empty propery/material) - Use collision sensor only when you need them. When no collision sensor is active on the sensor object, it is removed from the simulation and consume no CPU. Known limitations: - When running Blender in debug mode, you will see one warning line of the console: "warning btCollisionDispatcher::needsCollision: static-static collision!" In release mode this message is not printed. - Collision margin has no effect on sphere, cone and cylinder shape. Other performance improvements: - Remove unnecessary interpolation for Near and Radar objects and by extension sensor objects. - Use direct matrix copy instead of quaternion to synchronize orientation. Other bug fix: - Fix Near/Radar position error on newly activated objects. This was causing several detection problems in YoFrankie - Fix margin not passed correctly to gImpact shape. - Disable force/velocity actions on static objects --- source/blender/makesdna/DNA_object_types.h | 2 + source/blender/python/api2_2x/Object.c | 3 +- source/blender/src/buttons_logic.c | 82 ++++--- .../Converter/BL_BlenderDataConversion.cpp | 1 + source/gameengine/GameLogic/SCA_ISensor.h | 11 + .../Ketsji/KX_BulletPhysicsController.cpp | 24 ++- .../Ketsji/KX_BulletPhysicsController.h | 3 +- .../gameengine/Ketsji/KX_ClientObjectInfo.h | 5 +- .../Ketsji/KX_ConvertPhysicsObject.h | 1 + .../Ketsji/KX_ConvertPhysicsObjects.cpp | 54 +++-- source/gameengine/Ketsji/KX_GameObject.cpp | 26 ++- source/gameengine/Ketsji/KX_GameObject.h | 9 +- .../Ketsji/KX_IPhysicsController.cpp | 3 +- .../gameengine/Ketsji/KX_IPhysicsController.h | 12 +- source/gameengine/Ketsji/KX_MotionState.cpp | 5 + source/gameengine/Ketsji/KX_MotionState.h | 1 + source/gameengine/Ketsji/KX_NearSensor.cpp | 35 +-- source/gameengine/Ketsji/KX_NearSensor.h | 4 +- .../Ketsji/KX_OdePhysicsController.h | 1 + source/gameengine/Ketsji/KX_RadarSensor.cpp | 21 +- source/gameengine/Ketsji/KX_RadarSensor.h | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 4 +- .../Ketsji/KX_SumoPhysicsController.h | 3 +- .../Ketsji/KX_TouchEventManager.cpp | 34 ++- source/gameengine/Ketsji/KX_TouchSensor.cpp | 58 ++++- source/gameengine/Ketsji/KX_TouchSensor.h | 3 +- .../Physics/BlOde/OdePhysicsController.cpp | 5 +- .../Physics/BlOde/OdePhysicsController.h | 1 + .../Physics/BlOde/OdePhysicsEnvironment.h | 4 +- .../Physics/Bullet/CcdPhysicsController.cpp | 201 ++++++++++-------- .../Physics/Bullet/CcdPhysicsController.h | 14 +- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 87 ++------ .../Physics/Bullet/CcdPhysicsEnvironment.h | 4 +- .../Physics/Dummy/DummyPhysicsEnvironment.h | 4 +- .../Physics/Sumo/SumoPhysicsController.cpp | 5 + .../Physics/Sumo/SumoPhysicsController.h | 1 + .../Physics/Sumo/SumoPhysicsEnvironment.cpp | 7 +- .../Physics/Sumo/SumoPhysicsEnvironment.h | 4 +- .../Physics/common/PHY_IMotionState.h | 2 + .../Physics/common/PHY_IPhysicsController.h | 3 +- .../Physics/common/PHY_IPhysicsEnvironment.h | 4 +- source/gameengine/SceneGraph/SG_IObject.h | 7 + source/gameengine/SceneGraph/SG_Spatial.h | 7 + 43 files changed, 465 insertions(+), 302 deletions(-) diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 82da883df4a..9121f38be16 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -440,6 +440,7 @@ extern Object workob; #define OB_COLLISION 65536 #define OB_SOFT_BODY 0x20000 #define OB_OCCLUDER 0x40000 +#define OB_SENSOR 0x80000 /* ob->gameflag2 */ #define OB_NEVER_DO_ACTIVITY_CULLING 1 @@ -459,6 +460,7 @@ extern Object workob; #define OB_BODY_TYPE_RIGID 3 #define OB_BODY_TYPE_SOFT 4 #define OB_BODY_TYPE_OCCLUDER 5 +#define OB_BODY_TYPE_SENSOR 6 /* ob->scavisflag */ #define OB_VIS_SENS 1 diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 2de2906335f..c3f7a21a7bf 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -3562,7 +3562,7 @@ static int Object_setRBMass( BPy_Object * self, PyObject * args ) /* this is too low level, possible to add helper methods */ #define GAMEFLAG_MASK ( OB_OCCLUDER | OB_COLLISION | OB_DYNAMIC | OB_CHILD | OB_ACTOR | OB_DO_FH | \ - OB_ROT_FH | OB_ANISOTROPIC_FRICTION | OB_GHOST | OB_RIGID_BODY | OB_SOFT_BODY | \ + OB_ROT_FH | OB_ANISOTROPIC_FRICTION | OB_GHOST | OB_RIGID_BODY | OB_SOFT_BODY | OB_SENSOR | \ OB_BOUNDS | OB_COLLISION_RESPONSE | OB_SECTOR | OB_PROP | \ OB_MAINACTOR ) @@ -5544,6 +5544,7 @@ static PyObject *M_Object_RBFlagsDict( void ) BPy_constant *d = ( BPy_constant * ) M; PyConstant_Insert( d, "OCCLUDER", PyInt_FromLong( OB_OCCLUDER ) ); PyConstant_Insert( d, "COLLISION", PyInt_FromLong( OB_COLLISION ) ); + PyConstant_Insert( d, "SENSOR", PyInt_FromLong( OB_SENSOR ) ); PyConstant_Insert( d, "DYNAMIC", PyInt_FromLong( OB_DYNAMIC ) ); PyConstant_Insert( d, "CHILD", PyInt_FromLong( OB_CHILD ) ); PyConstant_Insert( d, "ACTOR", PyInt_FromLong( OB_ACTOR ) ); diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index dccbc73787d..a537d32feae 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3064,29 +3064,33 @@ static void check_body_type(void *arg1_but, void *arg2_object) Object *ob = arg2_object; switch (ob->body_type) { + case OB_BODY_TYPE_SENSOR: + ob->gameflag |= OB_SENSOR|OB_COLLISION|OB_GHOST; + ob->gameflag &= ~(OB_OCCLUDER|OB_DYNAMIC|OB_RIGID_BODY|OB_ACTOR|OB_ANISOTROPIC_FRICTION|OB_DO_FH|OB_ROT_FH|OB_COLLISION_RESPONSE); + break; case OB_BODY_TYPE_OCCLUDER: ob->gameflag |= OB_OCCLUDER; - ob->gameflag &= ~(OB_COLLISION|OB_DYNAMIC); + ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_DYNAMIC); break; case OB_BODY_TYPE_NO_COLLISION: - ob->gameflag &= ~(OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC); + ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC); break; case OB_BODY_TYPE_STATIC: ob->gameflag |= OB_COLLISION; - ob->gameflag &= ~(OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER); + ob->gameflag &= ~(OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR); break; case OB_BODY_TYPE_DYNAMIC: ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_ACTOR; - ob->gameflag &= ~(OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER); + ob->gameflag &= ~(OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR); break; case OB_BODY_TYPE_RIGID: ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_RIGID_BODY|OB_ACTOR; - ob->gameflag &= ~(OB_SOFT_BODY|OB_OCCLUDER); + ob->gameflag &= ~(OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR); break; default: case OB_BODY_TYPE_SOFT: ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_SOFT_BODY|OB_ACTOR; - ob->gameflag &= ~(OB_RIGID_BODY|OB_OCCLUDER); + ob->gameflag &= ~(OB_RIGID_BODY|OB_OCCLUDER|OB_SENSOR); /* assume triangle mesh, if no bounds chosen for soft body */ if ((ob->gameflag & OB_BOUNDS) && (ob->boundtypegameflag & OB_COLLISION)) - ob->body_type = (ob->gameflag & OB_OCCLUDER) ? OB_BODY_TYPE_OCCLUDER : OB_BODY_TYPE_NO_COLLISION; - else if (!(ob->gameflag & OB_DYNAMIC)) + if (!(ob->gameflag & OB_COLLISION)) { + if (ob->gameflag & OB_OCCLUDER) { + tip = "Occluder"; + ob->body_type = OB_BODY_TYPE_OCCLUDER; + } else { + tip = "Disable colision for this object"; + ob->body_type = OB_BODY_TYPE_NO_COLLISION; + } + } else if (ob->gameflag & OB_SENSOR) { + tip = "Collision Sensor, detects static and dynamic objects but not the other collision sensor objects"; + ob->body_type = OB_BODY_TYPE_SENSOR; + } else if (!(ob->gameflag & OB_DYNAMIC)) { + tip = "Static"; ob->body_type = OB_BODY_TYPE_STATIC; - else if (!(ob->gameflag & (OB_RIGID_BODY|OB_SOFT_BODY))) + } else if (!(ob->gameflag & (OB_RIGID_BODY|OB_SOFT_BODY))) { + tip = "Dynamic"; ob->body_type = OB_BODY_TYPE_DYNAMIC; - else if (ob->gameflag & OB_RIGID_BODY) + } else if (ob->gameflag & OB_RIGID_BODY) { + tip = "Rigid body"; ob->body_type = OB_BODY_TYPE_RIGID; - else { + } else { + tip = "Soft body"; ob->body_type = OB_BODY_TYPE_SOFT; /* create the structure here because we display soft body buttons in the main panel */ if (!ob->bsoft) @@ -3292,28 +3310,36 @@ static void buttons_bullet(uiBlock *block, Object *ob) //only enable game soft body if Blender Soft Body exists but = uiDefButS(block, MENU, REDRAWVIEW3D, - "Object type%t|Occluder%x5|No collision%x0|Static%x1|Dynamic%x2|Rigid body%x3|Soft body%x4", - 10, 205, 100, 19, &ob->body_type, 0, 0, 0, 0, "Selects the type of physical representation"); + "Object type%t|Occluder%x5|No collision%x0|Sensor%x6|Static%x1|Dynamic%x2|Rigid body%x3|Soft body%x4", + 10, 205, 100, 19, &ob->body_type, 0, 0, 0, 0, tip); uiButSetFunc(but, check_body_type, but, ob); if (ob->gameflag & OB_COLLISION) { - uiDefButBitI(block, TOG, OB_ACTOR, 0, "Actor", - 110, 205, 50, 19, &ob->gameflag, 0, 0, 0, 0, - "Objects that are detected by the Near and Radar sensor"); + if (ob->gameflag & OB_SENSOR) { + uiBlockEndAlign(block); + uiDefBlockBut(block, advanced_bullet_menu, ob, + "Advanced Settings", + 210, 205, 140, 19, "Display collision advanced settings"); + uiBlockBeginAlign(block); + } else { + uiDefButBitI(block, TOG, OB_ACTOR, 0, "Actor", + 110, 205, 50, 19, &ob->gameflag, 0, 0, 0, 0, + "Objects that are detected by the Near and Radar sensor and the collision sensor objects"); - + - uiDefButBitI(block, TOG, OB_GHOST, B_REDR, "Ghost", - 160,205,50,19, - &ob->gameflag, 0, 0, 0, 0, - "Objects that don't restitute collisions (like a ghost)"); + uiDefButBitI(block, TOG, OB_GHOST, B_REDR, "Ghost", + 160,205,50,19, + &ob->gameflag, 0, 0, 0, 0, + "Objects that don't restitute collisions (like a ghost)"); - //uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefBlockBut(block, advanced_bullet_menu, ob, - "Advanced Settings", - 210, 205, 140, 19, "Display collision advanced settings"); - //uiBlockSetCol(block, TH_BUT_SETTING2); + //uiBlockSetCol(block, TH_BUT_SETTING1); + uiDefBlockBut(block, advanced_bullet_menu, ob, + "Advanced Settings", + 210, 205, 140, 19, "Display collision advanced settings"); + //uiBlockSetCol(block, TH_BUT_SETTING2); + } if(ob->gameflag & OB_DYNAMIC) { @@ -3394,7 +3420,7 @@ static void buttons_bullet(uiBlock *block, Object *ob) /* In Bullet, anisotripic friction can be applied to static objects as well, just not soft bodies */ - if (!(ob->gameflag & OB_SOFT_BODY)) + if (!(ob->gameflag & (OB_SOFT_BODY|OB_SENSOR))) { uiDefButBitI(block, TOG, OB_ANISOTROPIC_FRICTION, B_REDR, "Anisotropic", 230, 145, 120, 19, diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 9ea623f17e4..d4cc047d5e3 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1413,6 +1413,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0; objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0; + objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0; if (objprop.m_softbody) { diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 9aeda728caf..ad8865299d6 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -91,6 +91,15 @@ protected: std::vector m_linkedcontrollers; public: + + enum sensortype { + NONE = 0, + TOUCH, + NEAR, + RADAR, + // to be updated as needed + }; + SCA_ISensor(SCA_IObject* gameobj, class SCA_EventManager* eventmgr, PyTypeObject* T );; @@ -138,6 +147,8 @@ public: virtual double GetNumber(); + virtual sensortype GetSensorType() { return NONE; } + /** Stop sensing for a while. */ void Suspend(); diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index 300a7906e81..e22edfd1306 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -17,8 +17,8 @@ #include "BulletSoftBody/btSoftBody.h" -KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound) -: KX_IPhysicsController(dyna,compound,(PHY_IPhysicsController*)this), +KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound) +: KX_IPhysicsController(dyna,sensor,compound,(PHY_IPhysicsController*)this), CcdPhysicsController(ci), m_savedCollisionFlags(0), m_savedCollisionFilterGroup(0), @@ -174,6 +174,20 @@ void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling) { CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z()); } +void KX_BulletPhysicsController::SetTransform() +{ + btVector3 pos; + btVector3 scale; + float ori[12]; + m_MotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); + m_MotionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]); + m_MotionState->getWorldOrientation(ori); + btMatrix3x3 rot(ori[0], ori[4], ori[8], + ori[1], ori[5], ori[9], + ori[2], ori[6], ori[10]); + CcdPhysicsController::forceWorldTransform(rot, pos); +} + MT_Scalar KX_BulletPhysicsController::GetMass() { if (GetSoftBody()) @@ -262,7 +276,7 @@ void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* chil // add to parent compound shapeinfo GetShapeInfo()->AddShape(proxyShapeInfo); // create new bullet collision shape from the object shapeinfo and set scaling - btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(); + btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin()); newChildShape->setLocalScaling(relativeScale); // add bullet collision shape to parent compound collision shape compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape); @@ -359,7 +373,7 @@ void KX_BulletPhysicsController::SetMass(MT_Scalar newmass) void KX_BulletPhysicsController::SuspendDynamics(bool ghost) { btRigidBody *body = GetRigidBody(); - if (body && !m_suspended) + if (body && !m_suspended && !IsSensor()) { btBroadphaseProxy* handle = body->getBroadphaseHandle(); m_savedCollisionFlags = body->getCollisionFlags(); @@ -445,7 +459,7 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) { - if (!m_bDyna) + if (!m_bDyna && !m_bSensor) { btCollisionObject* object = GetRigidBody(); object->setActivationState(ACTIVE_TAG); diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 9d2afad1a5c..755b1cbd780 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -19,7 +19,7 @@ private: public: - KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound); + KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound); virtual ~KX_BulletPhysicsController (); /////////////////////////////////// @@ -42,6 +42,7 @@ public: virtual void setOrientation(const MT_Matrix3x3& orn); virtual void setPosition(const MT_Point3& pos); virtual void setScaling(const MT_Vector3& scaling); + virtual void SetTransform(); virtual MT_Scalar GetMass(); virtual void SetMass(MT_Scalar newmass); virtual MT_Vector3 GetLocalInertia(); diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 7345edb054b..74d463fbf20 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -50,8 +50,8 @@ struct KX_ClientObjectInfo STATIC, ACTOR, RESERVED1, - RADAR, - NEAR + SENSOR, + OBSENSOR } m_type; KX_GameObject* m_gameobject; void* m_auxilary_info; @@ -84,6 +84,7 @@ public: } bool isActor() { return m_type <= ACTOR; } + bool isSensor() { return m_type >= SENSOR && m_type <= OBSENSOR; } }; #endif //__KX_CLIENTOBJECT_INFO_H diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 5b912a123fe..e48fddb30bd 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -83,6 +83,7 @@ struct KX_ObjectProperties bool m_ghost; class KX_GameObject* m_dynamic_parent; bool m_isactor; + bool m_sensor; bool m_concave; bool m_isdeformable; bool m_disableSleeping; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index f18ffb56ccb..73693e68642 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -808,12 +808,12 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, bool isbulletdyna = false; + bool isbulletsensor = false; CcdConstructionInfo ci; class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo(); - if (!objprop->m_dyna) { ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; @@ -832,6 +832,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, ci.m_margin = objprop->m_margin; shapeInfo->m_radius = objprop->m_radius; isbulletdyna = objprop->m_dyna; + isbulletsensor = objprop->m_sensor; ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f); @@ -851,7 +852,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1); shapeInfo->m_shapeType = PHY_SHAPE_SPHERE; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; }; case KX_BOUNDBOX: @@ -864,7 +865,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->m_halfExtend /= 2.0; shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute(); shapeInfo->m_shapeType = PHY_SHAPE_BOX; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; }; case KX_BOUNDCYLINDER: @@ -875,7 +876,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, objprop->m_boundobject.c.m_height * 0.5f ); shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } @@ -884,18 +885,18 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->m_radius = objprop->m_boundobject.c.m_radius; shapeInfo->m_height = objprop->m_boundobject.c.m_height; shapeInfo->m_shapeType = PHY_SHAPE_CONE; - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDPOLYTOPE: { shapeInfo->SetMesh(meshobj, dm,true,false); - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDMESH: { - bool useGimpact = (ci.m_mass && !objprop->m_softbody); + bool useGimpact = ((ci.m_mass || isbulletsensor) && !objprop->m_softbody); // mesh shapes can be shared, check first if we already have a shape on that mesh class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact); @@ -915,7 +916,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI } - bm = shapeInfo->CreateBulletShape(); + bm = shapeInfo->CreateBulletShape(ci.m_margin); //should we compute inertia for dynamic shape? //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); @@ -933,7 +934,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, return; } - bm->setMargin(ci.m_margin); + //bm->setMargin(ci.m_margin); if (objprop->m_isCompoundChild) @@ -1103,26 +1104,39 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/ //////////////////// - - ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter); - ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); + ci.m_collisionFilterGroup = + (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : + (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : + short(CcdConstructionInfo::StaticFilter); + ci.m_collisionFilterMask = + (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : + (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : + short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody; ci.m_bSoft = objprop->m_softbody; + ci.m_bSensor = isbulletsensor; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); - KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,objprop->m_hasCompoundChildren); + KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren); // shapeInfo is reference counted, decrement now as we don't use it anymore if (shapeInfo) shapeInfo->Release(); - if (objprop->m_in_active_layer) + gameobj->SetPhysicsController(physicscontroller,isbulletdyna); + if (isbulletsensor) + { + // use a different callback function for sensor object, + // bullet will not synchronize, we must do it explicitely + SG_Callbacks& callbacks = gameobj->GetSGNode()->GetCallBackFunctions(); + callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc; + // make sensor object invisible by default + gameobj->SetVisible(false, false); + } + // don't add automatically sensor object, they are added when a collision sensor is registered + else if (objprop->m_in_active_layer) { env->addCcdPhysicsController( physicscontroller); } - - - - gameobj->SetPhysicsController(physicscontroller,isbulletdyna); physicscontroller->setNewClientInfo(gameobj->getClientInfo()); { btRigidBody* rbody = physicscontroller->GetRigidBody(); @@ -1181,7 +1195,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, } bool isActor = objprop->m_isactor; - gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC); + gameobj->getClientInfo()->m_type = + (isbulletsensor) ? KX_ClientObjectInfo::OBSENSOR : + (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC; // store materialname in auxinfo, needed for touchsensors if (meshobj) { diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 79519bfb491..1d7bf56f6d3 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -332,7 +332,7 @@ void KX_GameObject::ProcessReplica() } -static void setGraphicController_recursive(SG_Node* node, bool v) +static void setGraphicController_recursive(SG_Node* node) { NodeList& children = node->GetSGChildren(); @@ -341,24 +341,24 @@ static void setGraphicController_recursive(SG_Node* node, bool v) SG_Node* childnode = (*childit); KX_GameObject *clientgameobj = static_cast( (*childit)->GetSGClientObject()); if (clientgameobj != NULL) // This is a GameObject - clientgameobj->ActivateGraphicController(v, false); + clientgameobj->ActivateGraphicController(false); // if the childobj is NULL then this may be an inverse parent link // so a non recursive search should still look down this node. - setGraphicController_recursive(childnode, v); + setGraphicController_recursive(childnode); } } -void KX_GameObject::ActivateGraphicController(bool active, bool recurse) +void KX_GameObject::ActivateGraphicController(bool recurse) { if (m_pGraphicController) { - m_pGraphicController->Activate(active); + m_pGraphicController->Activate(m_bVisible); } if (recurse) { - setGraphicController_recursive(GetSGNode(), active); + setGraphicController_recursive(GetSGNode()); } } @@ -538,6 +538,20 @@ void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* s ((KX_GameObject*)gameobj)->UpdateTransform(); } +void KX_GameObject::SynchronizeTransform() +{ + // only used for sensor object, do full synchronization as bullet doesn't do it + if (m_pPhysicsController1) + m_pPhysicsController1->SetTransform(); + if (m_pGraphicController) + m_pGraphicController->SetGraphicTransform(); +} + +void KX_GameObject::SynchronizeTransformFunc(SG_IObject* node, void* gameobj, void* scene) +{ + ((KX_GameObject*)gameobj)->SynchronizeTransform(); +} + void KX_GameObject::SetDebugColor(unsigned int bgra) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index e5b26539d4d..e0e78918dde 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -384,7 +384,7 @@ public: /* * @add/remove the graphic controller to the physic system */ - void ActivateGraphicController(bool active, bool recurse); + void ActivateGraphicController(bool recurse); /** * @section Coordinate system manipulation functions @@ -559,6 +559,13 @@ public: static void UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene); + /** + * only used for sensor objects + */ + void SynchronizeTransform(); + + static void SynchronizeTransformFunc(SG_IObject* node, void* gameobj, void* scene); + /** * Function to set IPO option at start of IPO */ diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp index a38222c5f7e..673acabd774 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp @@ -35,9 +35,10 @@ #include "PHY_DynamicTypes.h" -KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool compound, void* userdata) +KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool sensor, bool compound, void* userdata) : m_bDyna(dyna), + m_bSensor(sensor), m_bCompound(compound), m_suspendDynamics(false), m_userdata(userdata) diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index 10b66da7b76..81c01045071 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -49,11 +49,12 @@ class KX_IPhysicsController : public SG_Controller { protected: bool m_bDyna; + bool m_bSensor; bool m_bCompound; bool m_suspendDynamics; void* m_userdata; public: - KX_IPhysicsController(bool dyna,bool compound, void* userdata); + KX_IPhysicsController(bool dyna,bool sensor,bool compound, void* userdata); virtual ~KX_IPhysicsController(); @@ -74,6 +75,7 @@ public: virtual void getOrientation(MT_Quaternion& orn)=0; virtual void setOrientation(const MT_Matrix3x3& orn)=0; + virtual void SetTransform()=0; //virtual void setOrientation(const MT_Quaternion& orn)=0; virtual void setPosition(const MT_Point3& pos)=0; virtual void setScaling(const MT_Vector3& scaling)=0; @@ -100,10 +102,18 @@ public: m_bDyna = isDynamic; } + void SetSensor(bool isSensor) { + m_bSensor = isSensor; + } + bool IsDyna(void) { return m_bDyna; } + bool IsSensor(void) { + return m_bSensor; + } + bool IsCompound(void) { return m_bCompound; } diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp index b4d58dccfdf..60455d33312 100644 --- a/source/gameengine/Ketsji/KX_MotionState.cpp +++ b/source/gameengine/Ketsji/KX_MotionState.cpp @@ -73,6 +73,11 @@ void KX_MotionState::getWorldOrientation(float* ori) mat.getValue(ori); } +void KX_MotionState::setWorldOrientation(const float* ori) +{ + m_node->SetLocalOrientation(ori); +} + void KX_MotionState::setWorldPosition(float posX,float posY,float posZ) { m_node->SetLocalPosition(MT_Point3(posX,posY,posZ)); diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h index 7ba3ca2f85c..0e43e88fbeb 100644 --- a/source/gameengine/Ketsji/KX_MotionState.h +++ b/source/gameengine/Ketsji/KX_MotionState.h @@ -45,6 +45,7 @@ public: virtual void setWorldPosition(float posX,float posY,float posZ); virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal); virtual void getWorldOrientation(float* ori); + virtual void setWorldOrientation(const float* ori); virtual void calculateWorldTransformations(); }; diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index a3c4e95ae24..44842b7f5b3 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -36,6 +36,7 @@ #include "KX_Scene.h" // needed to create a replica #include "PHY_IPhysicsEnvironment.h" #include "PHY_IPhysicsController.h" +#include "PHY_IMotionState.h" #ifdef HAVE_CONFIG_H #include @@ -62,7 +63,7 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, { gameobj->getClientInfo()->m_sensors.remove(this); - m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::NEAR); + m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::SENSOR); m_client_info->m_sensors.push_back(this); //DT_ShapeHandle shape = (DT_ShapeHandle) vshape; @@ -81,28 +82,14 @@ void KX_NearSensor::SynchronizeTransform() // not linked to the parent object, must synchronize it. if (m_physCtrl) { + PHY_IMotionState* motionState = m_physCtrl->GetMotionState(); KX_GameObject* parent = ((KX_GameObject*)GetParent()); - MT_Vector3 pos = parent->NodeGetWorldPosition(); - MT_Quaternion orn = parent->NodeGetWorldOrientation().getRotation(); - m_physCtrl->setPosition(pos.x(),pos.y(),pos.z()); - m_physCtrl->setOrientation(orn.x(),orn.y(),orn.z(),orn.w()); - m_physCtrl->calcXform(); - } -} - -void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman) -{ - if (m_physCtrl) - { - touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl); - } -} - -void KX_NearSensor::UnregisterSumo(KX_TouchEventManager* touchman) -{ - if (m_physCtrl) - { - touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl); + const MT_Point3& pos = parent->NodeGetWorldPosition(); + float ori[12]; + parent->NodeGetWorldOrientation().getValue(ori); + motionState->setWorldPosition(pos[0], pos[1], pos[2]); + motionState->setWorldOrientation(ori); + m_physCtrl->WriteMotionStateToDynamics(true); } } @@ -117,7 +104,7 @@ void KX_NearSensor::ProcessReplica() { KX_TouchSensor::ProcessReplica(); - m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR); + m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::SENSOR); if (m_physCtrl) { @@ -134,11 +121,11 @@ void KX_NearSensor::ProcessReplica() void KX_NearSensor::ReParent(SCA_IObject* parent) { + SCA_ISensor::ReParent(parent); m_client_info->m_gameobject = static_cast(parent); m_client_info->m_sensors.push_back(this); //Synchronize here with the actual parent. SynchronizeTransform(); - SCA_ISensor::ReParent(parent); } diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 35136b79d13..d98b464a443 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -77,8 +77,8 @@ public: virtual bool NewHandleCollision(void* obj1,void* obj2, const PHY_CollData * coll_data); virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2); - virtual void RegisterSumo(KX_TouchEventManager *touchman); - virtual void UnregisterSumo(KX_TouchEventManager* touchman); + virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2) { return false; }; + virtual sensortype GetSensorType() { return NEAR; } /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h index 21b7e632d83..8c3974c38a3 100644 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.h +++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h @@ -70,6 +70,7 @@ public: virtual void setOrientation(const MT_Matrix3x3& orn); virtual void setPosition(const MT_Point3& pos); virtual void setScaling(const MT_Vector3& scaling); + virtual void SetTransform() {} virtual MT_Scalar GetMass(); virtual MT_Vector3 getReactionForce(); virtual void setRigidBody(bool rigid); diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 4532224a81e..064dc9126ac 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -30,6 +30,7 @@ #include "KX_GameObject.h" #include "KX_PyMath.h" #include "PHY_IPhysicsController.h" +#include "PHY_IMotionState.h" #ifdef HAVE_CONFIG_H #include @@ -66,7 +67,7 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, m_coneheight(coneheight), m_axis(axis) { - m_client_info->m_type = KX_ClientObjectInfo::RADAR; + m_client_info->m_type = KX_ClientObjectInfo::SENSOR; //m_client_info->m_clientobject = gameobj; //m_client_info->m_auxilary_info = NULL; //sumoObj->setClientObject(&m_client_info); @@ -84,12 +85,6 @@ CValue* KX_RadarSensor::GetReplica() return replica; } -void KX_RadarSensor::ProcessReplica() -{ - KX_NearSensor::ProcessReplica(); - m_client_info->m_type = KX_ClientObjectInfo::RADAR; -} - /** * Transforms the collision object. A cone is not correctly centered * for usage. */ @@ -169,11 +164,13 @@ void KX_RadarSensor::SynchronizeTransform() if (m_physCtrl) { - MT_Quaternion orn = trans.getRotation(); - MT_Point3 pos = trans.getOrigin(); - m_physCtrl->setPosition(pos[0],pos[1],pos[2]); - m_physCtrl->setOrientation(orn[0],orn[1],orn[2],orn[3]); - m_physCtrl->calcXform(); + PHY_IMotionState* motionState = m_physCtrl->GetMotionState(); + const MT_Point3& pos = trans.getOrigin(); + float ori[12]; + trans.getBasis().getValue(ori); + motionState->setWorldPosition(pos[0], pos[1], pos[2]); + motionState->setWorldOrientation(ori); + m_physCtrl->WriteMotionStateToDynamics(true); } } diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index b4268797f85..6779a9edffe 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -76,7 +76,6 @@ public: virtual ~KX_RadarSensor(); virtual void SynchronizeTransform(); virtual CValue* GetReplica(); - virtual void ProcessReplica(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ @@ -93,6 +92,7 @@ public: virtual PyObject* py_getattro(PyObject *attr); virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); + virtual sensortype GetSensorType() { return RADAR; } //Deprecated -----> KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 9502599603c..bb5e0875402 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -737,7 +737,7 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox()); replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius()); // we can now add the graphic controller to the physic engine - replica->ActivateGraphicController(true,true); + replica->ActivateGraphicController(true); // done with replica replica->Release(); @@ -850,7 +850,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox()); replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius()); // the size is correct, we can add the graphic controller to the physic engine - replica->ActivateGraphicController(true,true); + replica->ActivateGraphicController(true); // now replicate logic vector::iterator git; diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h index 083d89896f6..278994c6ae7 100644 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h @@ -53,7 +53,7 @@ public: class SM_Object* sumoObj, class PHY_IMotionState* motionstate ,bool dyna) - : KX_IPhysicsController(dyna,false,NULL) , + : KX_IPhysicsController(dyna,false,false,NULL) , SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna) { }; @@ -83,6 +83,7 @@ public: virtual void getOrientation(MT_Quaternion& orn); virtual void setOrientation(const MT_Matrix3x3& orn); + virtual void SetTransform() {} virtual void setPosition(const MT_Point3& pos); virtual void setScaling(const MT_Vector3& scaling); diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 8ae5fae8fa3..46927541099 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -85,14 +85,34 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data, PHY_IPhysicsController* ctrl = static_cast(object1); KX_ClientObjectInfo* info = (ctrl) ? static_cast(ctrl->getNewClientInfo()) : NULL; // This call back should only be called for controllers of Near and Radar sensor - if (info && - info->m_sensors.size() == 1 && - (info->m_type == KX_ClientObjectInfo::NEAR || - info->m_type == KX_ClientObjectInfo::RADAR)) + if (!info) + return true; + + switch (info->m_type) { - // only one sensor for this type of object - KX_TouchSensor* touchsensor = static_cast(*info->m_sensors.begin()); - return touchsensor->BroadPhaseFilterCollision(object1,object2); + case KX_ClientObjectInfo::SENSOR: + if (info->m_sensors.size() == 1) + { + // only one sensor for this type of object + KX_TouchSensor* touchsensor = static_cast(*info->m_sensors.begin()); + return touchsensor->BroadPhaseFilterCollision(object1,object2); + } + break; + case KX_ClientObjectInfo::OBSENSOR: + // this object may have multiple collision sensors, + // check is any of them is interested in this object + for(std::list::iterator it = info->m_sensors.begin(); + it != info->m_sensors.end(); + ++it) + { + if ((*it)->GetSensorType() == SCA_ISensor::TOUCH) + { + KX_TouchSensor* touchsensor = static_cast(*it); + if (touchsensor->BroadPhaseSensorFilterCollision(object1, object2)) + return true; + } + } + return false; } return true; } diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 8c0d5596939..509fc60e9f5 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -173,21 +173,67 @@ void KX_TouchSensor::RegisterSumo(KX_TouchEventManager *touchman) { if (m_physCtrl) { - touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl); - // collision - // Deprecated - + if (touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl)) + { + KX_ClientObjectInfo* client_info = static_cast(m_physCtrl->getNewClientInfo()); + if (client_info->isSensor()) + touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl); + } } } - void KX_TouchSensor::UnregisterSumo(KX_TouchEventManager* touchman) { if (m_physCtrl) { - touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl); + if (touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl)) + { + // no more sensor on the controller, can remove it if it is a sensor object + KX_ClientObjectInfo* client_info = static_cast(m_physCtrl->getNewClientInfo()); + if (client_info->isSensor()) + touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl); + } } } +// this function is called only for sensor objects +// return true if the controller can collide with the object +bool KX_TouchSensor::BroadPhaseSensorFilterCollision(void*obj1,void*obj2) +{ + assert(obj1==m_physCtrl && obj2); + + KX_GameObject* myobj = (KX_GameObject*)GetParent(); + KX_GameObject* myparent = myobj->GetParent(); + KX_ClientObjectInfo* client_info = static_cast(((PHY_IPhysicsController*)obj2)->getNewClientInfo()); + KX_GameObject* otherobj = ( client_info ? client_info->m_gameobject : NULL); + + // first, decrement refcount as GetParent() increases it + if (myparent) + myparent->Release(); + + // we can only check on persistent characteristic: m_link and m_suspended are not + // good candidate because they are transient. That must be handled at another level + if (!otherobj || + otherobj == myparent || // don't interact with our parent + client_info->m_type != KX_ClientObjectInfo::ACTOR) // only with actor objects + return false; + + bool found = m_touchedpropname.IsEmpty(); + if (!found) + { + if (m_bFindMaterial) + { + if (client_info->m_auxilary_info) + { + found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info)); + } + } else + { + found = (otherobj->GetProperty(m_touchedpropname) != NULL); + } + } + return found; +} + bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_CollData* colldata) { // KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr; diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 9c9c6bf5816..b62ec6eaf4d 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -103,7 +103,8 @@ public: // obj1 = sensor physical controller, obj2 = physical controller of second object // return value = true if collision should be checked on pair of object virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2) { return true; } - + virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2); + virtual sensortype GetSensorType() { return TOUCH; } virtual bool IsPositiveTrigger() { diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp b/source/gameengine/Physics/BlOde/OdePhysicsController.cpp index efe4554d970..5efd0994311 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp +++ b/source/gameengine/Physics/BlOde/OdePhysicsController.cpp @@ -379,7 +379,10 @@ bool ODEPhysicsController::SynchronizeMotionStates(float time) return false; //it update the worldpos } - +PHY_IMotionState* ODEPhysicsController::GetMotionState() +{ + return m_MotionState; +} // kinematic methods diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.h b/source/gameengine/Physics/BlOde/OdePhysicsController.h index e97afdb68c3..544d11da2ca 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.h +++ b/source/gameengine/Physics/BlOde/OdePhysicsController.h @@ -102,6 +102,7 @@ public: virtual void WriteDynamicsToMotionState() {}; virtual void WriteMotionStateToDynamics(bool nondynaonly); + virtual class PHY_IMotionState* GetMotionState(); /** call from Scene Graph Node to 'update'. diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h index 82e26e01460..54e4f7f90e1 100644 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h +++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h @@ -64,8 +64,8 @@ public: virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) { } - virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl) {} - virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl) {} + virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl) {return false;} + virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl) {return false;} virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;} virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 01e8aa2560f..7302c47f4bf 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -92,16 +92,19 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci) } -btTransform CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState) +btTransform& CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState) { - btTransform trans; - float tmp[3]; - motionState->getWorldPosition(tmp[0],tmp[1],tmp[2]); - trans.setOrigin(btVector3(tmp[0],tmp[1],tmp[2])); + static btTransform trans; + btVector3 tmp; + motionState->getWorldPosition(tmp.m_floats[0], tmp.m_floats[1], tmp.m_floats[2]); + trans.setOrigin(tmp); - btQuaternion orn; - motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - trans.setRotation(orn); + float ori[12]; + motionState->getWorldOrientation(ori); + trans.getBasis().setFromOpenGLSubMatrix(ori); + //btQuaternion orn; + //motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); + //trans.setRotation(orn); return trans; } @@ -118,18 +121,18 @@ public: } - virtual void getWorldTransform(btTransform& worldTrans ) const + void getWorldTransform(btTransform& worldTrans ) const { - float pos[3]; - float quatOrn[4]; + btVector3 pos; + float ori[12]; - m_blenderMotionState->getWorldPosition(pos[0],pos[1],pos[2]); - m_blenderMotionState->getWorldOrientation(quatOrn[0],quatOrn[1],quatOrn[2],quatOrn[3]); - worldTrans.setOrigin(btVector3(pos[0],pos[1],pos[2])); - worldTrans.setBasis(btMatrix3x3(btQuaternion(quatOrn[0],quatOrn[1],quatOrn[2],quatOrn[3]))); + m_blenderMotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); + m_blenderMotionState->getWorldOrientation(ori); + worldTrans.setOrigin(pos); + worldTrans.getBasis().setFromOpenGLSubMatrix(ori); } - virtual void setWorldTransform(const btTransform& worldTrans) + void setWorldTransform(const btTransform& worldTrans) { m_blenderMotionState->setWorldPosition(worldTrans.getOrigin().getX(),worldTrans.getOrigin().getY(),worldTrans.getOrigin().getZ()); btQuaternion rotQuat = worldTrans.getRotation(); @@ -493,10 +496,12 @@ void CcdPhysicsController::CreateRigidbody() //convert collision flags! //special case: a near/radar sensor controller should not be defined static or it will //generate loads of static-static collision messages on the console - if ((m_cci.m_collisionFilterGroup & CcdConstructionInfo::SensorFilter) != 0) + if (m_cci.m_bSensor) { // reset the flags that have been set so far GetCollisionObject()->setCollisionFlags(0); + // sensor must never go to sleep: they need to detect continously + GetCollisionObject()->setActivationState(DISABLE_DEACTIVATION); } GetCollisionObject()->setCollisionFlags(m_object->getCollisionFlags() | m_cci.m_collisionFlags); btRigidBody* body = GetRigidBody(); @@ -613,12 +618,13 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time) body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_min / len)); } - const btVector3& worldPos = body->getCenterOfMassPosition(); + const btTransform& xform = body->getCenterOfMassTransform(); + const btMatrix3x3& worldOri = xform.getBasis(); + const btVector3& worldPos = xform.getOrigin(); + float ori[12]; + worldOri.getOpenGLSubMatrix(ori); + m_MotionState->setWorldOrientation(ori); m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - - const btQuaternion& worldquat = body->getOrientation(); - m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); - m_MotionState->calculateWorldTransformations(); float scale[3]; @@ -655,8 +661,10 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time) void CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly) { - + btTransform& xform = CcdPhysicsController::GetTransformFromMotionState(m_MotionState); + SetCenterOfMassTransform(xform); } + void CcdPhysicsController::WriteDynamicsToMotionState() { } @@ -673,12 +681,12 @@ void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta if (m_shapeInfo) { m_shapeInfo->AddRef(); - m_collisionShape = m_shapeInfo->CreateBulletShape(); + m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin); if (m_collisionShape) { // new shape has no scaling, apply initial scaling - m_collisionShape->setMargin(m_cci.m_margin); + //m_collisionShape->setMargin(m_cci.m_margin); m_collisionShape->setLocalScaling(m_cci.m_scaling); if (m_cci.m_mass) @@ -697,8 +705,10 @@ void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta { body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); } - } - m_cci.m_physicsEnv->addCcdPhysicsController(this); + } + // sensor object are added when needed + if (!m_cci.m_bSensor) + m_cci.m_physicsEnv->addCcdPhysicsController(this); /* SM_Object* dynaparent=0; @@ -773,7 +783,7 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc if (m_object) { m_object->activate(true); - if (m_object->isStaticObject()) + if (m_object->isStaticObject() && !m_cci.m_bSensor) { m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } @@ -799,7 +809,7 @@ void CcdPhysicsController::RelativeRotate(const float rotval[9],bool local) if (m_object) { m_object->activate(true); - if (m_object->isStaticObject()) + if (m_object->isStaticObject() && !m_cci.m_bSensor) { m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } @@ -843,7 +853,7 @@ void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float if (m_object) { m_object->activate(true); - if (m_object->isStaticObject()) + if (m_object->isStaticObject() && !m_cci.m_bSensor) { m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } @@ -866,7 +876,7 @@ void CcdPhysicsController::setWorldOrientation(const btMatrix3x3& orn) if (m_object) { m_object->activate(true); - if (m_object->isStaticObject()) + if (m_object->isStaticObject() && !m_cci.m_bSensor) { m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } @@ -895,7 +905,7 @@ void CcdPhysicsController::setPosition(float posX,float posY,float posZ) if (m_object) { m_object->activate(true); - if (m_object->isStaticObject()) + if (m_object->isStaticObject() && !m_cci.m_bSensor) { m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } @@ -909,9 +919,19 @@ void CcdPhysicsController::setPosition(float posX,float posY,float posZ) // not required //m_bulletMotionState->setWorldTransform(xform); } - - } + +void CcdPhysicsController::forceWorldTransform(const btMatrix3x3& mat, const btVector3& pos) +{ + if (m_object) + { + btTransform& xform = m_object->getWorldTransform(); + xform.setBasis(mat); + xform.setOrigin(pos); + } +} + + void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) { } @@ -961,7 +981,9 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque m_object->activate(); if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + return; } if (local) { @@ -989,27 +1011,26 @@ void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bo m_object->activate(); if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + return; } - + btTransform xform = m_object->getWorldTransform(); + + if (local) + { + force = xform.getBasis()*force; + } + btRigidBody* body = GetRigidBody(); + if (body) + body->applyCentralForce(force); + btSoftBody* soft = GetSoftBody(); + if (soft) { - btTransform xform = m_object->getWorldTransform(); - - if (local) - { - force = xform.getBasis()*force; - } - btRigidBody* body = GetRigidBody(); - if (body) - body->applyCentralForce(force); - btSoftBody* soft = GetSoftBody(); - if (soft) - { - // the force is applied on each node, must reduce it in the same extend - if (soft->m_nodes.size() > 0) - force /= soft->m_nodes.size(); - soft->addForce(force); - } + // the force is applied on each node, must reduce it in the same extend + if (soft->m_nodes.size() > 0) + force /= soft->m_nodes.size(); + soft->addForce(force); } } } @@ -1021,19 +1042,18 @@ void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,flo m_object->activate(true); if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - } else - { - btTransform xform = m_object->getWorldTransform(); - if (local) - { - angvel = xform.getBasis()*angvel; - } - btRigidBody* body = GetRigidBody(); - if (body) - body->setAngularVelocity(angvel); - + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + return; } + btTransform xform = m_object->getWorldTransform(); + if (local) + { + angvel = xform.getBasis()*angvel; + } + btRigidBody* body = GetRigidBody(); + if (body) + body->setAngularVelocity(angvel); } } @@ -1046,7 +1066,8 @@ void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,floa m_object->activate(true); if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); return; } @@ -1080,7 +1101,9 @@ void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attac m_object->activate(); if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + return; } btVector3 pos(attachX,attachY,attachZ); @@ -1207,7 +1230,7 @@ PHY_IPhysicsController* CcdPhysicsController::GetReplica() if (m_shapeInfo) { // This situation does not normally happen - cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(); + cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(0.01); } else if (m_collisionShape) { @@ -1274,28 +1297,22 @@ void DefaultMotionState::getWorldScaling(float& scaleX,float& scaleY,float& scal void DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal) { - quatIma0 = m_worldTransform.getRotation().x(); - quatIma1 = m_worldTransform.getRotation().y(); - quatIma2 = m_worldTransform.getRotation().z(); - quatReal = m_worldTransform.getRotation()[3]; + btQuaternion quat = m_worldTransform.getRotation(); + quatIma0 = quat.x(); + quatIma1 = quat.y(); + quatIma2 = quat.z(); + quatReal = quat[3]; } void DefaultMotionState::getWorldOrientation(float* ori) { - *ori++ = m_worldTransform.getBasis()[0].x(); - *ori++ = m_worldTransform.getBasis()[1].x(); - *ori++ = m_worldTransform.getBasis()[1].x(); - *ori++ = 0.f; - *ori++ = m_worldTransform.getBasis()[0].y(); - *ori++ = m_worldTransform.getBasis()[1].y(); - *ori++ = m_worldTransform.getBasis()[1].y(); - *ori++ = 0.f; - *ori++ = m_worldTransform.getBasis()[0].z(); - *ori++ = m_worldTransform.getBasis()[1].z(); - *ori++ = m_worldTransform.getBasis()[1].z(); - *ori++ = 0.f; + m_worldTransform.getBasis().getOpenGLSubMatrix(ori); } +void DefaultMotionState::setWorldOrientation(const float* ori) +{ + m_worldTransform.getBasis().setFromOpenGLSubMatrix(ori); +} void DefaultMotionState::setWorldPosition(float posX,float posY,float posZ) { btVector3 pos(posX,posY,posZ); @@ -1583,7 +1600,7 @@ bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo) return true; } -btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() +btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) { btCollisionShape* collisionShape = 0; btTriangleMeshShape* concaveShape = 0; @@ -1591,7 +1608,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() CcdShapeConstructionInfo* nextShapeInfo; if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) - return m_shapeProxy->CreateBulletShape(); + return m_shapeProxy->CreateBulletShape(margin); switch (m_shapeType) { @@ -1600,22 +1617,27 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() case PHY_SHAPE_BOX: collisionShape = new btBoxShape(m_halfExtend); + collisionShape->setMargin(margin); break; case PHY_SHAPE_SPHERE: collisionShape = new btSphereShape(m_radius); + collisionShape->setMargin(margin); break; case PHY_SHAPE_CYLINDER: collisionShape = new btCylinderShapeZ(m_halfExtend); + collisionShape->setMargin(margin); break; case PHY_SHAPE_CONE: collisionShape = new btConeShapeZ(m_radius, m_height); + collisionShape->setMargin(margin); break; case PHY_SHAPE_POLYTOPE: collisionShape = new btConvexHullShape(&m_vertexArray[0], m_vertexArray.size()/3, 3*sizeof(btScalar)); + collisionShape->setMargin(margin); break; case PHY_SHAPE_MESH: @@ -1638,7 +1660,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() ); btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays); - + gimpactShape->setMargin(margin); collisionShape = gimpactShape; gimpactShape->updateBound(); @@ -1683,6 +1705,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() m_unscaledShape->recalcLocalAabb(); } collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f)); + collisionShape->setMargin(margin); } break; @@ -1694,7 +1717,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() sit != m_shapeArray.end(); sit++) { - collisionShape = (*sit)->CreateBulletShape(); + collisionShape = (*sit)->CreateBulletShape(margin); if (collisionShape) { collisionShape->setLocalScaling((*sit)->m_childScale); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 315e2bdf429..fc8de0e2ded 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -152,7 +152,7 @@ public: return m_shapeProxy; } - btCollisionShape* CreateBulletShape(); + btCollisionShape* CreateBulletShape(btScalar margin); // member variables PHY_ShapeType m_shapeType; @@ -222,6 +222,7 @@ struct CcdConstructionInfo m_collisionFlags(0), m_bRigid(false), m_bSoft(false), + m_bSensor(false), m_collisionFilterGroup(DefaultFilter), m_collisionFilterMask(AllFilter), m_collisionShape(0), @@ -288,6 +289,7 @@ struct CcdConstructionInfo int m_collisionFlags; bool m_bRigid; bool m_bSoft; + bool m_bSensor; ///optional use of collision group/mask: ///only collision with object goups that match the collision mask. @@ -326,7 +328,7 @@ class btSoftBody; ///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution. class CcdPhysicsController : public PHY_IPhysicsController { - +protected: btCollisionObject* m_object; @@ -361,8 +363,8 @@ class CcdPhysicsController : public PHY_IPhysicsController return (--m_registerCount == 0) ? true : false; } - protected: - void setWorldOrientation(const btMatrix3x3& mat); + void setWorldOrientation(const btMatrix3x3& mat); + void forceWorldTransform(const btMatrix3x3& mat, const btVector3& pos); public: @@ -407,6 +409,7 @@ class CcdPhysicsController : public PHY_IPhysicsController virtual void WriteMotionStateToDynamics(bool nondynaonly); virtual void WriteDynamicsToMotionState(); + // controller replication virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); @@ -505,7 +508,7 @@ class CcdPhysicsController : public PHY_IPhysicsController void SetCenterOfMassTransform(btTransform& xform); - static btTransform GetTransformFromMotionState(PHY_IMotionState* motionState); + static btTransform& GetTransformFromMotionState(PHY_IMotionState* motionState); void setAabb(const btVector3& aabbMin,const btVector3& aabbMax); @@ -563,6 +566,7 @@ class DefaultMotionState : public PHY_IMotionState virtual void setWorldPosition(float posX,float posY,float posZ); virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal); virtual void getWorldOrientation(float* ori); + virtual void setWorldOrientation(const float* ori); virtual void calculateWorldTransformations(); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 03c9d13a7dd..ed517e637dc 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -415,61 +415,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl) obj->setActivationState(ISLAND_SLEEPING); } - - //CollisionObject(body,ctrl->GetCollisionFilterGroup(),ctrl->GetCollisionFilterMask()); - assert(obj->getBroadphaseHandle()); - - btBroadphaseInterface* scene = getBroadphase(); - - - btCollisionShape* shapeinterface = ctrl->GetCollisionShape(); - - assert(shapeinterface); - - const btTransform& t = ctrl->GetCollisionObject()->getWorldTransform(); - - - btVector3 minAabb,maxAabb; - - shapeinterface->getAabb(t,minAabb,maxAabb); - - float timeStep = 0.02f; - - - //extent it with the motion - - if (body) - { - btVector3 linMotion = body->getLinearVelocity()*timeStep; - - float maxAabbx = maxAabb.getX(); - float maxAabby = maxAabb.getY(); - float maxAabbz = maxAabb.getZ(); - float minAabbx = minAabb.getX(); - float minAabby = minAabb.getY(); - float minAabbz = minAabb.getZ(); - - if (linMotion.x() > 0.f) - maxAabbx += linMotion.x(); - else - minAabbx += linMotion.x(); - if (linMotion.y() > 0.f) - maxAabby += linMotion.y(); - else - minAabby += linMotion.y(); - if (linMotion.z() > 0.f) - maxAabbz += linMotion.z(); - else - minAabbz += linMotion.z(); - - - minAabb = btVector3(minAabbx,minAabby,minAabbz); - maxAabb = btVector3(maxAabbx,maxAabby,maxAabbz); - } - - - } @@ -1884,29 +1830,20 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl) // addCcdPhysicsController(ctrl1); //} enableCcdPhysicsController(ctrl1); - - //Collision filter/mask is now set at the time of the creation of the controller - //force collision detection with everything, including static objects (might hurt performance!) - //ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::SensorTrigger; - //ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterGroup = btBroadphaseProxy::SensorTrigger; - //todo: make this 'sensor'! - - requestCollisionCallback(ctrl); - //printf("addSensor\n"); } -void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) +bool CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) { CcdPhysicsController* ccdCtrl = (CcdPhysicsController*)ctrl; - if (ccdCtrl->Unregister()) - m_triggerControllers.erase(ccdCtrl); + if (!ccdCtrl->Unregister()) + return false; + m_triggerControllers.erase(ccdCtrl); + return true; } void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl) { - removeCollisionCallback(ctrl); - disableCcdPhysicsController((CcdPhysicsController*)ctrl); } @@ -1942,12 +1879,14 @@ void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCal m_triggerCallbacksUserPtrs[response_class] = user; } -void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) +bool CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) { CcdPhysicsController* ccdCtrl = static_cast(ctrl); - if (ccdCtrl->Register()) - m_triggerControllers.insert(ccdCtrl); + if (!ccdCtrl->Register()) + return false; + m_triggerControllers.insert(ccdCtrl); + return true; } void CcdPhysicsEnvironment::CallbackTriggers() @@ -2096,12 +2035,13 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radi // declare this object as Dyamic rather then static!! // The reason as it is designed to detect all type of object, including static object // It would cause static-static message to be printed on the console otherwise - cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE/* | btCollisionObject::CF_KINEMATIC_OBJECT*/; + cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_STATIC_OBJECT; DefaultMotionState* motionState = new DefaultMotionState(); cinfo.m_MotionState = motionState; // we will add later the possibility to select the filter from option cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter; + cinfo.m_bSensor = true; motionState->m_worldTransform.setIdentity(); motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2])); @@ -2555,13 +2495,14 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float conera cinfo.m_collisionShape = new btConeShape(coneradius,coneheight); cinfo.m_MotionState = 0; cinfo.m_physicsEnv = this; - cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE; + cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_STATIC_OBJECT; DefaultMotionState* motionState = new DefaultMotionState(); cinfo.m_MotionState = motionState; // we will add later the possibility to select the filter from option cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter; + cinfo.m_bSensor = true; motionState->m_worldTransform.setIdentity(); // motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2])); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 5f9fb9511d6..4e39d531cd6 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -179,8 +179,8 @@ protected: virtual void addSensor(PHY_IPhysicsController* ctrl); virtual void removeSensor(PHY_IPhysicsController* ctrl); virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user); - virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl); - virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl); + virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl); + virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl); //These two methods are used *solely* to create controllers for Near/Radar sensor! Don't use for anything else virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position); virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight); diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 397a1ba4218..73e7e947355 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -79,8 +79,8 @@ public: virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) { } - virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl) {} - virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl) {} + virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl) { return false; } + virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl) { return false;} virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;} virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp index 3451e6c3ec8..56caa9236bf 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp @@ -390,6 +390,11 @@ void SumoPhysicsController::PostProcessReplica(class PHY_IMotionState* motionst m_sumoScene->add(* (m_sumoObj)); } +PHY_IMotionState* SumoPhysicsController::GetMotionState() +{ + return m_MotionState; +} + void SumoPhysicsController::SetSimulatedTime(float) { } diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.h b/source/gameengine/Physics/Sumo/SumoPhysicsController.h index 415bc1e3982..adf29649f18 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.h +++ b/source/gameengine/Physics/Sumo/SumoPhysicsController.h @@ -110,6 +110,7 @@ public: virtual void WriteDynamicsToMotionState() {}; virtual void WriteMotionStateToDynamics(bool nondynaonly); + virtual class PHY_IMotionState* GetMotionState(); /** * call from Scene Graph Node to 'update'. diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp index cc6d5654ec9..b4daf0a3f80 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp @@ -213,7 +213,7 @@ void SumoPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCa m_sumoScene->addTouchCallback(sumoRespClass,SumoPHYCallbackBridge::StaticSolidToPHYCallback,bridge); } -void SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) +bool SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) { SumoPhysicsController* smctrl = dynamic_cast(ctrl); MT_assert(smctrl); @@ -225,12 +225,15 @@ void SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ct smObject->setPhysicsClientObject(ctrl); m_sumoScene->requestCollisionCallback(*smObject); + return true; } + return false; } -void SumoPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) +bool SumoPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) { // intentionally empty + return false; } PHY_IPhysicsController* SumoPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position) diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h index c2b443a2b38..4c9d59e3673 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h @@ -83,8 +83,8 @@ public: virtual void addSensor(PHY_IPhysicsController* ctrl); virtual void removeSensor(PHY_IPhysicsController* ctrl); virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user); - virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl); - virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl); + virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl); + virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl); virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position); virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight); diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h index 64bb810ee7c..f7bcbd4f2d0 100644 --- a/source/gameengine/Physics/common/PHY_IMotionState.h +++ b/source/gameengine/Physics/common/PHY_IMotionState.h @@ -45,10 +45,12 @@ class PHY_IMotionState virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)=0; // ori = array 12 floats, [0..3] = first column + 0, [4..7] = second colum, [8..11] = third column virtual void getWorldOrientation(float* ori)=0; + virtual void setWorldOrientation(const float* ori)=0; virtual void setWorldPosition(float posX,float posY,float posZ)=0; virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)=0; + virtual void calculateWorldTransformations()=0; }; diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h index 770426b48db..d7b8cb0b54f 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h @@ -31,7 +31,7 @@ #include "PHY_IController.h" - +class PHY_IMotionState; /** PHY_IPhysicsController is the abstract simplified Interface to a physical object. @@ -53,6 +53,7 @@ class PHY_IPhysicsController : public PHY_IController virtual void WriteMotionStateToDynamics(bool nondynaonly)=0; virtual void WriteDynamicsToMotionState()=0; + virtual class PHY_IMotionState* GetMotionState() = 0; // controller replication virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)=0; diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index a3605669f70..1939083ef5f 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -152,8 +152,8 @@ class PHY_IPhysicsEnvironment virtual void addSensor(PHY_IPhysicsController* ctrl)=0; virtual void removeSensor(PHY_IPhysicsController* ctrl)=0; virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0; - virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0; - virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl)=0; + virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl)=0; + virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl)=0; //These two methods are *solely* used to create controllers for sensor! Don't use for anything else virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0; virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0; diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index b4dd9a9ddf2..8f448a0e890 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -203,6 +203,13 @@ public: return m_SGcontrollers; } + /** + * + */ + SG_Callbacks& GetCallBackFunctions() + { + return m_callbacks; + } /** * Get the client object associated with this diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index d1fc95cceac..6e274487c9d 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -148,6 +148,13 @@ public: SetModified(); } + // rot is arrange like openGL matrix + void SetLocalOrientation(const float* rot) + { + m_localRotation.setValue(rot); + SetModified(); + } + void SetWorldOrientation(const MT_Matrix3x3& rot) { m_worldRotation = rot; From 65796e2c0712798606497dfb3f36ccbd6e7ab725 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 17 May 2009 15:09:03 +0000 Subject: [PATCH 259/444] Patch #18758 for bug #17423 by Matt D. (foom) Thanks! "Mouse wheel zoom lost after rendering." --- intern/ghost/intern/GHOST_SystemWin32.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index feb0fe39040..b265353144d 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -41,7 +41,7 @@ #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning #include "GHOST_SystemWin32.h" - +//#include //for printf() // win64 doesn't define GWL_USERDATA #ifdef WIN32 #ifndef GWL_USERDATA @@ -747,6 +747,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * the message is sent asynchronously, so the window is activated immediately. */ event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window); + /* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL + will not be dispatched to OUR active window if we minimize one of OUR windows. */ + lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); break; case WM_PAINT: /* An application sends the WM_PAINT message when the system or another application @@ -766,6 +769,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * message without calling DefWindowProc. */ event = processWindowEvent(GHOST_kEventWindowSize, window); + break; case WM_CAPTURECHANGED: window->lostMouseCapture(); break; @@ -904,7 +908,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, if (event) { system->pushEvent(event); - lResult = 0; + if(!lResult) //WM_ACTIVATE might have returned something. + lResult = 0; } else { lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); From 41acd3b81cd2a7156b8c5ced4d4aa257e7575517 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 17 May 2009 16:30:18 +0000 Subject: [PATCH 260/444] While testing YoFrankie with the new API attributes found some issues... - corrections to docs - disallow calling controller.activate(actuator) when the controller is not active. (Raise a SystemError) - Added 2 new attributes, CValue.name - deprecates CValue.getName(), KX_GameObject.children deprecated KX_GameObject.getChildren(), (same for getChildrenRecursive()). --- source/gameengine/Expressions/Value.cpp | 9 +++++++- source/gameengine/Expressions/Value.h | 2 ++ .../GameLogic/SCA_PythonController.cpp | 10 +++++++++ source/gameengine/Ketsji/KX_Camera.cpp | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 20 ++++++++++++++++- source/gameengine/Ketsji/KX_GameObject.h | 2 ++ source/gameengine/PyDoc/GameTypes.py | 22 ++++++++++++++----- 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 83deeef91a3..f61ef1455b4 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -66,13 +66,14 @@ PyParentObject CValue::Parents[] = { }; PyMethodDef CValue::Methods[] = { -// { "printHello", (PyCFunction) CValue::sPyPrintHello, METH_VARARGS}, { "getName", (PyCFunction) CValue::sPyGetName, METH_NOARGS}, {NULL,NULL} //Sentinel }; PyObject* CValue::PyGetName() { + ShowDeprecationWarning("getName()", "the name property"); + return PyString_FromString(this->GetName()); } @@ -550,6 +551,7 @@ static PyMethodDef CValueMethods[] = }; PyAttributeDef CValue::Attributes[] = { + KX_PYATTRIBUTE_RO_FUNCTION("name", CValue, pyattr_get_name), { NULL } //Sentinel }; @@ -574,6 +576,11 @@ PyObject* CValue::py_getattro_dict() { py_getattro_dict_up(PyObjectPlus); } +PyObject * CValue::pyattr_get_name(void * self_v, const KX_PYATTRIBUTE_DEF * attrdef) { + CValue * self = static_cast (self_v); + return PyString_FromString(self->GetName()); +} + CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) { diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index e5c95df1c5c..0be76c4f452 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -236,6 +236,8 @@ public: virtual int py_delattro(PyObject *attr); virtual int py_setattro(PyObject *attr, PyObject* value); + static PyObject * pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef); + virtual PyObject* ConvertKeysToPython( void ); KX_PYMETHOD_NOARGS(CValue,GetName); diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 212366e6526..abb3b36b91e 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -494,6 +494,11 @@ int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value) PyObject* SCA_PythonController::PyActivate(PyObject *value) { + if(m_sCurrentController != this) { + PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller"); + return NULL; + } + SCA_IActuator* actu = LinkedActuatorFromPy(value); if(actu==NULL) return NULL; @@ -504,6 +509,11 @@ PyObject* SCA_PythonController::PyActivate(PyObject *value) PyObject* SCA_PythonController::PyDeActivate(PyObject *value) { + if(m_sCurrentController != this) { + PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller"); + return NULL; + } + SCA_IActuator* actu = LinkedActuatorFromPy(value); if(actu==NULL) return NULL; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 0d2e68243f8..625710fa65d 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -757,7 +757,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport, "Sets this camera's viewport status\n" ) { - ShowDeprecationWarning("enableViewport(bool)", "the isViewport property"); + ShowDeprecationWarning("enableViewport(bool)", "the useViewport property"); int viewport = PyObject_IsTrue(value); if (viewport == -1) { diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 1d7bf56f6d3..cbd17e66f62 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1213,6 +1213,8 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition), KX_PYATTRIBUTE_RW_FUNCTION("localScale", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling), KX_PYATTRIBUTE_RO_FUNCTION("worldScale", KX_GameObject, pyattr_get_worldScaling), + KX_PYATTRIBUTE_RO_FUNCTION("children", KX_GameObject, pyattr_get_children), + KX_PYATTRIBUTE_RO_FUNCTION("childrenRecursive", KX_GameObject, pyattr_get_children_recursive), KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict), /* Experemental, dont rely on these yet */ @@ -1753,6 +1755,18 @@ PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE return KX_PythonSeq_CreatePyObject((static_cast(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_ACTUATORS); } +PyObject* KX_GameObject::pyattr_get_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast(self_v); + return self->GetChildren()->NewProxy(true); +} + +PyObject* KX_GameObject::pyattr_get_children_recursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast(self_v); + return self->GetChildrenRecursive()->NewProxy(true); +} + PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); @@ -2155,11 +2169,15 @@ PyObject* KX_GameObject::PyRemoveParent() PyObject* KX_GameObject::PyGetChildren() { + ShowDeprecationWarning("getChildren()", "the children property"); + return GetChildren()->NewProxy(true); } PyObject* KX_GameObject::PyGetChildrenRecursive() { + ShowDeprecationWarning("getChildrenRecursive()", "the childrenRecursive property"); + return GetChildrenRecursive()->NewProxy(true); } @@ -2304,7 +2322,7 @@ PyObject* KX_GameObject::PyGetAxisVect(PyObject* value) PyObject* KX_GameObject::PySetPosition(PyObject* value) { - ShowDeprecationWarning("setPosition()", "the position property"); + ShowDeprecationWarning("setPosition()", "the localPosition property"); MT_Point3 pos; if (PyVecTo(value, pos)) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index e0e78918dde..0011b8407fd 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -902,6 +902,8 @@ public: static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_meshes(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_children_recursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); /* Experemental! */ diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index b5b0839c0f4..3a6c62e7d23 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -45,11 +45,14 @@ class PyObjectPlus: class CValue(PyObjectPlus): """ This class is a basis for other classes. + @ivar name: The name of this CValue derived object (read-only). + @type name: string """ def getName(): """ Returns the name of the CValue. + @deprecated: Use the L{name} attribute instead. @note: in most cases the CValue's subclasses will override this function. @rtype: string """ @@ -1584,7 +1587,11 @@ class KX_GameObject(SCA_IObject): @type actuators: list @ivar attrDict: get the objects internal python attribute dictionary for direct (faster) access. @type attrDict: dict - @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh + @ivar children: direct children of this object, (read-only). + @type children: L{CListValue} of L{KX_GameObject}'s + @ivar childrenRecursive: all children of this object including childrens children, (read-only). + @type childrenRecursive: L{CListValue} of L{KX_GameObject}'s + @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh, getChildren, getChildrenRecursive """ def endObject(): """ @@ -1647,6 +1654,7 @@ class KX_GameObject(SCA_IObject): """ Sets the game object's position in world coordinates regardless if the object is root or child. + @deprecated: use L{worldPosition} @type pos: [x, y, z] @param pos: the new position, in world coordinates. """ @@ -2386,7 +2394,7 @@ class KX_MouseFocusSensor(SCA_MouseSensor): @ivar hitNormal: the worldspace normal from the face at point of intersection. @type hitNormal: list (normalized vector of 3 floats) """ - +#{ Deprecated def getHitNormal(): """ Returns the normal (in worldcoordinates) at the point of collision where the object was hit by this ray. @@ -2435,6 +2443,7 @@ class KX_MouseFocusSensor(SCA_MouseSensor): @rtype: list [x, y, z] @return: the ray target. """ +#} class KX_TouchSensor(SCA_ISensor): """ @@ -2736,8 +2745,7 @@ class KX_ObjectActuator(SCA_IActuator): @rtype: list [dx, dy, dz, local] @return: A four item list, containing the angular displacement vector, and whether - the displacement is applied in local coordinates (True) or world - coordinates (False) + the displacement is applied in local coordinates (True) or world coordinates (False) """ def setDRot(dx, dy, dz, local): """ @@ -3660,7 +3668,7 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator): # The mesh is a different mesh - switch it. # Check the current mesh is not a better fit. if curmesh == None or curmesh[1] < depth or curmesh[2] > depth: - act.setMesh(obj.getName() + newmesh[0]) + act.mesh = obj.getName() + newmesh[0] GameLogic.addActiveActuator(act, True) @warning: Replace mesh actuators will be ignored if at game start, the @@ -4008,7 +4016,7 @@ class KX_SoundActuator(SCA_IActuator): """ Sets the position this sound will come from. - @deprecated: Use the L{position} attribute instead. + @deprecated: Use the L{localPosition} attribute instead. @type x: float @param x: The x coordinate of the sound. @type y: float @@ -4120,6 +4128,7 @@ class KX_TrackToActuator(SCA_IActuator): @type use3D: boolean """ +#{ Deprecated def setObject(object): """ Sets the object to track. @@ -4168,6 +4177,7 @@ class KX_TrackToActuator(SCA_IActuator): @deprecated: Use the L{use3D} attribute instead. @rtype: boolean """ +#} class KX_VehicleWrapper(PyObjectPlus): """ From 9ce8a676906b6b07b0971f0d5886ae338d188629 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sun, 17 May 2009 20:37:13 +0000 Subject: [PATCH 261/444] BGE Dome: removing of size option and adding tilt option. - Size adjustments can be accomplished with warp mesh data now. So we get a free spot in the GUI for a tilt option. - Tilt option to tilt the camera (for planetarium domes). Angle is in degree from -180 to +180. It's needed for planetarium domes (as this one http://domejunky.blogspot.com/2009/05/dome-corrected-bge.html ). - This is the last commit regarding dome code I expected to 2.49. I consider this feature full implemented now. (working on docs now) --- source/blender/blenkernel/intern/scene.c | 2 +- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/makesdna/DNA_scene_types.h | 4 +- source/blender/src/buttons_scene.c | 8 +-- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 2 +- .../GamePlayer/ghost/GPG_Application.cpp | 2 +- source/gameengine/Ketsji/KX_Dome.cpp | 54 +++++++++++-------- source/gameengine/Ketsji/KX_Dome.h | 20 +++---- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 12 +---- source/gameengine/Ketsji/KX_KetsjiEngine.h | 2 +- 10 files changed, 54 insertions(+), 54 deletions(-) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index ed1a77d645e..df304568ed5 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -232,9 +232,9 @@ Scene *add_scene(char *name) sce->r.stereomode = 1; // no stereo sce->r.domeangle = 180; sce->r.domemode = 1; - sce->r.domesize = 1.0f; sce->r.domeres = 4; sce->r.domeresbuf = 1.0f; + sce->r.dometilt = 0; sce->r.simplify_subsurf= 6; sce->r.simplify_particles= 1.0f; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6c5a5bd551c..91557da7aa6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8082,9 +8082,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (sce= main->scene.first; sce; sce= sce->id.next) { sce->r.domeangle = 180; sce->r.domemode = 1; - sce->r.domesize = 1.0f; sce->r.domeres = 4; sce->r.domeresbuf = 1.0f; + sce->r.dometilt = 0; } /* DBVT culling by default */ for(wrld=main->world.first; wrld; wrld= wrld->id.next) { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index ac73ccc498c..36df11ac2e8 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -318,9 +318,9 @@ typedef struct RenderData { /* Dome variables */ short domeres, domemode; - short domeangle, pad9; - float domesize; + short domeangle, dometilt; float domeresbuf; + float pad2; struct Text *dometext; } RenderData; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index d140001ba2d..3036bb78da8 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1832,11 +1832,11 @@ static uiBlock *framing_render_menu(void *arg_unused) xco = 8; uiBlockBeginAlign(block); uiDefButS(block, ROW, 0, "Dome", xco, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 8.0, 0, 0, "Enables dome camera"); - uiDefButS(block, NUM, 0, "Ang:", xco+90, yco, 88, 19, &G.scene->r.domeangle, 90.0, 250.0, 0, 0, "Angle (Aperture) of the Dome - it only works in mode 1"); - uiDefButS(block, NUM, 0, "Mode:", xco+180, yco, 88, 19, &G.scene->r.domemode, 1.0, 3.0, 0, 0, "1 fisheye, 2 environment map, 3 spherical panoramic"); + uiDefButS(block, NUM, 0, "Ang:", xco+90, yco, 88, 19, &G.scene->r.domeangle, 90.0, 250.0, 0, 0, "Angle (Aperture) of the Dome - it only works in mode 1 to 3"); + uiDefButS(block, NUM, 0, "Mode:", xco+180, yco, 88, 19, &G.scene->r.domemode, 1.0, 5.0, 0, 0, "1 fulldome, 2 front-truncated, 3 rear-truncated, 4 environment map, 5 spherical panoramic"); - uiDefButF(block, NUM, 0, "Size:", xco, yco-=21, 88, 19, &G.scene->r.domesize, 0.5, 3.5, 0, 0, "Size adjustments"); - uiDefButS(block, NUM, 0, "Tes:", xco+90, yco, 88, 19, &G.scene->r.domeres, 1.0, 8.0, 0, 0, "Tesselation level - 1 to 8"); + uiDefButS(block, NUM, 0, "Tilt:", xco, yco-=21, 88, 19, &G.scene->r.dometilt, -180.0, 180.0, 0, 0, "Dome tilt - camera rotation in horizontal axis"); + uiDefButS(block, NUM, 0, "Tes:", xco+90, yco, 88, 19, &G.scene->r.domeres, 0.0, 8.0, 0, 0, "Tesselation level - check the generated mesh in wireframe mode"); uiDefButF(block, NUM, 0, "Res:", xco+180, yco, 88, 19, &G.scene->r.domeresbuf, 0.1, 1.0, 0, 0, "Buffer Resolution - decrease it to increase speed"); uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Warp Data: ", xco,yco-=21,268, 19, &G.scene->r.dometext, "Custom Warp Mesh data file"); diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 641938253b7..0e0377a7cb9 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -376,7 +376,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, //initialize Dome Settings if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) - ketsjiengine->InitDome(blscene->r.domesize, blscene->r.domeres, blscene->r.domemode, blscene->r.domeangle, blscene->r.domeresbuf, blscene->r.dometext); + ketsjiengine->InitDome(blscene->r.domeres, blscene->r.domemode, blscene->r.domeangle, blscene->r.domeresbuf, blscene->r.dometilt, blscene->r.dometext); if (sceneconverter) { diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index af8b94857b9..8a594f7365d 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -701,7 +701,7 @@ bool GPG_Application::startEngine(void) //initialize Dome Settings if(m_startScene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) - m_ketsjiengine->InitDome(m_startScene->r.domesize, m_startScene->r.domeres, m_startScene->r.domemode, m_startScene->r.domeangle, m_startScene->r.domeresbuf, m_startScene->r.dometext); + m_ketsjiengine->InitDome(m_startScene->r.domeres, m_startScene->r.domemode, m_startScene->r.domeangle, m_startScene->r.domeresbuf, m_startScene->r.dometilt, m_startScene->r.dometext); // Set the GameLogic.globalDict from marshal'd data, so we can // load new blend files and keep data in GameLogic.globalDict diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 25efe0a59c9..daa31379985 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -43,23 +43,23 @@ KX_Dome::KX_Dome ( RAS_IRenderTools* rendertools, /// engine KX_KetsjiEngine* engine, - - float size, //size for adjustments + short res, //resolution of the mesh short mode, //mode - fisheye, truncated, warped, panoramic, ... short angle, float resbuf, //size adjustment of the buffer + short tilt, struct Text* warptext ): dlistSupported(false), canvaswidth(-1), canvasheight(-1), m_drawingmode(engine->GetDrawType()), - m_size(size), m_resolution(res), m_mode(mode), m_angle(angle), m_resbuffer(resbuf), + m_tilt(tilt), m_canvas(canvas), m_rasterizer(rasterizer), m_rendertools(rendertools), @@ -124,7 +124,7 @@ KX_Dome::KX_Dome ( CreateMeshPanorama(); m_numfaces = 6; break; - default: //DOME_TRUNCATED_DOWN and DOME_TRUNCATED_UP + default: //DOME_TRUNCATED_FRONT and DOME_TRUNCATED_REAR if (m_angle <= 180){ cubetop.resize(1); cubebottom.resize(1); @@ -269,7 +269,7 @@ http://projects.blender.org/tracker/?func=detail&aid=18655&group_id=9&atid=125 bool KX_Dome::CreateDL(){ dlistId = glGenLists((GLsizei) m_numimages); if (dlistId != 0) { - if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_UP || m_mode == DOME_TRUNCATED_DOWN){ + if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_FRONT || m_mode == DOME_TRUNCATED_REAR){ glNewList(dlistId, GL_COMPILE); GLDrawTriangles(cubetop, nfacestop); glEndList(); @@ -1485,13 +1485,14 @@ Uses 4 cameras for angles up to 180 Uses 5 cameras for angles up to 250º Uses 6 cameras for angles up to 360º */ + int i; float deg45 = MT_PI / 4; MT_Scalar c = cos(deg45); MT_Scalar s = sin(deg45); if (m_angle <= 180 && (m_mode == DOME_FISHEYE - || m_mode == DOME_TRUNCATED_UP - || m_mode == DOME_TRUNCATED_DOWN)){ + || m_mode == DOME_TRUNCATED_FRONT + || m_mode == DOME_TRUNCATED_REAR)){ m_locRot[0] = MT_Matrix3x3( // 90º - Top c, -s, 0.0, @@ -1514,8 +1515,8 @@ Uses 6 cameras for angles up to 360 s, 0.0, c); } else if (m_mode == DOME_ENVMAP || (m_angle > 180 && (m_mode == DOME_FISHEYE - || m_mode == DOME_TRUNCATED_UP - || m_mode == DOME_TRUNCATED_DOWN))){ + || m_mode == DOME_TRUNCATED_FRONT + || m_mode == DOME_TRUNCATED_REAR))){ m_locRot[0] = MT_Matrix3x3( // 90º - Top 1.0, 0.0, 0.0, @@ -1579,6 +1580,23 @@ Uses 6 cameras for angles up to 360 0.0, 1.0, 0.0, s, 0.0, c); } + + // rotating the camera in horizontal axis + if (m_tilt) + { + float tiltdeg = ((m_tilt % 360) * 2 * MT_PI) / 360; + c = cos(tiltdeg); + s = sin(tiltdeg); + + MT_Matrix3x3 tilt_mat = MT_Matrix3x3( + 1.0, 0.0, 0.0, + 0.0, c, -s, + 0.0, s, c + ); + + for (i =0;i<6;i++) + m_locRot[i] = tilt_mat * m_locRot[i]; + } } void KX_Dome::RotateCamera(KX_Camera* cam, int i) @@ -1621,10 +1639,10 @@ void KX_Dome::Draw(void) case DOME_PANORAM_SPH: DrawPanorama(); break; - case DOME_TRUNCATED_UP: + case DOME_TRUNCATED_FRONT: DrawDomeFisheye(); break; - case DOME_TRUNCATED_DOWN: + case DOME_TRUNCATED_REAR: DrawDomeFisheye(); break; } @@ -1670,9 +1688,6 @@ void KX_Dome::DrawEnvMap(void) ortho_width = (float)can_width/can_height * ortho_height; } - ortho_width /= m_size; - ortho_height /= m_size; - glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); } @@ -1803,20 +1818,17 @@ void KX_Dome::DrawDomeFisheye(void) ortho_height = 1.0; } - ortho_width /= m_size; - ortho_height /= m_size; - glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); } } - else if(m_mode == DOME_TRUNCATED_UP) + else if(m_mode == DOME_TRUNCATED_FRONT) { ortho_width = 1.0; ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0); } - else { //m_mode == DOME_TRUNCATED_DOWN + else { //m_mode == DOME_TRUNCATED_REAR ortho_width = 1.0; ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; @@ -1901,9 +1913,6 @@ void KX_Dome::DrawPanorama(void) ortho_width = (float)can_width/can_height * 0.5; ortho_height = 0.5; } - - ortho_width /= m_size; - ortho_height /= m_size; glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); } @@ -1972,7 +1981,6 @@ void KX_Dome::DrawDomeWarped(void) int can_height = m_viewport.GetTop(); double screen_ratio = can_width/ (double) can_height; - screen_ratio /= m_size; glOrtho(-screen_ratio,screen_ratio,-1.0,1.0,-20.0,10.0); diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 30d02dce7a0..032098d38ad 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -40,12 +40,12 @@ Developed as part of a Research and Development project for SAT - La Soci #include "BKE_text.h" //Dome modes: limit hardcoded in buttons_scene.c -#define DOME_FISHEYE 1 -#define DOME_ENVMAP 2 -#define DOME_PANORAM_SPH 3 -#define DOME_TRUNCATED_UP 4 -#define DOME_TRUNCATED_DOWN 5 -#define DOME_NUM_MODES 6 +#define DOME_FISHEYE 1 +#define DOME_TRUNCATED_FRONT 2 +#define DOME_TRUNCATED_REAR 3 +#define DOME_ENVMAP 4 +#define DOME_PANORAM_SPH 5 +#define DOME_NUM_MODES 6 /// class for render 3d scene @@ -61,12 +61,12 @@ public: RAS_IRenderTools* m_rendertools, /// engine KX_KetsjiEngine* m_engine, - - float size, + short res, short mode, short angle, float resbuf, + short tilt, struct Text* warptext ); @@ -159,13 +159,13 @@ protected: int m_buffersize; // canvas small dimension int m_numfaces; // 4 to 6 depending on the kind of dome image int m_numimages; //numfaces +1 if we have warp mesh - - float m_size; // size to adjust + short m_resolution; //resolution to tesselate the mesh short m_mode; // the mode (truncated, warped, panoramic,...) short m_angle; //the angle of the fisheye float m_radangle; //the angle of the fisheye in radians float m_resbuffer; //the resolution of the buffer + short m_tilt; //the dome tilt (camera rotation on horizontal axis) RAS_Rect m_viewport; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index e773a9571f1..4107ed7d82e 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -262,9 +262,9 @@ void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter) m_sceneconverter = sceneconverter; } -void KX_KetsjiEngine::InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text) +void KX_KetsjiEngine::InitDome(short res, short mode, short angle, float resbuf, short tilt, struct Text* text) { - m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, size, res, mode, angle, resbuf, text); + m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, res, mode, angle, resbuf, tilt, text); m_usedome = true; } @@ -272,7 +272,6 @@ void KX_KetsjiEngine::RenderDome() { GLuint viewport[4]={0}; glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); -// unsigned int m_viewport[4] = {viewport[0], viewport[1], viewport[2], viewport[3]}; m_dome->SetViewPort(viewport); @@ -297,13 +296,6 @@ void KX_KetsjiEngine::RenderDome() KX_SceneList::iterator sceneit; - // This is now done incrementally in KX_Scene::CalculateVisibleMeshes() - //for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) - //{ - // // do this only once per scene - // (*sceneit)->UpdateMeshTransformations(); - //} - int n_renders=m_dome->GetNumberRenders();// usually 4 or 6 for (int i=0;iClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 528465b6c2c..cc9b9198db7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -211,7 +211,7 @@ public: RAS_IRenderTools* GetRenderTools(){return m_rendertools;}; /// Dome functions - void InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text); + void InitDome(short res, short mode, short angle, float resbuf, short tilt, struct Text* text); void EndDome(); void RenderDome(); bool m_usedome; From 9a40f4d2a63183edb741bd5280b27aa068773d92 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 17 May 2009 21:50:31 +0000 Subject: [PATCH 262/444] BGE: bookmark option on controller to make them run before all other controllers. A new bookmark button is available on the controller UI. When set, the controller is guaranteed to execute before all other non-bookmarked controllers, provided it is scheduled for execution. This is useful for initialization scripts that run once at startup or scripts that must set some prerequisite for the other controllers at the start of each logic frame. This feature is also available at python level with the "bookmark" attribute. It can be changed during the game. Note that if several script are bookmarked, their relative order of execution is not guaranteed. Make sure they don't depend on each other. --- source/blender/makesdna/DNA_controller_types.h | 1 + source/blender/src/buttons_logic.c | 5 +++-- .../Converter/KX_ConvertControllers.cpp | 1 + .../gameengine/GameLogic/SCA_IController.cpp | 1 + source/gameengine/GameLogic/SCA_IController.h | 18 +++++++++++++++--- source/gameengine/GameLogic/SCA_IObject.cpp | 3 +-- source/gameengine/GameLogic/SCA_IObject.h | 7 ++++++- source/gameengine/Ketsji/KX_StateActuator.h | 11 +++++++++++ source/gameengine/PyDoc/GameTypes.py | 4 ++++ 9 files changed, 43 insertions(+), 8 deletions(-) diff --git a/source/blender/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h index b3c82e746c1..599bbf9653a 100644 --- a/source/blender/makesdna/DNA_controller_types.h +++ b/source/blender/makesdna/DNA_controller_types.h @@ -79,6 +79,7 @@ typedef struct bController { #define CONT_DEL 2 #define CONT_NEW 4 #define CONT_MASK 8 +#define CONT_PRIO 16 /* pyctrl->flag */ #define CONT_PY_DEBUG 1 diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index a537d32feae..b229fe440a5 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3788,6 +3788,7 @@ void logic_buts(void) uiBlockSetEmboss(block, UI_EMBOSSM); uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller"); uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings"); + uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Bookmarl controller to run before all other non-bookmarked controllers on each logic frame"); uiBlockSetEmboss(block, UI_EMBOSSP); sprintf(name, "%d", first_bit(cont->state_mask)+1); uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)"); @@ -3796,7 +3797,7 @@ void logic_buts(void) if(cont->flag & CONT_SHOW) { cont->otype= cont->type; uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, 19, &cont->type, 0, 0, 0, 0, "Controller type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-136), 19, cont->name, 0, 31, 0, 0, "Controller name"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), 19, cont->name, 0, 31, 0, 0, "Controller name"); uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0); ycoo= yco; @@ -3808,7 +3809,7 @@ void logic_buts(void) glRecti(xco+22, yco, xco+width-22,yco+19); but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, 19, cont, 0, 0, 0, 0, "Controller type"); uiButSetFunc(but, sca_move_controller, cont, NULL); - but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-136), 19, cont, 0, 0, 0, 0, "Controller name"); + but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), 19, cont, 0, 0, 0, 0, "Controller name"); uiButSetFunc(but, sca_move_controller, cont, NULL); ycoo= yco; } diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp index 9b0e27b573a..85ab8e4f8b8 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.cpp +++ b/source/gameengine/Converter/KX_ConvertControllers.cpp @@ -199,6 +199,7 @@ void BL_ConvertControllers( { LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter); gamecontroller->SetExecutePriority(executePriority++); + gamecontroller->SetBookmark((bcontr->flag & CONT_PRIO) != 0); gamecontroller->SetState(bcontr->state_mask); STR_String uniquename = bcontr->name; uniquename += "#CONTR#"; diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index f8b081ef050..84a6bfb8085 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -244,6 +244,7 @@ PyAttributeDef SCA_IController::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state), KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors), KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators), + KX_PYATTRIBUTE_BOOL_RW("bookmark",SCA_IController,m_bookmark), { NULL } //Sentinel }; diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 1b9d8fb0d2b..a52c57ab3ed 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -45,6 +45,7 @@ protected: std::vector m_linkedactuators; unsigned int m_statemask; bool m_justActivated; + bool m_bookmark; public: SCA_IController(SCA_IObject* gameobj,PyTypeObject* T); virtual ~SCA_IController(); @@ -76,13 +77,24 @@ public: { m_justActivated = false; } - + void SetBookmark(bool bookmark) + { + m_bookmark = bookmark; + } void Activate(SG_DList& head) { if (QEmpty()) { - InsertActiveQList(m_gameobj->m_activeControllers); - head.AddBack(&m_gameobj->m_activeControllers); + if (m_bookmark) + { + m_gameobj->m_activeBookmarkedControllers.QAddBack(this); + head.AddFront(&m_gameobj->m_activeBookmarkedControllers); + } + else + { + InsertActiveQList(m_gameobj->m_activeControllers); + head.AddBack(&m_gameobj->m_activeControllers); + } } } diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 8962c8e8580..2b87a7c1526 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -39,13 +39,12 @@ #endif MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0); +SG_QList SCA_IObject::m_activeBookmarkedControllers; SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0) { m_suspended = false; } - - SCA_IObject::~SCA_IObject() { diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 281c72ecd46..c4f346059d4 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -64,11 +64,16 @@ protected: // SG_QList: Head of active actuators list on this object // Elements: SCA_IActuator SG_QList m_activeActuators; - // SG_Dlist: element of objects with active controllers + // SG_Dlist: element of list os lists with active controllers // Head: SCA_LogicManager::m_activeControllers // SG_QList: Head of active controller list on this object // Elements: SCA_IController SG_QList m_activeControllers; + // SG_Dlist: element of list of lists of active controllers + // Head: SCA_LogicManager::m_activeControllers + // SG_QList: Head of active bookmarked controller list globally + // Elements: SCA_IController with bookmark option + static SG_QList m_activeBookmarkedControllers; static class MT_Point3 m_sDummy; diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index 57303ad403f..a4191a4c5fd 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -33,6 +33,13 @@ #include "SCA_IActuator.h" + +/* + * Use of SG_DList : element of actuator being deactivated + * Head: SCA_LogicManager::m_removedActuators + * Use of SG_QList : element of global activated state actuator list + * Head: KX_StateActuator::m_stateActuatorHead + */ class KX_StateActuator : public SCA_IActuator { Py_Header; @@ -46,6 +53,10 @@ class KX_StateActuator : public SCA_IActuator OP_NEG, OP_COUNT }; + // SG_Dlist: element of objects with active actuators, always put in front of the list + // Head: SCA_LogicManager::m_activeActuators + // SG_QList: Head of active state actuators list globally + // Elements: KX_StateActuator static SG_QList m_stateActuatorHead; int m_operation; int m_mask; diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 3a6c62e7d23..ca02b1a2798 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -240,6 +240,10 @@ class SCA_IController(SCA_ILogicBrick): - note: the sensors are not necessarily owned by the same object. - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. @type actuators: sequence supporting index/string lookups and iteration. + @ivar bookmark: the bookmark option. + If set, the controller executes always before all other non-bookmarked controllers. + - note: Order of execution between bookmarked controllers is not guaranteed. + @type bookmark: bool """ #{ Deprecated def getState(): From 5a16f0b60cf373016881d1ce2d67a84b4121f265 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 May 2009 04:11:54 +0000 Subject: [PATCH 263/444] Bugfix for FBX export for animations in 2.48 constant interpolations meant that wasnt a problem but since it now uses linear interp. you can notice errors with animated characters because the 2 eulers are not compatible. Added optional euler_compat argument to matrix.toEuler(eul) and quat.toEuler(eul) so when getting the euler rotations from a list of matrices the animation curve will be continues. Also added euler.makeCompatible(euler). - warning silenced for imagepaint.c --- release/scripts/export_fbx.py | 14 +++++++-- .../blender/python/api2_2x/doc/Mathutils.py | 14 +++++++-- source/blender/python/api2_2x/euler.c | 29 ++++++++++++++++++- source/blender/python/api2_2x/euler.h | 1 + source/blender/python/api2_2x/matrix.c | 27 ++++++++++++----- source/blender/python/api2_2x/matrix.h | 2 +- source/blender/python/api2_2x/quat.c | 28 ++++++++++++++---- source/blender/python/api2_2x/quat.h | 2 +- source/blender/src/imagepaint.c | 3 +- 9 files changed, 100 insertions(+), 20 deletions(-) diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index d2028c22468..52d1f3a62f3 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -2591,8 +2591,18 @@ Takes: {''') for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats] - elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats] - else: context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats] + elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats] + elif TX_CHAN=='R': + # Was.... + # elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats] + # + # ...but we need to use the previous euler for compatible conversion. + context_bone_anim_vecs = [] + prev_eul = None + for mtx in context_bone_anim_mats: + if prev_eul: prev_eul = mtx[1].toEuler(prev_eul) + else: prev_eul = mtx[1].toEuler() + context_bone_anim_vecs.append(prev_eul) file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index d8492558317..52cd5fbcc7f 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -617,6 +617,12 @@ class Euler: @rtype: Quaternion object @return: Quaternion representation of the euler. """ + def makeCompatible(eul_compat): + """ + Make this euler compatible with another, so interpolating between them works as expected. + @rtype: Euler object + @return: an instance of itself + """ class Quaternion: """ @@ -718,9 +724,11 @@ class Quaternion: @return: an instance of itself """ - def toEuler(): + def toEuler(eul_compat): """ Return Euler representation of the quaternion. + @type eul_compat: L{Euler} + @param eul_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves. @rtype: Euler object @return: Euler representation of the quaternion. """ @@ -870,9 +878,11 @@ class Matrix: @return: an instance of itself. """ - def toEuler(): + def toEuler(eul_compat): """ Return an Euler representation of the rotation matrix (3x3 or 4x4 matrix only). + @type eul_compat: L{Euler} + @param eul_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves. @rtype: Euler object @return: Euler representation of the rotation matrix. """ diff --git a/source/blender/python/api2_2x/euler.c b/source/blender/python/api2_2x/euler.c index 23f82fc0eb0..ae7eeed5d33 100644 --- a/source/blender/python/api2_2x/euler.c +++ b/source/blender/python/api2_2x/euler.c @@ -40,6 +40,7 @@ char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the eul char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation"; char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation"; char Euler_copy_doc[] = "() - returns a copy of the euler."; +char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping)."; //-----------------------METHOD DEFINITIONS ---------------------- struct PyMethodDef Euler_methods[] = { {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc}, @@ -47,6 +48,7 @@ struct PyMethodDef Euler_methods[] = { {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc}, {"toQuat", (PyCFunction) Euler_ToQuat, METH_NOARGS, Euler_ToQuat_doc}, {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, Euler_Rotate_doc}, + {"makeCompatible", (PyCFunction) Euler_MakeCompatible, METH_O, Euler_MakeCompatible_doc}, {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, {"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, {NULL, NULL, 0, NULL} @@ -173,6 +175,32 @@ PyObject *Euler_Rotate(EulerObject * self, PyObject *args) Py_INCREF(self); return (PyObject *)self; } + +PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) +{ + float eul_from_rad[3]; + int x; + + if(!EulerObject_Check(value)) { + PyErr_SetString(PyExc_TypeError, "euler.makeCompatible(euler):expected a single euler argument."); + return NULL; + } + + //covert to radians + for(x = 0; x < 3; x++) { + self->eul[x] = self->eul[x] * ((float)Py_PI / 180); + eul_from_rad[x] = value->eul[x] * ((float)Py_PI / 180); + } + compatible_eul(self->eul, eul_from_rad); + //convert back from radians + for(x = 0; x < 3; x++) { + self->eul[x] *= (180 / (float)Py_PI); + } + + Py_INCREF(self); + return (PyObject *)self; +} + //----------------------------Euler.rotate()----------------------- // return a copy of the euler PyObject *Euler_copy(EulerObject * self, PyObject *args) @@ -528,4 +556,3 @@ PyObject *newEulerObject(float *eul, int type) } return (PyObject *)self; } - diff --git a/source/blender/python/api2_2x/euler.h b/source/blender/python/api2_2x/euler.h index b76eb962baa..5a5a84074a7 100644 --- a/source/blender/python/api2_2x/euler.h +++ b/source/blender/python/api2_2x/euler.h @@ -58,6 +58,7 @@ PyObject *Euler_Unique( EulerObject * self ); PyObject *Euler_ToMatrix( EulerObject * self ); PyObject *Euler_ToQuat( EulerObject * self ); PyObject *Euler_Rotate( EulerObject * self, PyObject *args ); +PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value ); PyObject *Euler_copy( EulerObject * self, PyObject *args ); PyObject *newEulerObject( float *eul, int type ); diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c index 659f746468a..07f67c1c15f 100644 --- a/source/blender/python/api2_2x/matrix.c +++ b/source/blender/python/api2_2x/matrix.c @@ -41,7 +41,7 @@ char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the trans char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix"; char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector"; char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix"; -char Matrix_toEuler_doc[] = "() - convert matrix to a euler angle rotation"; +char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with."; char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation"; char Matrix_copy_doc[] = "() - return a copy of the matrix"; /*-----------------------METHOD DEFINITIONS ----------------------*/ @@ -55,7 +55,7 @@ struct PyMethodDef Matrix_methods[] = { {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc}, {"scalePart", (PyCFunction) Matrix_scalePart, METH_NOARGS, Matrix_scalePart_doc}, {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc}, - {"toEuler", (PyCFunction) Matrix_toEuler, METH_NOARGS, Matrix_toEuler_doc}, + {"toEuler", (PyCFunction) Matrix_toEuler, METH_VARARGS, Matrix_toEuler_doc}, {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc}, {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, @@ -81,19 +81,32 @@ PyObject *Matrix_toQuat(MatrixObject * self) return newQuaternionObject(quat, Py_NEW); } /*---------------------------Matrix.toEuler() --------------------*/ -PyObject *Matrix_toEuler(MatrixObject * self) +PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args) { - float eul[3]; - + float eul[3], eul_compatf[3]; + EulerObject *eul_compat = NULL; int x; - + + if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat)) + return NULL; + + if(eul_compat) { + for(x = 0; x < 3; x++) { + eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180); + } + } + /*must be 3-4 cols, 3-4 rows, square matrix*/ if(self->colSize ==3 && self->rowSize ==3) { - Mat3ToEul((float (*)[3])*self->matrix, eul); + if(eul_compat) Mat3ToCompatibleEul((float (*)[3])*self->matrix, eul, eul_compatf); + else Mat3ToEul((float (*)[3])*self->matrix, eul); }else if (self->colSize ==4 && self->rowSize ==4) { float tempmat3[3][3]; Mat3CpyMat4(tempmat3, (float (*)[4])*self->matrix); Mat3ToEul(tempmat3, eul); + if(eul_compat) Mat3ToCompatibleEul(tempmat3, eul, eul_compatf); + else Mat3ToEul(tempmat3, eul); + }else { PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); return NULL; diff --git a/source/blender/python/api2_2x/matrix.h b/source/blender/python/api2_2x/matrix.h index 8e6bfc0674e..130977742f1 100644 --- a/source/blender/python/api2_2x/matrix.h +++ b/source/blender/python/api2_2x/matrix.h @@ -69,7 +69,7 @@ PyObject *Matrix_TranslationPart( MatrixObject * self ); PyObject *Matrix_RotationPart( MatrixObject * self ); PyObject *Matrix_scalePart( MatrixObject * self ); PyObject *Matrix_Resize4x4( MatrixObject * self ); -PyObject *Matrix_toEuler( MatrixObject * self ); +PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args ); PyObject *Matrix_toQuat( MatrixObject * self ); PyObject *Matrix_copy( MatrixObject * self ); PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type); diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c index 9c718d95c63..14fd5f9ba4c 100644 --- a/source/blender/python/api2_2x/quat.c +++ b/source/blender/python/api2_2x/quat.c @@ -39,7 +39,7 @@ char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their n char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate"; char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse"; char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion"; -char Quaternion_ToEuler_doc[] = "() - return a euler rotation representing the quaternion"; +char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with."; char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion"; char Quaternion_copy_doc[] = "() - return a copy of the quat"; //-----------------------METHOD DEFINITIONS ---------------------- @@ -49,7 +49,7 @@ struct PyMethodDef Quaternion_methods[] = { {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc}, {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, Quaternion_Inverse_doc}, {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, Quaternion_Normalize_doc}, - {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_NOARGS, Quaternion_ToEuler_doc}, + {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, Quaternion_ToEuler_doc}, {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, Quaternion_ToMatrix_doc}, {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, @@ -58,12 +58,30 @@ struct PyMethodDef Quaternion_methods[] = { //-----------------------------METHODS------------------------------ //----------------------------Quaternion.toEuler()------------------ //return the quat as a euler -PyObject *Quaternion_ToEuler(QuaternionObject * self) +PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) { float eul[3]; + EulerObject *eul_compat = NULL; int x; - - QuatToEul(self->quat, eul); + + if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat)) + return NULL; + + if(eul_compat) { + float mat[3][3], eul_compatf[3]; + + for(x = 0; x < 3; x++) { + eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180); + } + + QuatToMat3(self->quat, mat); + Mat3ToCompatibleEul(mat, eul, eul_compatf); + } + else { + QuatToEul(self->quat, eul); + } + + for(x = 0; x < 3; x++) { eul[x] *= (180 / (float)Py_PI); } diff --git a/source/blender/python/api2_2x/quat.h b/source/blender/python/api2_2x/quat.h index ac70b4e3802..9f3a919bce0 100644 --- a/source/blender/python/api2_2x/quat.h +++ b/source/blender/python/api2_2x/quat.h @@ -62,7 +62,7 @@ PyObject *Quaternion_Negate( QuaternionObject * self ); PyObject *Quaternion_Conjugate( QuaternionObject * self ); PyObject *Quaternion_Inverse( QuaternionObject * self ); PyObject *Quaternion_Normalize( QuaternionObject * self ); -PyObject *Quaternion_ToEuler( QuaternionObject * self ); +PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args ); PyObject *Quaternion_ToMatrix( QuaternionObject * self ); PyObject *Quaternion_copy( QuaternionObject * self ); PyObject *newQuaternionObject( float *quat, int type ); diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 37670d09749..1a6eb10b00b 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -2603,7 +2603,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i if (!is_ortho) { pixelScreenCo[3] = 1.0f; - Mat4MulVec4fl(ps->projectMat, pixelScreenCo); + Mat4MulVec4fl((float (*)[4])*ps->projectMat, pixelScreenCo); pixelScreenCo[0] = (float)(curarea->winx/2.0f)+(curarea->winx/2.0f)*pixelScreenCo[0]/pixelScreenCo[3]; pixelScreenCo[1] = (float)(curarea->winy/2.0f)+(curarea->winy/2.0f)*pixelScreenCo[1]/pixelScreenCo[3]; pixelScreenCo[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth for bucket point occlusion */ @@ -4664,3 +4664,4 @@ void imagepaint_pick(short mousebutton) sample_vpaint(); } + From bd7b92bfb5be39cac141a560f083ec0241cb4474 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 May 2009 04:33:33 +0000 Subject: [PATCH 264/444] Need to export the mesh-object into the bind-pose otherwise Maya complains the FBX has errors. --- release/scripts/export_fbx.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 52d1f3a62f3..4115140a852 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -1364,7 +1364,8 @@ def write(filename, batch_objects = None, \ file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) file.write('\n\t\tVersion: 232') # newline is added in write_object_props - write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix()) + poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3] + pose_items.append((my_mesh.fbxName, poseMatrix)) file.write('\n\t\t}') file.write('\n\t\tMultiLayer: 0') From 3bda88babfd422e2b40377d8d3be9a4bda7ed997 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 18 May 2009 07:53:13 +0000 Subject: [PATCH 265/444] cmake: apply patch to link with correct python library in win32 debug mode. --- CMake/macros.cmake | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CMake/macros.cmake b/CMake/macros.cmake index 95799a2c1fd..e4ba662eefb 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -59,7 +59,24 @@ ENDMACRO(SETUP_LIBDIRS) MACRO(SETUP_LIBLINKS target) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ") - TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + + TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + + # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions + + IF(WIN32) + + TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d) + + TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB}) + + ELSE(WIN32) + + TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB}) + + ENDIF(WIN32) + IF(WITH_INTERNATIONAL) TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIB}) TARGET_LINK_LIBRARIES(${target} ${GETTEXT_LIB}) From 07fc2aa5268da7708a289fa785b0f0cbd9be2575 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 18 May 2009 08:22:51 +0000 Subject: [PATCH 266/444] BGE #18665: Servo control and relative motion Servo control motion actuator did not work as expected when the object is moving on a moving platform. This patch introduces a new Ref field in the servo motion actuator to set a reference object for the velocity calculation. You can set the object during the game using the actuator "reference" attribute; use an object name or an object reference. The servo controller takes into account the angular velocity of the reference object to compute the relative local velocity. --- source/blender/blenkernel/intern/sca.c | 9 ++ source/blender/blenloader/intern/readfile.c | 17 ++++ source/blender/makesdna/DNA_actuator_types.h | 1 + source/blender/src/buttons_logic.c | 52 ++++++------ .../Converter/KX_ConvertActuators.cpp | 7 +- .../gameengine/Ketsji/KX_ObjectActuator.cpp | 83 ++++++++++++++++++- source/gameengine/Ketsji/KX_ObjectActuator.h | 12 ++- source/gameengine/PyDoc/GameTypes.py | 2 + 8 files changed, 154 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index bbca97d75f7..ea7b566c3b5 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -579,6 +579,10 @@ void set_sca_new_poins_ob(Object *ob) bCameraActuator *ca= act->data; ID_NEW(ca->ob); } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + ID_NEW(oa->reference); + } else if(act->type==ACT_SCENE) { bSceneActuator *sca= act->data; ID_NEW(sca->camera); @@ -606,6 +610,7 @@ void sca_remove_ob_poin(Object *obt, Object *ob) bMessageSensor *ms; bActuator *act; bCameraActuator *ca; + bObjectActuator *oa; bSceneActuator *sa; bEditObjectActuator *eoa; bPropertyActuator *pa; @@ -628,6 +633,10 @@ void sca_remove_ob_poin(Object *obt, Object *ob) ca= act->data; if(ca->ob==ob) ca->ob= NULL; break; + case ACT_OBJECT: + oa= act->data; + if(oa->reference==ob) oa->reference= NULL; + break; case ACT_PROPERTY: pa= act->data; if(pa->ob==ob) pa->ob= NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 91557da7aa6..0f233410f4e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3077,6 +3077,10 @@ static void lib_link_object(FileData *fd, Main *main) bAddObjectActuator *eoa= act->data; if(eoa) eoa->ob= newlibadr(fd, ob->id.lib, eoa->ob); } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + oa->reference= newlibadr(fd, ob->id.lib, oa->reference); + } else if(act->type==ACT_EDIT_OBJECT) { bEditObjectActuator *eoa= act->data; if(eoa==NULL) { @@ -3087,6 +3091,15 @@ static void lib_link_object(FileData *fd, Main *main) eoa->me= newlibadr(fd, ob->id.lib, eoa->me); } } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + if(oa==NULL) { + init_actuator(act); + } + else { + oa->reference= newlibadr(fd, ob->id.lib, oa->reference); + } + } else if(act->type==ACT_SCENE) { bSceneActuator *sa= act->data; sa->camera= newlibadr(fd, ob->id.lib, sa->camera); @@ -8862,6 +8875,10 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) expand_doit(fd, mainvar, eoa->me); } } + else if(act->type==ACT_OBJECT) { + bObjectActuator *oa= act->data; + expand_doit(fd, mainvar, oa->reference); + } else if(act->type==ACT_SCENE) { bSceneActuator *sa= act->data; expand_doit(fd, mainvar, sa->camera); diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index aeabae42adf..81c02779cba 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -107,6 +107,7 @@ typedef struct bObjectActuator { float loc[3], rot[3]; float dloc[3], drot[3]; float linearvelocity[3], angularvelocity[3]; + struct Object *reference; } bObjectActuator; typedef struct bIpoActuator { diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index b229fe440a5..605568680ba 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1830,42 +1830,44 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh } } else if (oa->type == ACT_OBJECT_SERVO) { - ysize= 172; + ysize= 195; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, LABEL, 0, "linV", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the target linear velocity, it will be achieve by automatic application of force. Null velocity is a valid target"); - uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); - uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates"); + uiDefBut(block, LABEL, 0, "Ref", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, ""); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+45, yco-45, wval*3, 19, &(oa->reference), "Reference object for velocity calculation, leave empty for world reference"); + uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Sets the target relative linear velocity, it will be achieve by automatic application of force. Null velocity is a valid target"); + uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-68, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates"); - uiDefBut(block, LABEL, 0, "Limit", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Select if the force need to be limited along certain axis (local or global depending on LinV Local flag)"); - uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X", xco+45, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis"); - uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y", xco+45+wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis"); - uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z", xco+45+2*wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis"); - uiDefBut(block, LABEL, 0, "Max", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force"); - uiDefBut(block, LABEL, 0, "Min", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force"); + uiDefBut(block, LABEL, 0, "Limit", xco, yco-91, 45, 19, NULL, 0, 0, 0, 0, "Select if the force need to be limited along certain axis (local or global depending on LinV Local flag)"); + uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X", xco+45, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis"); + uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y", xco+45+wval, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis"); + uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z", xco+45+2*wval, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis"); + uiDefBut(block, LABEL, 0, "Max", xco, yco-110, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force"); + uiDefBut(block, LABEL, 0, "Min", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force"); if (oa->flag & ACT_SERVO_LIMIT_X) { - uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45, yco-110, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); } if (oa->flag & ACT_SERVO_LIMIT_Y) { - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-110, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); } if (oa->flag & ACT_SERVO_LIMIT_Z) { - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-110, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); } - uiDefBut(block, LABEL, 0, "Servo", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller"); - uiDefButF(block, NUMSLI, B_REDR, "P: ", xco+45, yco-129, wval*3, 19, oa->forcerot, 0.00, 200.0, 100, 0, "Proportional coefficient, typical value is 60x Integral coefficient"); - uiDefBut(block, LABEL, 0, "Slow", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response"); - but = uiDefButF(block, NUMSLI, B_REDR, " I : ", xco+45, yco-148, wval*3, 19, oa->forcerot+1, 0.0, 3.0, 1, 0, "Integral coefficient, low value (0.01) for slow response, high value (0.5) for fast response"); + uiDefBut(block, LABEL, 0, "Servo", xco, yco-152, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller"); + uiDefButF(block, NUMSLI, B_REDR, "P: ", xco+45, yco-152, wval*3, 19, oa->forcerot, 0.00, 200.0, 100, 0, "Proportional coefficient, typical value is 60x Integral coefficient"); + uiDefBut(block, LABEL, 0, "Slow", xco, yco-152, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response"); + but = uiDefButF(block, NUMSLI, B_REDR, " I : ", xco+45, yco-171, wval*3, 19, oa->forcerot+1, 0.0, 3.0, 1, 0, "Integral coefficient, low value (0.01) for slow response, high value (0.5) for fast response"); uiButSetFunc(but, update_object_actuator_PID, oa, NULL); - uiDefBut(block, LABEL, 0, "Fast", xco+45+3*wval, yco-148, 45, 19, NULL, 0, 0, 0, 0, "High value of I coefficient correspond to fast response"); - uiDefButF(block, NUMSLI, B_REDR, "D: ", xco+45, yco-167, wval*3, 19, oa->forcerot+2, -100.0, 100.0, 100, 0, "Derivate coefficient, not required, high values can cause instability"); + uiDefBut(block, LABEL, 0, "Fast", xco+45+3*wval, yco-171, 45, 19, NULL, 0, 0, 0, 0, "High value of I coefficient correspond to fast response"); + uiDefButF(block, NUMSLI, B_REDR, "D: ", xco+45, yco-190, wval*3, 19, oa->forcerot+2, -100.0, 100.0, 100, 0, "Derivate coefficient, not required, high values can cause instability"); } str= "Motion Type %t|Simple motion %x0|Servo Control %x1"; but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &oa->type, 0.0, 0.0, 0, 0, ""); @@ -3788,7 +3790,7 @@ void logic_buts(void) uiBlockSetEmboss(block, UI_EMBOSSM); uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller"); uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings"); - uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Bookmarl controller to run before all other non-bookmarked controllers on each logic frame"); + uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Bookmarl controller to run before all other non-bookmarked controllers"); uiBlockSetEmboss(block, UI_EMBOSSP); sprintf(name, "%d", first_bit(cont->state_mask)+1); uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)"); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 60d64621665..98df34aa4a9 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -134,6 +134,7 @@ void BL_ConvertActuators(char* maggiename, case ACT_OBJECT: { bObjectActuator* obact = (bObjectActuator*) bact->data; + KX_GameObject* obref = NULL; MT_Vector3 forcevec(KX_BLENDERTRUNC(obact->forceloc[0]), KX_BLENDERTRUNC(obact->forceloc[1]), KX_BLENDERTRUNC(obact->forceloc[2])); @@ -171,9 +172,13 @@ void BL_ConvertActuators(char* maggiename, bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0); bitLocalFlag.ServoControl = bool(obact->type == ACT_OBJECT_SERVO); bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0); - + if (obact->reference && bitLocalFlag.ServoControl) + { + obref = converter->FindGameObject(obact->reference); + } KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(gameobj, + obref, forcevec.getValue(), torquevec.getValue(), dlocvec.getValue(), diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index 0232e3407b0..eaae04d406d 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -45,6 +45,7 @@ KX_ObjectActuator:: KX_ObjectActuator( SCA_IObject* gameobj, + KX_GameObject* refobj, const MT_Vector3& force, const MT_Vector3& torque, const MT_Vector3& dloc, @@ -69,6 +70,7 @@ KX_ObjectActuator( m_previous_error(0.0,0.0,0.0), m_error_accumulator(0.0,0.0,0.0), m_bitLocalFlag (flag), + m_reference(refobj), m_active_combined_velocity (false), m_linear_damping_active(false), m_angular_damping_active(false) @@ -80,10 +82,17 @@ KX_ObjectActuator( m_pid = m_torque; } - + if (m_reference) + m_reference->RegisterActuator(this); UpdateFuzzyFlags(); } +KX_ObjectActuator::~KX_ObjectActuator() +{ + if (m_reference) + m_reference->UnregisterActuator(this); +} + bool KX_ObjectActuator::Update() { @@ -132,6 +141,18 @@ bool KX_ObjectActuator::Update() if (mass < MT_EPSILON) return false; MT_Vector3 v = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity); + if (m_reference) + { + const MT_Point3& mypos = parent->NodeGetWorldPosition(); + const MT_Point3& refpos = m_reference->NodeGetWorldPosition(); + MT_Point3 relpos; + relpos = (mypos-refpos); + MT_Vector3 vel= m_reference->GetVelocity(relpos); + if (m_bitLocalFlag.LinearVelocity) + // must convert in local space + vel = parent->NodeGetWorldOrientation().transposed()*vel; + v -= vel; + } MT_Vector3 e = m_linear_velocity - v; MT_Vector3 dv = e - m_previous_error; MT_Vector3 I = m_error_accumulator + e; @@ -260,7 +281,34 @@ CValue* KX_ObjectActuator::GetReplica() return replica; } +void KX_ObjectActuator::ProcessReplica() +{ + SCA_IActuator::ProcessReplica(); + if (m_reference) + m_reference->RegisterActuator(this); +} +bool KX_ObjectActuator::UnlinkObject(SCA_IObject* clientobj) +{ + if (clientobj == (SCA_IObject*)m_reference) + { + // this object is being deleted, we cannot continue to use it as reference. + m_reference = NULL; + return true; + } + return false; +} + +void KX_ObjectActuator::Relink(GEN_Map *obj_map) +{ + void **h_obj = (*obj_map)[m_reference]; + if (h_obj) { + if (m_reference) + m_reference->UnregisterActuator(this); + m_reference = (KX_GameObject*)(*h_obj); + m_reference->RegisterActuator(this); + } +} /* some 'standard' utilities... */ bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type) @@ -357,6 +405,7 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("forceLimitY", KX_ObjectActuator, pyattr_get_forceLimitY, pyattr_set_forceLimitY), KX_PYATTRIBUTE_RW_FUNCTION("forceLimitZ", KX_ObjectActuator, pyattr_get_forceLimitZ, pyattr_set_forceLimitZ), KX_PYATTRIBUTE_VECTOR_RW_CHECK("pid", -100, 200, true, KX_ObjectActuator, m_pid, PyCheckPid), + KX_PYATTRIBUTE_RW_FUNCTION("reference", KX_ObjectActuator,pyattr_get_reference,pyattr_set_reference), { NULL } //Sentinel }; @@ -484,6 +533,38 @@ int KX_ObjectActuator::pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE return PY_SET_ATTR_FAIL; } +PyObject* KX_ObjectActuator::pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_ObjectActuator* actuator = static_cast(self); + if (!actuator->m_reference) + Py_RETURN_NONE; + + return actuator->m_reference->GetProxy(); +} + +int KX_ObjectActuator::pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* actuator = static_cast(self); + KX_GameObject *refOb; + + if (!ConvertPythonToGameObject(value, &refOb, true, "actu.reference = value: KX_ObjectActuator")) + return PY_SET_ATTR_FAIL; + + if (actuator->m_reference) + actuator->m_reference->UnregisterActuator(actuator); + + if(refOb==NULL) { + actuator->m_reference= NULL; + } + else { + actuator->m_reference = refOb; + actuator->m_reference->RegisterActuator(actuator); + } + + return PY_SET_ATTR_SUCCESS; +} + + /* 1. set ------------------------------------------------------------------ */ /* Removed! */ diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index b60f877074d..f9bd2a0c748 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -35,6 +35,8 @@ #include "SCA_IActuator.h" #include "MT_Vector3.h" +class KX_GameObject; + // // Stores the flags for each CValue derived class // @@ -92,7 +94,7 @@ class KX_ObjectActuator : public SCA_IActuator MT_Vector3 m_previous_error; MT_Vector3 m_error_accumulator; KX_LocalFlags m_bitLocalFlag; - + KX_GameObject* m_reference; // A hack bool -- oh no sorry everyone // This bool is used to check if we have informed // the physics object that we are no longer @@ -121,6 +123,7 @@ public: KX_ObjectActuator( SCA_IObject* gameobj, + KX_GameObject* refobj, const MT_Vector3& force, const MT_Vector3& torque, const MT_Vector3& dloc, @@ -131,8 +134,11 @@ public: const KX_LocalFlags& flag, PyTypeObject* T=&Type ); - + ~KX_ObjectActuator(); CValue* GetReplica(); + void ProcessReplica(); + bool UnlinkObject(SCA_IObject* clientobj); + void Relink(GEN_Map *obj_map); void SetForceLoc(const double force[3]) { /*m_force=force;*/ } void UpdateFuzzyFlags() @@ -188,6 +194,8 @@ public: static int pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + 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); // This lets the attribute macros use UpdateFuzzyFlags() static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef) diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index ca02b1a2798..5ec6f31e30c 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -2668,6 +2668,8 @@ class KX_ObjectActuator(SCA_IActuator): @ivar pid: The PID coefficients of the servo controller @type pid: list of floats [proportional, integral, derivate] + @ivar reference: The object that is used as reference to compute the velocity for the servo controller. + @type reference: KX_GameObject or None @group Deprecated: getForce, setForce, getTorque, setTorque, getDLoc, setDLoc, getDRot, setDRot, getLinearVelocity, setLinearVelocity, getAngularVelocity, setAngularVelocity, getDamping, setDamping, getForceLimitX, setForceLimitX, getForceLimitY, setForceLimitY, getForceLimitZ, setForceLimitZ, From cb96dc40e8b1039382a1bb978b82adcedcd8c713 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 May 2009 10:27:09 +0000 Subject: [PATCH 267/444] Sensor objects were initialized as invisible, which conflicted with initializing the invisible setting from the outliner render object (which it seems nobody knew about). Added an 'Invisible' button to make this more clear, it seems like a display option but its also related to logic because the actuators can toggle this after the game starts. Without this its annoying to add UV's only to set the invisible flag. Sensor objects were not clearing the softbody gameflag --- source/blender/src/buttons_logic.c | 19 +++++++++++++------ .../Ketsji/KX_ConvertPhysicsObjects.cpp | 2 -- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 605568680ba..2cda73eaef3 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3068,7 +3068,7 @@ static void check_body_type(void *arg1_but, void *arg2_object) switch (ob->body_type) { case OB_BODY_TYPE_SENSOR: ob->gameflag |= OB_SENSOR|OB_COLLISION|OB_GHOST; - ob->gameflag &= ~(OB_OCCLUDER|OB_DYNAMIC|OB_RIGID_BODY|OB_ACTOR|OB_ANISOTROPIC_FRICTION|OB_DO_FH|OB_ROT_FH|OB_COLLISION_RESPONSE); + ob->gameflag &= ~(OB_OCCLUDER|OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_ACTOR|OB_ANISOTROPIC_FRICTION|OB_DO_FH|OB_ROT_FH|OB_COLLISION_RESPONSE); break; case OB_BODY_TYPE_OCCLUDER: ob->gameflag |= OB_OCCLUDER; @@ -3315,14 +3315,21 @@ static void buttons_bullet(uiBlock *block, Object *ob) "Object type%t|Occluder%x5|No collision%x0|Sensor%x6|Static%x1|Dynamic%x2|Rigid body%x3|Soft body%x4", 10, 205, 100, 19, &ob->body_type, 0, 0, 0, 0, tip); uiButSetFunc(but, check_body_type, but, ob); - + + uiBlockEndAlign(block); + + uiDefButBitS(block, TOG, OB_RESTRICT_RENDER, B_NOP, "Invisible", + 210, 205, 60, 19, + &ob->restrictflag, 0, 0, 0, 0, + "Initializes objects as invisible, this can be toggled by the visibility actuator (uses outliner render option)"); + if (ob->gameflag & OB_COLLISION) { if (ob->gameflag & OB_SENSOR) { uiBlockEndAlign(block); uiDefBlockBut(block, advanced_bullet_menu, ob, - "Advanced Settings", - 210, 205, 140, 19, "Display collision advanced settings"); + "Advanced", + 270, 205, 80, 19, "Display collision advanced settings"); uiBlockBeginAlign(block); } else { uiDefButBitI(block, TOG, OB_ACTOR, 0, "Actor", @@ -3338,8 +3345,8 @@ static void buttons_bullet(uiBlock *block, Object *ob) //uiBlockSetCol(block, TH_BUT_SETTING1); uiDefBlockBut(block, advanced_bullet_menu, ob, - "Advanced Settings", - 210, 205, 140, 19, "Display collision advanced settings"); + "Advanced", + 270, 205, 80, 19, "Display collision advanced settings"); //uiBlockSetCol(block, TH_BUT_SETTING2); } diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 73693e68642..d81b6d5a653 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -1129,8 +1129,6 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, // bullet will not synchronize, we must do it explicitely SG_Callbacks& callbacks = gameobj->GetSGNode()->GetCallBackFunctions(); callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc; - // make sensor object invisible by default - gameobj->SetVisible(false, false); } // don't add automatically sensor object, they are added when a collision sensor is registered else if (objprop->m_in_active_layer) From b1a393e8156d9020aaefb25cf5cf8fb4103cea75 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 18 May 2009 10:34:26 +0000 Subject: [PATCH 268/444] Bugfix #18733 & #18609 (revisited) New imbuf scaling code, advertised as "quick and quality" gave inacceptable noise and rounding errors. Check this bugreport for images that show it well: http://projects.blender.org/tracker/?func=detail&atid=125&aid=18609&group_id=9 For release, better disable this code and fall back on perfectly working old code. :) --- source/blender/imbuf/intern/scaling.c | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index b308915cd62..1ccdad05deb 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -596,12 +596,12 @@ static void shrink_picture_byte( y_counter = 65536; for (y_src = 0; y_src < src_height; y_src++) { unsigned char* line = src + y_src * 4 * src_width; - uintptr_t weight1y = 65536 - (y_dst & 0xffff); - uintptr_t weight2y = 65536 - weight1y; + uintptr_t weight1y = 65535 - (y_dst & 0xffff); + uintptr_t weight2y = 65535 - weight1y; x_dst = 0; for (x_src = 0; x_src < src_width; x_src++) { - uintptr_t weight1x = 65536 - (x_dst & 0xffff); - uintptr_t weight2x = 65536 - weight1x; + uintptr_t weight1x = 65535 - (x_dst & 0xffff); + uintptr_t weight2x = 65535 - weight1x; uintptr_t x = x_dst >> 16; @@ -609,7 +609,7 @@ static void shrink_picture_byte( w = (weight1y * weight1x) >> 16; - /* ensure correct rounding, without this you get ugly banding (ton) */ + /* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */ dst_line1[x].r += (line[0] * w + 32767) >> 16; dst_line1[x].g += (line[1] * w + 32767) >> 16; dst_line1[x].b += (line[2] * w + 32767) >> 16; @@ -647,18 +647,18 @@ static void shrink_picture_byte( y_dst += dy_dst; y_counter -= dy_dst; if (y_counter < 0) { + int val; uintptr_t x; struct scale_outpix_byte * temp; y_counter += 65536; for (x=0; x < dst_width; x++) { - uintptr_t f = 0x80000000UL - / dst_line1[x].weight; - *dst++ = (dst_line1[x].r * f) >> 15; - *dst++ = (dst_line1[x].g * f) >> 15; - *dst++ = (dst_line1[x].b * f) >> 15; - *dst++ = (dst_line1[x].a * f) >> 15; + uintptr_t f = 0x80000000UL / dst_line1[x].weight; + *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val; } memset(dst_line1, 0, dst_width * sizeof(struct scale_outpix_byte)); @@ -668,13 +668,14 @@ static void shrink_picture_byte( } } if (dst - dst_begin < dst_width * dst_height * 4) { + int val; uintptr_t x; for (x = 0; x < dst_width; x++) { uintptr_t f = 0x80000000UL / dst_line1[x].weight; - *dst++ = (dst_line1[x].r * f) >> 15; - *dst++ = (dst_line1[x].g * f) >> 15; - *dst++ = (dst_line1[x].b * f) >> 15; - *dst++ = (dst_line1[x].a * f) >> 15; + *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val; + *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val; } } MEM_freeN(dst_line1); @@ -912,6 +913,8 @@ static void q_scale_float(float* in, float* out, int in_width, Should be comparable in speed to the ImBuf ..._fast functions at least for byte-buffers. + NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton) + */ static int q_scale_linear_interpolation( struct ImBuf *ibuf, int newx, int newy) @@ -1584,7 +1587,8 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) scalefast_Z_ImBuf(ibuf, newx, newy); /* try to scale common cases in a fast way */ - if (q_scale_linear_interpolation(ibuf, newx, newy)) { + /* disabled, quality loss is inacceptable, see report #18609 (ton) */ + if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) { return ibuf; } From 65bd48c896492a6485121524171f2f447fe1b95f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 May 2009 11:15:24 +0000 Subject: [PATCH 269/444] [#18778] Lattice Vertex Groups Don't get deleted fixed 'Copy Group' for lattice too. --- source/blender/src/editdeform.c | 57 ++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c index 8a07a4fddff..ac027b2c1ad 100644 --- a/source/blender/src/editdeform.c +++ b/source/blender/src/editdeform.c @@ -211,11 +211,10 @@ void duplicate_defgroup ( Object *ob ) bDeformGroup *dg, *cdg; char name[32], s[32]; MDeformWeight *org, *cpy; - MDeformVert *dvert; - Mesh *me; - int i, idg, icdg; + MDeformVert *dvert, *dvert_array; + int i, idg, icdg, dvert_tot; - if (ob->type != OB_MESH) + if (ob->type != OB_MESH && ob->type != OB_LATTICE) return; dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); @@ -246,12 +245,22 @@ void duplicate_defgroup ( Object *ob ) ob->actdef = BLI_countlist (&ob->defbase); icdg = (ob->actdef-1); - me = get_mesh (ob); - if (!me->dvert) + if(ob->type == OB_MESH) { + Mesh *me = get_mesh (ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + + if (!dvert_array) return; - for (i = 0; i < me->totvert; i++) { - dvert = me->dvert+i; + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; org = get_defweight (dvert, idg); if (org) { cpy = verify_defweight (dvert, icdg); @@ -323,29 +332,39 @@ static void del_defgroup_update_users(Object *ob, int id) void del_defgroup_in_object_mode ( Object *ob ) { bDeformGroup *dg; - MDeformVert *dvert; - Mesh *me; - int i, e; + MDeformVert *dvert_array, *dvert; + + int i, e, dvert_tot; - if ((!ob) || (ob->type != OB_MESH)) + if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE)) return; + if(ob->type == OB_MESH) { + Mesh *me = get_mesh (ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); if (!dg) return; - - me = get_mesh (ob); - if (me->dvert) { - for (i = 0; i < me->totvert; i++) { - dvert = me->dvert + i; + + if (dvert_array) { + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array + i; if (dvert) { if (get_defweight (dvert, (ob->actdef-1))) remove_vert_defgroup (ob, dg, i); } } - for (i = 0; i < me->totvert; i++) { - dvert = me->dvert+i; + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; if (dvert) { for (e = 0; e < dvert->totweight; e++) { if (dvert->dw[e].def_nr > (ob->actdef-1)) From 9c8f09d2a0ade9eefb430c6cab3c98c23b0e188a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 May 2009 14:20:16 +0000 Subject: [PATCH 270/444] bug in copy weight group since 2.44, accessing free'd memory. --- source/blender/src/editdeform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c index ac027b2c1ad..e9e4c2e2440 100644 --- a/source/blender/src/editdeform.c +++ b/source/blender/src/editdeform.c @@ -263,8 +263,10 @@ void duplicate_defgroup ( Object *ob ) dvert = dvert_array+i; org = get_defweight (dvert, idg); if (org) { + float weight = org->weight; + /* verify_defweight re-allocs org so need to store the weight first */ cpy = verify_defweight (dvert, icdg); - cpy->weight = org->weight; + cpy->weight = weight; } } } From d35a556d6603d021cf3297ed3b2519e46b74871b Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 18 May 2009 20:23:38 +0000 Subject: [PATCH 271/444] Bug fix for: [#18761] GLSL Negative light option in Blender does not work in the GE --- source/blender/gpu/intern/gpu_material.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index f7052694fc7..93604e76527 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1309,9 +1309,9 @@ void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]) void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy) { lamp->la->energy = energy; - lamp->la->r = r; - lamp->la->g = g; - lamp->la->b = b; + lamp->la->r = fabs(r); + lamp->la->g = fabs(g); + lamp->la->b = fabs(b); lamp->col[0]= lamp->la->r*lamp->energy; lamp->col[1]= lamp->la->g*lamp->energy; From 379f02f6e60d6592d7579e67a167026018dc27e1 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 18 May 2009 21:05:21 +0000 Subject: [PATCH 272/444] CMake + MSVC debug build fix Initializing lResult = 0; and removing NOP (if(!lResult) lResult = 0; That was discussed with Genscher and Benoit in IRC. --- intern/ghost/intern/GHOST_SystemWin32.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index b265353144d..2cee48032f5 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -537,7 +537,7 @@ GHOST_Event* GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { GHOST_Event* event = 0; - LRESULT lResult; + LRESULT lResult = 0; GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem()); GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized") @@ -908,8 +908,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, if (event) { system->pushEvent(event); - if(!lResult) //WM_ACTIVATE might have returned something. - lResult = 0; } else { lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); From 2ac81cc7ad83135b00e2e44103f69515a751bafd Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 18 May 2009 21:32:03 +0000 Subject: [PATCH 273/444] BGE soft body: give access to the soft body collision margin in the Advanced panel. By default the collision margin is set to 0.25, which causes the soft body to somewhat float above the ground. You can decrease this value to get more realistic collision. Note that the algorithm may become unstable with lower margin. --- source/blender/makesdna/DNA_object_force.h | 1 + source/blender/src/buttons_logic.c | 10 ++++++++-- .../gameengine/Converter/BL_BlenderDataConversion.cpp | 3 ++- .../gameengine/Physics/Bullet/CcdPhysicsController.cpp | 6 +++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index e8e865a533c..dc449a64c6d 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -120,6 +120,7 @@ typedef struct BulletSoftBody { int collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ int numclusteriterations; /* number of iterations to refine collision clusters*/ float welding; /* welding limit to remove duplicate/nearby vertices, 0.0..0.01 */ + float margin; /* margin specific to softbody */ } BulletSoftBody; /* BulletSoftBody.flag */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 2cda73eaef3..2f8933b593b 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3141,8 +3141,14 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) uiBlockEndAlign(block); yco -= 20; xco = 0; - uiDefButF(block, NUMSLI, 0, "Welding ", - xco, yco, 360, 19, &ob->bsoft->welding, 0.f, 0.01f, 10, 4, + if (ob->bsoft->margin < 0.001f) + ob->bsoft->margin = 0.25f; + uiDefButF(block, NUM, 0, "Margin", + xco, yco, 180, 19, &ob->bsoft->margin, 0.001, 1.0, 1, 0, + "Collision margin for soft body. Small value makes the algorithm unstable"); + + uiDefButF(block, NUM, 0, "Welding ", + xco+=180, yco, 180, 19, &ob->bsoft->welding, 0.f, 0.01f, 10, 4, "Welding threshold: distance between nearby vertices to be considered equal => set to 0.0 to disable welding test and speed up scene loading (ok if the mesh has no duplicates)"); /* diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d4cc047d5e3..13aac74edca 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1456,7 +1456,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */ - + objprop.m_margin = blenderobject->bsoft->margin; } else { objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT; @@ -1496,6 +1496,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS; objprop.m_soft_numclusteriterations= 16; objprop.m_soft_welding = 0.f; + objprop.m_margin = 0.f; } } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 7302c47f4bf..6b00011b693 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -296,7 +296,11 @@ void CcdPhysicsController::CreateRigidbody() } } - + if (m_cci.m_margin > 0.f) + { + psb->getCollisionShape()->setMargin(m_cci.m_margin); + psb->updateBounds(); + } m_object = psb; From def33757e303255bfd9c17eb716a02d49df58062 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 19 May 2009 05:07:52 +0000 Subject: [PATCH 274/444] recorded game physics ipo's also have the same problem FBX export had with eulers rotations http://www.graphicall.org/ftp/ideasman42/game_euler.png - dont calculate handles for key added (it does them all at the end). - was doing twice the number of curve lookup's per frame as was needed. - test handles function that runs at the end was converting to ipo transformation values for no reason. - when adding new curves set them to linear interpolation. --- .../Converter/KX_BlenderSceneConverter.cpp | 292 +++++------------- 1 file changed, 77 insertions(+), 215 deletions(-) diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 190f9dbb472..c9ac7a23625 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -87,6 +87,7 @@ extern "C" #include "BSE_editipo_types.h" #include "DNA_ipo_types.h" #include "BKE_global.h" +#include "BKE_ipo.h" // eval_icu #include "DNA_space_types.h" } @@ -666,7 +667,9 @@ extern "C" struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int, short); void testhandles_ipocurve(struct IpoCurve *icu); void insert_vert_icu(struct IpoCurve *, float, float, short); - void Mat3ToEul(float tmat[][3], float *eul); + float eval_icu(struct IpoCurve *icu, float ipotime); + //void Mat3ToEul(float tmat[][3], float *eul); + void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot); } IpoCurve* findIpoCurve(IpoCurve* first, const char* searchName) @@ -816,7 +819,6 @@ void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){ } } -#define TEST_HANDLES_GAME2IPO 0 ///this generates ipo curves for position, rotation, allowing to use game physics in animation void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) @@ -840,138 +842,80 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); Object* blenderObject = FindBlenderObject(gameObj); - if (blenderObject) + if (blenderObject && blenderObject->ipo) { - - const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation(); - float eulerAngles[3]; - float tmat[3][3]; - for (int r=0;r<3;r++) - { - for (int c=0;c<3;c++) - { - tmat[r][c] = orn[c][r]; - } - } - Mat3ToEul(tmat, eulerAngles); - - for(int x = 0; x < 3; x++) { - eulerAngles[x] *= (float) (180 / 3.14159265f); - } - - eulerAngles[0]/=10.f; - eulerAngles[1]/=10.f; - eulerAngles[2]/=10.f; - - - - //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); const MT_Point3& position = gameObj->NodeGetWorldPosition(); + //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); + const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation(); + + float eulerAngles[3]; + float eulerAnglesOld[3] = {0.0f, 0.0f, 0.0f}; + float tmat[3][3]; Ipo* ipo = blenderObject->ipo; - if (ipo) - { - //create the curves, if not existing - - IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1); - - - - //fill the curves with data - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); - if (icu1) - { - float curVal = position.x(); - insert_vert_icu(icu1, frameNumber, curVal, 0); -#ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); -#endif - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); - if (icu1) - { - float curVal = position.y(); - insert_vert_icu(icu1, frameNumber, curVal, 0); -#ifdef TEST_HANDLES_GAME2IPO - - testhandles_ipocurve(icu1); -#endif - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); - if (icu1) - { - float curVal = position.z(); - insert_vert_icu(icu1, frameNumber, curVal, 0); -#ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); -#endif - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); - if (icu1) - { - float curVal = eulerAngles[0]; - insert_vert_icu(icu1, frameNumber, curVal, 0); -#ifdef TEST_HANDLES_GAME2IPO - - testhandles_ipocurve(icu1); -#endif - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); - if (icu1) - { - float curVal = eulerAngles[1]; - insert_vert_icu(icu1, frameNumber, curVal, 0); -#ifdef TEST_HANDLES_GAME2IPO - - testhandles_ipocurve(icu1); -#endif - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); - if (icu1) - { - float curVal = eulerAngles[2]; - insert_vert_icu(icu1, frameNumber, curVal, 0); -#ifdef TEST_HANDLES_GAME2IPO - - testhandles_ipocurve(icu1); -#endif - - } + //create the curves, if not existing, set linear if new + IpoCurve *icu_lx = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); + if (!icu_lx) { + icu_lx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1); + if(icu_lx) icu_lx->ipo = IPO_LIN; } + IpoCurve *icu_ly = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); + if (!icu_ly) { + icu_ly = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1); + if(icu_ly) icu_ly->ipo = IPO_LIN; + } + IpoCurve *icu_lz = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); + if (!icu_lz) { + icu_lz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1); + if(icu_lz) icu_lz->ipo = IPO_LIN; + } + IpoCurve *icu_rx = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); + if (!icu_rx) { + icu_rx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1); + if(icu_rx) icu_rx->ipo = IPO_LIN; + } + IpoCurve *icu_ry = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); + if (!icu_ry) { + icu_ry = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1); + if(icu_ry) icu_ry->ipo = IPO_LIN; + } + IpoCurve *icu_rz = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); + if (!icu_rz) { + icu_rz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1); + if(icu_rz) icu_rz->ipo = IPO_LIN; + } + + if(icu_rx) eulerAnglesOld[0]= eval_icu( icu_rx, frameNumber - 1 ) / ((180 / 3.14159265f) / 10); + if(icu_ry) eulerAnglesOld[1]= eval_icu( icu_ry, frameNumber - 1 ) / ((180 / 3.14159265f) / 10); + if(icu_rz) eulerAnglesOld[2]= eval_icu( icu_rz, frameNumber - 1 ) / ((180 / 3.14159265f) / 10); + + // orn.getValue((float *)tmat); // uses the wrong ordering, cant use this + for (int r=0;r<3;r++) + for (int c=0;c<3;c++) + tmat[r][c] = orn[c][r]; + + // Mat3ToEul(tmat, eulerAngles); // better to use Mat3ToCompatibleEul + Mat3ToCompatibleEul(tmat, eulerAngles, eulerAnglesOld); + + //eval_icu + for(int x = 0; x < 3; x++) + eulerAngles[x] *= (float) ((180 / 3.14159265f) / 10.0); + + //fill the curves with data + if (icu_lx) insert_vert_icu(icu_lx, frameNumber, position.x(), 1); + if (icu_ly) insert_vert_icu(icu_ly, frameNumber, position.y(), 1); + if (icu_lz) insert_vert_icu(icu_lz, frameNumber, position.z(), 1); + if (icu_rx) insert_vert_icu(icu_rx, frameNumber, eulerAngles[0], 1); + if (icu_ry) insert_vert_icu(icu_ry, frameNumber, eulerAngles[1], 1); + if (icu_rz) insert_vert_icu(icu_rz, frameNumber, eulerAngles[2], 1); + + // Handles are corrected at the end, testhandles_ipocurve isnt needed yet } } - } - - - } - - + } } @@ -996,100 +940,18 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo() //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); Object* blenderObject = FindBlenderObject(gameObj); - if (blenderObject) + if (blenderObject && blenderObject->ipo) { - - const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation(); - float eulerAngles[3]; - float tmat[3][3]; - for (int r=0;r<3;r++) - { - for (int c=0;c<3;c++) - { - tmat[r][c] = orn[c][r]; - } - } - Mat3ToEul(tmat, eulerAngles); - - for(int x = 0; x < 3; x++) { - eulerAngles[x] *= (float) (180 / 3.14159265f); - } - - eulerAngles[0]/=10.f; - eulerAngles[1]/=10.f; - eulerAngles[2]/=10.f; - - - - //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); - //const MT_Point3& position = gameObj->NodeGetWorldPosition(); - Ipo* ipo = blenderObject->ipo; - if (ipo) - { - - //create the curves, if not existing - - IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1); - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1); - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); - if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1); - - - - //fill the curves with data - - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); - if (icu1) - { - testhandles_ipocurve(icu1); - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); - if (icu1) - { - testhandles_ipocurve(icu1); - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); - if (icu1) - { - testhandles_ipocurve(icu1); - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); - if (icu1) - { - testhandles_ipocurve(icu1); - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); - if (icu1) - { - testhandles_ipocurve(icu1); - } - icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); - if (icu1) - { - testhandles_ipocurve(icu1); - } - - } + //create the curves, if not existing + //testhandles_ipocurve checks for NULL + testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocX")); + testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocY")); + testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ")); + testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotX")); + testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotY")); + testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ")); } } From 5bd4b25dd1997672e4487f7dcba76e4b74ce814f Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 19 May 2009 06:48:36 +0000 Subject: [PATCH 275/444] BGE bug #18762 fixed: softbody. An incompatibility between the soft body deformer and other types of deformer was causing the soft body to disappear in the game. This was the case when the soft body had an armature or simply vertex groups. --- source/gameengine/Converter/BL_SkinDeformer.h | 4 ++ source/gameengine/Rasterizer/RAS_Deformer.h | 4 ++ .../Rasterizer/RAS_MaterialBucket.cpp | 66 ++++++++++++------- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index 8d3167746be..7c43246a9d7 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -90,6 +90,10 @@ public: { m_lastArmaUpdate = -1.0; }; + virtual bool ShareVertexArray() + { + return false; + } protected: BL_ArmatureObject* m_armobj; // Our parent object diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index 9dc656ba56a..fe9b1540af8 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -54,6 +54,10 @@ public: { return false; } + virtual bool ShareVertexArray() + { + return true; + } virtual bool UseVertexArray() { return true; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 841264465cf..8e90c9a1c08 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -284,35 +284,55 @@ void RAS_MeshSlot::AddPolygonVertex(int offset) void RAS_MeshSlot::SetDeformer(RAS_Deformer* deformer) { if (deformer && m_pDeformer != deformer) { - // we create local copy of RAS_DisplayArray when we have a deformer: - // this way we can avoid conflict between the vertex cache of duplicates RAS_DisplayArrayList::iterator it; - for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) { - if (deformer->UseVertexArray()) { - // the deformer makes use of vertex array, make sure we have our local copy - if ((*it)->m_users > 1) { - // only need to copy if there are other users - // note that this is the usual case as vertex arrays are held by the material base slot - RAS_DisplayArray *newarray = new RAS_DisplayArray(*(*it)); - newarray->m_users = 1; - (*it)->m_users--; - *it = newarray; - } - } else { - // the deformer is not using vertex array (Modifier), release them + if (deformer->ShareVertexArray()) { + // this deformer uses the base vertex array, first release the current ones + for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) { (*it)->m_users--; if((*it)->m_users == 0) delete *it; } - } - if (!deformer->UseVertexArray()) { m_displayArrays.clear(); - m_startarray = 0; - m_startvertex = 0; - m_startindex = 0; - m_endarray = 0; - m_endvertex = 0; - m_endindex = 0; + // then hook to the base ones + RAS_MeshMaterial *mmat = m_mesh->GetMeshMaterial(m_bucket->GetPolyMaterial()); + if (mmat && mmat->m_baseslot) { + m_displayArrays = mmat->m_baseslot->m_displayArrays; + for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) { + (*it)->m_users++; + } + } + } + else { + // no sharing + // we create local copy of RAS_DisplayArray when we have a deformer: + // this way we can avoid conflict between the vertex cache of duplicates + for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) { + if (deformer->UseVertexArray()) { + // the deformer makes use of vertex array, make sure we have our local copy + if ((*it)->m_users > 1) { + // only need to copy if there are other users + // note that this is the usual case as vertex arrays are held by the material base slot + RAS_DisplayArray *newarray = new RAS_DisplayArray(*(*it)); + newarray->m_users = 1; + (*it)->m_users--; + *it = newarray; + } + } else { + // the deformer is not using vertex array (Modifier), release them + (*it)->m_users--; + if((*it)->m_users == 0) + delete *it; + } + } + if (!deformer->UseVertexArray()) { + m_displayArrays.clear(); + m_startarray = 0; + m_startvertex = 0; + m_startindex = 0; + m_endarray = 0; + m_endvertex = 0; + m_endindex = 0; + } } } m_pDeformer = deformer; From 1a16fb1953a566cd57f49683d4711b7052d6b586 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 19 May 2009 07:16:40 +0000 Subject: [PATCH 276/444] BGE Py API use PY_SET_ATTR_FAIL and PY_SET_ATTR_SUCCESS return values so the fake subclassing can know if a value failed to be set or if it was missing from the type. (with PY_SET_ATTR_MISSING) Also noticed some other mistakes. - KX_LightObject, setting the type didnt check for an int. - KX_SoundActuator, didnt return an error when assigning an invalid orientation value - KX_GameObject, worldOrientation didnt return an error value. --- .../Converter/BL_ActionActuator.cpp | 6 +-- .../Converter/BL_ShapeActionActuator.cpp | 6 +-- .../GameLogic/SCA_PythonController.cpp | 4 +- .../GameLogic/SCA_RandomActuator.cpp | 4 +- .../gameengine/GameLogic/SCA_RandomSensor.cpp | 4 +- source/gameengine/Ketsji/KX_CDActuator.cpp | 2 +- source/gameengine/Ketsji/KX_Camera.cpp | 24 +++++----- .../gameengine/Ketsji/KX_CameraActuator.cpp | 4 +- source/gameengine/Ketsji/KX_GameObject.cpp | 46 +++++++++---------- source/gameengine/Ketsji/KX_Light.cpp | 11 +++-- .../gameengine/Ketsji/KX_ParentActuator.cpp | 4 +- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 8 ++-- .../Ketsji/KX_SCA_AddObjectActuator.cpp | 4 +- .../Ketsji/KX_SCA_ReplaceMeshActuator.cpp | 4 +- source/gameengine/Ketsji/KX_SoundActuator.cpp | 37 +++++++-------- .../gameengine/Ketsji/KX_TrackToActuator.cpp | 4 +- 16 files changed, 89 insertions(+), 83 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index d0a4a87af72..0812693ee0a 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -1037,7 +1037,7 @@ int BL_ActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF if (!PyString_Check(value)) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Action Actuator, expected the string name of the action"); - return -1; + return PY_SET_ATTR_FAIL; } bAction *action= NULL; @@ -1049,11 +1049,11 @@ int BL_ActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF if (!action) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Action Actuator, action not found!"); - return 1; + return PY_SET_ATTR_FAIL; } } self->SetAction(action); - return 0; + return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index a24d83da90c..bf7edb5f641 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -870,7 +870,7 @@ int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE if (!PyString_Check(value)) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, expected the string name of the action"); - return -1; + return PY_SET_ATTR_FAIL; } bAction *action= NULL; @@ -882,11 +882,11 @@ int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE if (action==NULL) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, action not found!"); - return 1; + return PY_SET_ATTR_FAIL; } } self->SetAction(action); - return 0; + return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index abb3b36b91e..d58259457e6 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -563,14 +563,14 @@ int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_D if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text"); - return -1; + return PY_SET_ATTR_FAIL; } /* set scripttext sets m_bModified to true, so next time the script is needed, a reparse into byte code is done */ self->SetScriptText(scriptArg); - return 0; + return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index ff957d8350e..1bc4487b5bf 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -387,10 +387,10 @@ int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_ if (PyInt_Check(value)) { int ival = PyInt_AsLong(value); act->m_base->SetSeed(ival); - return 0; + return PY_SET_ATTR_SUCCESS; } else { PyErr_SetString(PyExc_TypeError, "actuator.seed = int: Random Actuator, expected an integer"); - return 1; + return PY_SET_ATTR_FAIL; } } diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 1581a29480e..3c04173d10e 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -236,10 +236,10 @@ int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *at SCA_RandomSensor* self= static_cast(self_v); if (!PyInt_Check(value)) { PyErr_SetString(PyExc_TypeError, "sensor.seed = int: Random Sensor, expected an integer"); - return -1; + return PY_SET_ATTR_FAIL; } self->m_basegenerator->SetSeed(PyInt_AsLong(value)); - return 0; + return PY_SET_ATTR_SUCCESS; } /* eof */ diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index 7f8505afa3d..8511526fd5f 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -214,7 +214,7 @@ int KX_CDActuator::pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *a { KX_CDActuator* act = static_cast(self); SND_CDObject::Instance()->SetGain(act->m_gain); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_CDActuator::py_getattro(PyObject *attr) diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 625710fa65d..fe50b371475 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -806,11 +806,11 @@ int KX_Camera::pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *at int param = PyObject_IsTrue( value ); if (param == -1) { PyErr_SetString(PyExc_AttributeError, "camera.perspective = bool: KX_Camera, expected True/False or 0/1"); - return -1; + return PY_SET_ATTR_FAIL; } self->m_camdata.m_perspective= param; - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_Camera::pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -825,12 +825,12 @@ int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, float param = PyFloat_AsDouble(value); if (param == -1) { PyErr_SetString(PyExc_AttributeError, "camera.lens = float: KX_Camera, expected a float greater then zero"); - return -1; + return PY_SET_ATTR_FAIL; } self->m_camdata.m_lens= param; self->m_set_projection_matrix = false; - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_Camera::pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -845,12 +845,12 @@ int KX_Camera::pyattr_set_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, float param = PyFloat_AsDouble(value); if (param == -1) { PyErr_SetString(PyExc_AttributeError, "camera.near = float: KX_Camera, expected a float greater then zero"); - return -1; + return PY_SET_ATTR_FAIL; } self->m_camdata.m_clipstart= param; self->m_set_projection_matrix = false; - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_Camera::pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -865,12 +865,12 @@ int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, P float param = PyFloat_AsDouble(value); if (param == -1) { PyErr_SetString(PyExc_AttributeError, "camera.far = float: KX_Camera, expected a float greater then zero"); - return -1; + return PY_SET_ATTR_FAIL; } self->m_camdata.m_clipend= param; self->m_set_projection_matrix = false; - return 0; + return PY_SET_ATTR_SUCCESS; } @@ -886,10 +886,10 @@ int KX_Camera::pyattr_set_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *a int param = PyObject_IsTrue( value ); if (param == -1) { PyErr_SetString(PyExc_AttributeError, "camera.useViewport = bool: KX_Camera, expected True or False"); - return 1; + return PY_SET_ATTR_FAIL; } self->EnableViewport((bool)param); - return 0; + return PY_SET_ATTR_SUCCESS; } @@ -904,10 +904,10 @@ int KX_Camera::pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_D KX_Camera* self= static_cast(self_v); MT_Matrix4x4 mat; if (!PyMatTo(value, mat)) - return -1; + return PY_SET_ATTR_FAIL; self->SetProjectionMatrix(mat); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_Camera::pyattr_get_modelview_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index b87d0ee4283..3a6011db604 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -597,7 +597,7 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF KX_GameObject *gameobj; if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_CameraActuator")) - return 1; // ConvertPythonToGameObject sets the error + return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error if (self->m_ob) self->m_ob->UnregisterActuator(self); @@ -605,7 +605,7 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF if ((self->m_ob = (SCA_IObject*)gameobj)) self->m_ob->RegisterActuator(self); - return 0; + return PY_SET_ATTR_SUCCESS; } /* eof */ diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index cbd17e66f62..63d508e6250 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1468,13 +1468,13 @@ int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrd MT_Scalar val = PyFloat_AsDouble(value); if (val < 0.0f) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.mass = float: KX_GameObject, expected a float zero or above"); - return 1; + return PY_SET_ATTR_FAIL; } if (spc) spc->SetMass(val); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1491,13 +1491,13 @@ int KX_GameObject::pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF MT_Scalar val = PyFloat_AsDouble(value); if (val < 0.0f) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.linVelocityMin = float: KX_GameObject, expected a float zero or above"); - return 1; + return PY_SET_ATTR_FAIL; } if (spc) spc->SetLinVelocityMin(val); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1514,13 +1514,13 @@ int KX_GameObject::pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF MT_Scalar val = PyFloat_AsDouble(value); if (val < 0.0f) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.linVelocityMax = float: KX_GameObject, expected a float zero or above"); - return 1; + return PY_SET_ATTR_FAIL; } if (spc) spc->SetLinVelocityMax(val); - return 0; + return PY_SET_ATTR_SUCCESS; } @@ -1536,12 +1536,12 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at int param = PyObject_IsTrue( value ); if (param == -1) { PyErr_SetString(PyExc_AttributeError, "gameOb.visible = bool: KX_GameObject, expected True or False"); - return 1; + return PY_SET_ATTR_FAIL; } self->SetVisible(param, false); self->UpdateBuckets(false); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1555,11 +1555,11 @@ int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_D KX_GameObject* self= static_cast(self_v); MT_Point3 pos; if (!PyVecTo(value, pos)) - return 1; + return PY_SET_ATTR_FAIL; self->NodeSetWorldPosition(pos); self->NodeUpdateGS(0.f); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1576,11 +1576,11 @@ int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_D KX_GameObject* self= static_cast(self_v); MT_Point3 pos; if (!PyVecTo(value, pos)) - return 1; + return PY_SET_ATTR_FAIL; self->NodeSetLocalPosition(pos); self->NodeUpdateGS(0.f); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1606,7 +1606,7 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT /* if value is not a sequence PyOrientationTo makes an error */ MT_Matrix3x3 rot; if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, ")) - return NULL; + return PY_SET_ATTR_FAIL; if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) { self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); @@ -1616,7 +1616,7 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT } self->NodeUpdateGS(0.f); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1635,11 +1635,11 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT /* if value is not a sequence PyOrientationTo makes an error */ MT_Matrix3x3 rot; if (!PyOrientationTo(value, rot, "gameOb.localOrientation = sequence: KX_GameObject, ")) - return NULL; + return PY_SET_ATTR_FAIL; self->NodeSetLocalOrientation(rot); self->NodeUpdateGS(0.f); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1662,11 +1662,11 @@ int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DE KX_GameObject* self= static_cast(self_v); MT_Vector3 scale; if (!PyVecTo(value, scale)) - return 1; + return PY_SET_ATTR_FAIL; self->NodeSetLocalScale(scale); self->NodeUpdateGS(0.f); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1688,12 +1688,12 @@ int KX_GameObject::pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF SG_Node* sg_parent= self->GetSGNode()->GetSGParent(); if (val < 0.0f) { /* also accounts for non float */ PyErr_SetString(PyExc_AttributeError, "gameOb.timeOffset = float: KX_GameObject, expected a float zero or above"); - return 1; + return PY_SET_ATTR_FAIL; } if (sg_parent && sg_parent->IsSlowParent()) static_cast(sg_parent->GetParentRelation())->SetTimeOffset(val); } - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1712,16 +1712,16 @@ int KX_GameObject::pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attr if (state_i == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "gameOb.state = int: KX_GameObject, expected an int bit field"); - return 1; + return PY_SET_ATTR_FAIL; } state |= state_i; if ((state & ((1<<30)-1)) == 0) { PyErr_SetString(PyExc_AttributeError, "gameOb.state = int: KX_GameObject, state bitfield was not between 0 and 30 (1<<0 and 1<<29)"); - return 1; + return PY_SET_ATTR_FAIL; } self->SetState(state); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index df7691d016b..1496f34c5f2 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -261,9 +261,9 @@ int KX_LightObject::pyattr_set_color(void *self_v, const KX_PYATTRIBUTE_DEF *att self->m_lightobj.m_red = color[0]; self->m_lightobj.m_green = color[1]; self->m_lightobj.m_blue = color[2]; - return 0; + return PY_SET_ATTR_SUCCESS; } - return 1; + return PY_SET_ATTR_FAIL; } PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -293,6 +293,11 @@ int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attr { KX_LightObject* self = static_cast(self_v); int val = PyInt_AsLong(value); + if((val==-1 && PyErr_Occurred()) || val<0 || val>2) { + PyErr_SetString(PyExc_ValueError, "light.type= val: KX_LightObject, expected an int between 0 and 2"); + return PY_SET_ATTR_FAIL; + } + switch(val) { case 0: self->m_lightobj.m_type = self->m_lightobj.LIGHT_SPOT; @@ -300,7 +305,7 @@ int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attr case 1: self->m_lightobj.m_type = self->m_lightobj.LIGHT_SUN; break; - default: + case 2: self->m_lightobj.m_type = self->m_lightobj.LIGHT_NORMAL; break; } diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index c5248785b12..38ad9aec33b 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -197,7 +197,7 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE KX_GameObject *gameobj; if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator")) - return 1; // ConvertPythonToGameObject sets the error + return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error if (actuator->m_ob != NULL) actuator->m_ob->UnregisterActuator(actuator); @@ -207,7 +207,7 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE if (actuator->m_ob) actuator->m_ob->RegisterActuator(actuator); - return 0; + return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 2aa0ef921e9..98aad3943fe 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -386,10 +386,10 @@ int KX_PolygonMaterial::pyattr_set_diffuse(void *self_v, const KX_PYATTRIBUTE_DE MT_Vector3 vec; if (!PyVecTo(value, vec)) - return -1; + return PY_SET_ATTR_FAIL; self->m_diffuse= vec; - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_PolygonMaterial::pyattr_get_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -404,8 +404,8 @@ int KX_PolygonMaterial::pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_D MT_Vector3 vec; if (!PyVecTo(value, vec)) - return -1; + return PY_SET_ATTR_FAIL; self->m_specular= vec; - return 0; + return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 3c72eac3e62..dec76a75e50 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -242,7 +242,7 @@ int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYAT KX_GameObject *gameobj; if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SCA_AddObjectActuator")) - return 1; // ConvertPythonToGameObject sets the error + return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error if (actuator->m_OriginalObject != NULL) actuator->m_OriginalObject->UnregisterActuator(actuator); @@ -252,7 +252,7 @@ int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYAT if (actuator->m_OriginalObject) actuator->m_OriginalObject->RegisterActuator(actuator); - return 0; + return PY_SET_ATTR_SUCCESS; } PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 730d1ed49e6..00842d7012a 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -128,10 +128,10 @@ int KX_SCA_ReplaceMeshActuator::pyattr_set_mesh(void *self, const struct KX_PYAT RAS_MeshObject* new_mesh; if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator")) - return 1; + return PY_SET_ATTR_FAIL; actuator->m_mesh = new_mesh; - return 0; + return PY_SET_ATTR_SUCCESS; } /* 1. setMesh */ diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 3a341f007e4..5c02a2db646 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -450,13 +450,13 @@ int KX_SoundActuator::pyattr_set_filename(void *self, const struct KX_PYATTRIBUT // void *soundPointer = NULL; /*unused*/ if (!PyArg_Parse(value, "s", &soundName)) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) { actuator->m_soundObject->SetObjectName(soundName); } - return 0; + return PY_SET_ATTR_SUCCESS; } @@ -465,12 +465,12 @@ int KX_SoundActuator::pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DE float gain = 1.0; KX_SoundActuator * actuator = static_cast (self); if (!PyArg_Parse(value, "f", &gain)) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) actuator->m_soundObject->SetGain(gain); - return 0; + return PY_SET_ATTR_SUCCESS; } int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -478,12 +478,12 @@ int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_D float pitch = 1.0; KX_SoundActuator * actuator = static_cast (self); if (!PyArg_Parse(value, "f", &pitch)) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) actuator->m_soundObject->SetPitch(pitch); - return 0; + return PY_SET_ATTR_SUCCESS; } int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -491,12 +491,12 @@ int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATT KX_SoundActuator * actuator = static_cast (self); float rollofffactor = 1.0; if (!PyArg_Parse(value, "f", &rollofffactor)) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) actuator->m_soundObject->SetRollOffFactor(rollofffactor); - return 0; + return PY_SET_ATTR_SUCCESS; } int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -504,12 +504,12 @@ int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE KX_SoundActuator * actuator = static_cast (self); int looping = 1; if (!PyArg_Parse(value, "i", &looping)) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) actuator->m_soundObject->SetLoopMode(looping); - return 0; + return PY_SET_ATTR_SUCCESS; } int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -519,12 +519,12 @@ int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUT KX_SoundActuator * actuator = static_cast (self); if (!PyArg_ParseTuple(value, "fff", &pos[0], &pos[1], &pos[2])) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) actuator->m_soundObject->SetPosition(MT_Vector3(pos)); - return 0; + return PY_SET_ATTR_SUCCESS; } int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -534,12 +534,12 @@ int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUT if (!PyArg_ParseTuple(value, "fff", &vel[0], &vel[1], &vel[2])) - return 1; + return PY_SET_ATTR_FAIL; if (actuator->m_soundObject) actuator->m_soundObject->SetVelocity(MT_Vector3(vel)); - return 0; + return PY_SET_ATTR_SUCCESS; } @@ -551,14 +551,15 @@ int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRI /* if value is not a sequence PyOrientationTo makes an error */ if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator")) - return NULL; + return PY_SET_ATTR_FAIL; + /* Since not having m_soundObject didn't do anything in the old version, + * it probably should be kept that way */ if (!actuator->m_soundObject) - return 0; /* Since not having m_soundObject didn't do anything in the old version, - * it probably should be kept that way */ + return PY_SET_ATTR_SUCCESS; actuator->m_soundObject->SetOrientation(rot); - return 0; + return PY_SET_ATTR_SUCCESS; } // Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 800da83dc3d..5a50d0fb944 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -504,7 +504,7 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT KX_GameObject *gameobj; if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_TrackToActuator")) - return 1; // ConvertPythonToGameObject sets the error + return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error if (actuator->m_object != NULL) actuator->m_object->UnregisterActuator(actuator); @@ -514,7 +514,7 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT if (actuator->m_object) actuator->m_object->RegisterActuator(actuator); - return 0; + return PY_SET_ATTR_SUCCESS; } From ecacef36829897c1b5d03dffb08f3a4ab7863e9a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 19 May 2009 15:40:03 +0000 Subject: [PATCH 277/444] Last minute mini feature: Expanded the "10-timer" (ALT+CTRL+T) with two new test options: - Draw entire window - Anim step The latter will only call animation system, no drawing. Added this to match the testing menu in 2.5 too, so we can get good reference performance tests. --- source/blender/src/toets.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 804660c3433..3a1b21e91f1 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -901,7 +901,7 @@ int blenderqread(unsigned short event, short val) } else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) { int a; - int event= pupmenu("10 Timer%t|draw|draw+swap|undo"); + int event= pupmenu("10 Timer%t|Draw Area|Draw Area and Swap|Draw Window and Swap|Anim Steps|Undo/Redo"); if(event>0) { double stime= PIL_check_seconds_timer(); char tmpstr[128]; @@ -912,11 +912,20 @@ int blenderqread(unsigned short event, short val) for(a=0; a<10; a++) { if (event==1) { scrarea_do_windraw(curarea); - } else if (event==2) { + } + else if (event==2) { scrarea_do_windraw(curarea); screen_swapbuffers(); } - else if(event==3) { + else if (event==3) { + force_draw_all(1); + } + else if(event==4) { + if(a & 1) G.scene->r.cfra--; + else G.scene->r.cfra++; + scene_update_for_newframe(G.scene, G.scene->lay); + } + else if(event==5) { BIF_undo(); BIF_redo(); } @@ -924,9 +933,11 @@ int blenderqread(unsigned short event, short val) time= (int) ((PIL_check_seconds_timer()-stime)*1000); - if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time); - if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time); - if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time); + if(event==1) sprintf(tmpstr, "Draw %%t|%d ms", time); + if(event==2) sprintf(tmpstr, "Draw+swap %%t|%d ms", time); + if(event==3) sprintf(tmpstr, "Window+sw %%t|%d ms", time); + if(event==4) sprintf(tmpstr, "Anim %%t|%d ms", time); + if(event==5) sprintf(tmpstr, "Undo %%t|%d ms", time); waitcursor(0); pupmenu(tmpstr); From 73904597e9c822fde9ec633db650c9783cf43847 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 20 May 2009 01:11:56 +0000 Subject: [PATCH 278/444] - Added an intro page for the BGE docs rather then using GameLogic - Added notes on BGE stability and modules - updated some examples to new api syntax - include BGL Mathutils and Geometry modules in docs --- source/gameengine/PyDoc/API_intro.py | 103 ++++++++++++++++++++++++++ source/gameengine/PyDoc/GameLogic.py | 30 ++------ source/gameengine/PyDoc/epy_docgen.sh | 9 ++- 3 files changed, 118 insertions(+), 24 deletions(-) create mode 100644 source/gameengine/PyDoc/API_intro.py diff --git a/source/gameengine/PyDoc/API_intro.py b/source/gameengine/PyDoc/API_intro.py new file mode 100644 index 00000000000..ad37e34fbac --- /dev/null +++ b/source/gameengine/PyDoc/API_intro.py @@ -0,0 +1,103 @@ +# This is not a real module, it's simply an introductory text. + +""" +The Blender Game Engine Python API Reference +============================================ + + See U{release notes} for updates, changes and new functionality in the Game Engine Python API. + + Top Module: + ----------- + + - L{GameLogic} + - L{GameKeys} + - L{GameTypes} + - L{Mathutils} + - L{Geometry} + - L{BGL} + + Undocumented modules: + --------------------- + - VideoTexture + - CValue + - Expression + - PhysicsConstraints + + +Introduction: +============= + + This reference documents the Blender Python API, a growing collection of + Python modules (libraries) that give access to part of the program's internal + data and functions. + + Through scripting Blender can be extended in real-time via + U{Python }, an impressive high level, multi-paradigm, open + source language. Newcomers are recommended to start with the tutorial that + comes with it. + + This opens many interesting possibilities not available with logic bricks. + + Game Engine API Stability: + -------------------------- + + When writing python scripts there are a number of situations you should avoid to prevent crashes or unstable behavior. + While the API tries to prevent problems there are some situations where error checking would be too time consuming. + + Known cases: + - Memory Limits. + + There is nothing stopping you from filling a list or making a string so big that that causes blender to run out of memory, in this case python should rasie a MemoryError, but its likely blender will crash before this point. + + - Accessing any data that has been freed. + + For instance accessing a KX_GameObject after its End Object actuator runs. + This will cause a SystemError, however for L{KX_MeshProxy}, L{KX_VertexProxy} and L{KX_VertexProxy} it will crash the blender game engine. + + See: L{GameTypes.PyObjectPlus.invalid} which many types inherit. + + - Mixing L{KX_GameObject} between scenes. + + For instance tracking/parenting an L{KX_GameObject} object to an object from other scene. + + External Modules: + ----------------- + + Since 2.49 support for importing modules has been added. + + This allows you to import any blender textblock with a .py extension. + + External python scripts may be imported as modules when the script is in the same directory as the blend file. + + The current blend files path is included in the sys.path for loading modules. + All linked libraries will also be included so you can be sure when linking in assets from another blend file the scripts will load too. + + A note to newbie script writers: + -------------------------------- + + Interpreted languages are known to be much slower than compiled code, but for + many applications the difference is negligible or acceptable. Also, with + profiling (or even simple direct timing with L{Blender.sys.time}) to + identify slow areas and well thought optimizations, the speed can be + I{considerably} improved in many cases. Try some of the best BPython scripts + to get an idea of what can be done, you may be surprised. + +@author: The Blender Python Team +@requires: Blender 2.49 or newer. +@version: 2.49 +@see: U{www.blender.org}: documentation and forum +@see: U{blenderartists.org}: user forum +@see: U{projects.blender.org} +@see: U{www.python.org} +@see: U{www.python.org/doc} +@see: U{Blending into Python}: User contributed documentation, featuring a blender/python cookbook with many examples. + +@note: the official version of this reference guide is only updated for each + new Blender release. But you can build the current SVN + version yourself: install epydoc, grab all files in the + source/gameengine/PyDoc/ folder of Blender's SVN and use the + epy_docgen.sh script also found there to generate the html docs. + Naturally you will also need a recent Blender binary to try the new + features. If you prefer not to compile it yourself, there is a testing + builds forum at U{blender.org}. +""" diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 28fd95611bc..1bc406daf09 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -2,29 +2,15 @@ """ Documentation for the GameLogic Module. ======================================= - - Modules available in the game engine: - - GameLogic - - L{GameKeys} - - L{Rasterizer} - - L{GameTypes} - Undocumented modules: - - VideoTexture - - CValue - - Expression - - PhysicsConstraints - - All the other modules are accessible through the methods in GameLogic. - - See U{release notes} for updates, changes and new functionality in the Game Engine Python API. + Module to access logic functions, imported automatically into the python controllers namespace. Examples:: # To get the controller thats running this python script: - co = GameLogic.getCurrentController() # GameLogic is automatically imported + cont = GameLogic.getCurrentController() # GameLogic is automatically imported # To get the game object this controller is on: - obj = co.getOwner() + obj = cont.owner L{KX_GameObject} and L{KX_Camera} or L{KX_LightObject} methods are available depending on the type of object:: # To get a sensor linked to this controller. @@ -32,10 +18,10 @@ Documentation for the GameLogic Module. # +---------------------+ +--------+ # | Sensor "sensorname" +--+ Python + # +---------------------+ +--------+ - sens = co.getSensor("sensorname") + sens = cont.sensors["sensorname"] - # To get a list of all sensors: - sensors = co.getSensors() + # To get a sequence of all sensors: + sensors = co.sensors See the sensor's reference for available methods: - L{DelaySensor} @@ -56,7 +42,7 @@ Documentation for the GameLogic Module. # +--------+ +-------------------------+ # + Python +--+ Actuator "actuatorname" | # +--------+ +-------------------------+ - actuator = co.getActuator("actuatorname") + actuator = co.actuators["actuatorname"] # Activate an actuator controller.activate(actuator) @@ -96,7 +82,7 @@ Documentation for the GameLogic Module. cam = scene.active_camera Matricies as used by the game engine are B{row major}:: - matrix[row][col] = blah + matrix[row][col] = float L{KX_Camera} has some examples using matricies. diff --git a/source/gameengine/PyDoc/epy_docgen.sh b/source/gameengine/PyDoc/epy_docgen.sh index 0872d2abbbd..dd30256f42f 100755 --- a/source/gameengine/PyDoc/epy_docgen.sh +++ b/source/gameengine/PyDoc/epy_docgen.sh @@ -7,5 +7,10 @@ # set posix locale so regex works properly for [A-Z]*.py LC_ALL=POSIX -epydoc --debug -v -o BPY_GE --url "http://www.blender.org" --top GameLogic \ - --name "Blender GameEngine" --no-private --no-sourcecode --inheritance=included *.py +epydoc --debug -v -o BPY_GE --url "http://www.blender.org" --top API_intro \ + --name "Blender GameEngine" --no-private --no-sourcecode --inheritance=included \ + *.py \ + ../../../source/blender/python/api2_2x/doc/BGL.py \ + ../../../source/blender/python/api2_2x/doc/Mathutils.py \ + ../../../source/blender/python/api2_2x/doc/Geometry.py + From fc9f893306c359c8a9102745840d749f056fcbed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 20 May 2009 03:30:50 +0000 Subject: [PATCH 279/444] remove module that was never used. --- release/scripts/bpymodules/BPyMesh_octree.py | 332 ------------------- 1 file changed, 332 deletions(-) delete mode 100644 release/scripts/bpymodules/BPyMesh_octree.py diff --git a/release/scripts/bpymodules/BPyMesh_octree.py b/release/scripts/bpymodules/BPyMesh_octree.py deleted file mode 100644 index 368a33496eb..00000000000 --- a/release/scripts/bpymodules/BPyMesh_octree.py +++ /dev/null @@ -1,332 +0,0 @@ -from Blender import * - -try: - import psyco - psyco.full() -except: - print 'no psyco for you!' - -DotVecs= Mathutils.DotVecs -#======================================================== -# SPACIAL TREE - Seperate Class - use if you want to -# USed for getting vert is a proximity -LEAF_SIZE = 128 -class octreeNode: - def __init__(self, verts, parent): - - # Assunme we are a leaf node, until split is run. - self.verts = verts - self.children = [] - - if parent == None: # ROOT NODE, else set bounds when making children, - # BOUNDS - v= verts[0] - maxx,maxy,maxz= v.co - minx,miny,minz= maxx,maxy,maxz - - for v in verts: - x,y,z= v.co - if x>maxx: maxx= x - if y>maxy: maxy= y - if z>maxz: maxz= z - - if x LEAF_SIZE: - self.makeChildren() # 8 new children, - self.verts = None - # Alredy assumed a leaf not so dont do anything here. - - def makeChildren(self): - verts= self.verts - # Devide into 8 children. - axisDividedVerts = [[],[],[],[],[],[],[],[]] # Verts Only - - - divx = (self.maxx + self.minx) / 2 - divy = (self.maxy + self.miny) / 2 - divz = (self.maxz + self.minz) / 2 - - # Sort into 8 - for v in verts: - x,y,z = v.co - - if x > divx: - if y > divy: - if z > divz: - axisDividedVerts[0].append(v) - else: - axisDividedVerts[1].append(v) - else: - if z > divz: - axisDividedVerts[2].append(v) - else: - axisDividedVerts[3].append(v) - else: - if y > divy: - if z > divz: - axisDividedVerts[4].append(v) - else: - axisDividedVerts[5].append(v) - else: - if z > divz: - axisDividedVerts[6].append(v) - else: - axisDividedVerts[7].append(v) - - # populate self.children - for i in xrange(8): - octNode = octreeNode(axisDividedVerts[i], self) - # Set bounds manually - if i == 0: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 1: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = self.minz # - octNode.maxz = divz # - elif i == 2: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 3: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = self.minz # - octNode.maxz = divz # - elif i == 4: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 5: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = self.minz # - octNode.maxz = divz # - elif i == 6: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 7: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = self.minz # - octNode.maxz = divz # - #octNode.setCornerPoints() - octNode.splitNode() # Splits the node if it can. - self.children.append(octNode) - - # GETS VERTS IN A Distance RANGE- - def getVertsInRange(self, loc, normal, range_val, vertList): - #loc= Mathutils.Vector(loc) # MUST BE VECTORS - #normal= Mathutils.Vector(normal) - - ''' - loc: Vector of the location to search from - normal: None or Vector - if a vector- will only get verts on this side of the vector - range_val: maximum distance. A negative value will fill the list with teh closest vert only. - vertList: starts as an empty list - list that this function fills with verts that match - ''' - xloc,yloc,zloc= loc - - if range_val<0: - range_val= -range_val - FIND_CLOSEST= True - vertList.append(None) # just update the 1 vertex - else: - FIND_CLOSEST= False - - if self.children: - # Check if the bounds are in range_val, - for childNode in self.children: - # First test if we are surrounding the point. - if\ - childNode.minx - range_val < xloc and\ - childNode.maxx + range_val > xloc and\ - childNode.miny - range_val < yloc and\ - childNode.maxy + range_val > yloc and\ - childNode.minz - range_val < zloc and\ - childNode.maxz + range_val > zloc: - # Recurse down or get virts. - childNode.getVertsInRange(loc, normal, range_val, vertList) - #continue # Next please - - else: # we are a leaf node. Test vert locations. - if not normal: - # Length only check - for v in self.verts: - length = (loc - v.co).length - if length < range_val: - if FIND_CLOSEST: - # Just update the 1 vert - vertList[0]= (v, length) - range_val= length # Shink the length so we only get verts from their. - else: - vertList.append((v, length)) - else: - # Lengh and am I infront of the vert. - for v in self.verts: - length = (loc - v.co).length - if length < range_val: - # Check if the points in front - dot= DotVecs(normal, loc) - DotVecs(normal, v.co) - if dot<0: - vertList.append((v, length)) - -# END TREE - - - - -# EXAMPLE RADIO IN PYTHON USING THE ABOVE FUNCTION -""" -import BPyMesh -# Radio bake -def bake(): - - _AngleBetweenVecs_= Mathutils.AngleBetweenVecs - def AngleBetweenVecs(a1,a2): - try: - return _AngleBetweenVecs_(a1,a2) - except: - return 180 - - - - scn = Scene.GetCurrent() - ob = scn.getActiveObject() - me = ob.getData(mesh=1) - - dist= Draw.PupFloatInput('MaxDist:', 2.0, 0.1, 20.0, 0.1, 3) - if dist==None: - return - - # Make nice normals - BPyMesh.meshCalcNormals(me) - - - len_verts= len(me.verts) - #me.sel= False - meshOctTree = octreeNode(me.verts, None) - - - - # Store face areas - vertex_areas= [0.0] * len_verts - - # Get vertex areas - all areas of face users - for f in me.faces: - a= f.area - for v in f.v: - vertex_areas[v.index] += a - - - - bias= 0.001 - - t= sys.time() - - # Tone for the verts - vert_tones= [0.0] * len_verts - maxtone= 0.0 - mintone= 100000000 - for i, v in enumerate(me.verts): - if not i%10: - print 'verts to go', len_verts-i - v_co= v.co - v_no= v.no - verts_in_range= [] - meshOctTree.getVertsInRange(v_co, v_no, dist, verts_in_range) - - tone= 0.0 - # These are verts in our range - for test_v, length in verts_in_range: - if bias 90: # were facing this vert - #if 1: - # Current value us between zz90 and 180 - # make between 0 and 90 - # so 0 is right angles and 90 is direct opposite vertex normal - normal_diff= (normal_diff-90) - - # Vertex area needs to be taken into account so we dont have small faces over influencing. - vertex_area= vertex_areas[test_v.index] - - # Get the angle the vertex is in location from the location and normal of the vert. - above_diff= AngleBetweenVecs(test_v.co-v.co, v_no) - ## Result will be between 0 :above and 90: horizon.. invert this so horizon has littel effect - above_diff= 90-above_diff - # dist-length or 1.0/length both work well - tone= (dist-length) * vertex_area * above_diff * normal_diff - vert_tones[i] += tone - - if maxtonevert_tones[i]: - mintone= vert_tones[i] - - - if not maxtone: - Draw.PupMenu('No verts in range, use a larger range') - return - - # Apply tones - for f in me.faces: - f_col= f.col - for i, v in enumerate(f.v): - c= f_col[i] - v_index= v.index - tone= int(((maxtone - vert_tones[v.index]) / maxtone) * 255 ) - #print tone - c.r= c.g= c.b= tone - - print 'time', sys.time()-t - - -if __name__=="__main__": - bake() -""" \ No newline at end of file From dc6ae673b1d95d28c4fab4dbfbd9947d4a6c3bb2 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 20 May 2009 05:33:39 +0000 Subject: [PATCH 280/444] Moving ScreenSpace methods from Rasterizer to KX_Camera (getScreenPos, getScreenVect, getScreenRay) The modules were moved in order to access the camera internal matrixes. It will make then compatible with multiple viewports in a near future. So far the problem I found was: 1) KX_Camera doesn't store the canvas viewport 2) RAS_ICanvas methods: GetDisplayArea and GetWindowArea are affected by multiple viewports (and they shouldn't). Test file is here: http://www.pasteall.org/blend/68 --- source/gameengine/Ketsji/KX_Camera.cpp | 144 ++++++++++++++++++++- source/gameengine/Ketsji/KX_Camera.h | 4 + source/gameengine/Ketsji/KX_PythonInit.cpp | 128 ------------------ source/gameengine/PyDoc/GameTypes.py | 43 ++++++ source/gameengine/PyDoc/Rasterizer.py | 44 ------- 5 files changed, 189 insertions(+), 174 deletions(-) diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index fe50b371475..4bef4936813 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -28,6 +28,7 @@ * Camera in the gameengine. Cameras are also used for views. */ +#include "GL/glew.h" #include "KX_Camera.h" #include "KX_Scene.h" #include "KX_PythonInit.h" @@ -478,7 +479,10 @@ PyMethodDef KX_Camera::Methods[] = { KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera), KX_PYMETHODTABLE(KX_Camera, setViewport), KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop), - + KX_PYMETHODTABLE_O(KX_Camera, getScreenPosition), + KX_PYMETHODTABLE(KX_Camera, getScreenVect), + KX_PYMETHODTABLE(KX_Camera, getScreenRay), + // DEPRECATED KX_PYMETHODTABLE_O(KX_Camera, enableViewport), KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix), @@ -989,4 +993,140 @@ bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok } return false; -} \ No newline at end of file +} + +KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition, +"getScreenPosition()\n" +) + +{ + MT_Vector3 vect; + KX_GameObject *obj = NULL; + + if (!PyVecTo(value, vect)) + { + if(ConvertPythonToGameObject(value, &obj, true, "")) + { + PyErr_Clear(); + vect = MT_Vector3(obj->NodeGetWorldPosition()); + } + else + { + PyErr_SetString(PyExc_TypeError, "Error in getScreenPosition. Expected a Vector3 or a KX_GameObject or a string for a name of a KX_GameObject"); + return NULL; + } + } + + GLint viewport[4]; + GLdouble win[3]; + GLdouble modelmatrix[16]; + GLdouble projmatrix[16]; + + MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix(); + MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix(); + + m_modelmatrix.getValue(modelmatrix); + m_projmatrix.getValue(projmatrix); + + glGetIntegerv(GL_VIEWPORT, viewport); + + gluProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]); + + vect[0] = win[0] / (viewport[0] + viewport[2]); + vect[1] = win[1] / (viewport[1] + viewport[3]); + + PyObject* ret = PyTuple_New(2); + if(ret){ + PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(vect[0])); + PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(vect[1])); + return ret; + } + + return NULL; +} + +KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect, +"getScreenVect()\n" +) +{ + double x,y; + if (!PyArg_ParseTuple(args,"dd:getScreenVect",&x,&y)) + return NULL; + + MT_Vector3 vect; + MT_Point3 campos, screenpos; + + GLint viewport[4]; + GLdouble win[3]; + GLdouble modelmatrix[16]; + GLdouble projmatrix[16]; + + MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix(); + MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix(); + + m_modelmatrix.getValue(modelmatrix); + m_projmatrix.getValue(projmatrix); + + glGetIntegerv(GL_VIEWPORT, viewport); + + vect[0] = x * viewport[2]; + vect[1] = y * viewport[3]; + + vect[0] += viewport[0]; + vect[1] += viewport[1]; + + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vect[2]); + gluUnProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]); + + campos = this->GetCameraLocation(); + screenpos = MT_Point3(win[0], win[1], win[2]); + vect = campos-screenpos; + + vect.normalize(); + return PyObjectFrom(vect); +} + +KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay, +"getScreenRay()\n" +) +{ + KX_Camera* cam; + MT_Vector3 vect; + double x,y,dist; + char *propName = NULL; + + if (!PyArg_ParseTuple(args,"ddd|s:getScreenRay",&x,&y,&dist,&propName)) + return NULL; + + PyObject* argValue = PyTuple_New(2); + if (argValue) { + PyTuple_SET_ITEM(argValue, 0, PyFloat_FromDouble(x)); + PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(y)); + } + + if(!PyVecTo(PygetScreenVect(argValue), vect)) + { + Py_DECREF(argValue); + PyErr_SetString(PyExc_TypeError, + "Error in getScreenRay. Invalid 2D coordinate. Expected a normalized 2D screen coordinate, a distance and an optional property argument"); + return NULL; + } + Py_DECREF(argValue); + + dist *= -1.0; + + argValue = (propName?PyTuple_New(3):PyTuple_New(2)); + if (argValue) { + PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect)); + PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist)); + if (propName) + PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName)); + + PyObject* ret= this->PyrayCastTo(argValue,NULL); + Py_DECREF(argValue); + return ret; + } + + return NULL; +} + diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index c00741bf43f..2ec60be0404 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -273,6 +273,10 @@ public: KX_PYMETHOD_DOC_VARARGS(KX_Camera, setViewport); KX_PYMETHOD_DOC_NOARGS(KX_Camera, setOnTop); + KX_PYMETHOD_DOC_O(KX_Camera, getScreenPosition); + KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenVect); + KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenRay); + virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */ virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject *pyvalue); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index d32f3b1b8a2..fb99eab7747 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -511,128 +511,6 @@ static struct PyMethodDef game_methods[] = { {NULL, (PyCFunction) NULL, 0, NULL } }; - -static PyObject* gPyGetScreenPosition(PyObject*, PyObject* value) -{ - MT_Vector3 vect; - KX_GameObject *obj = NULL; - - if (!PyVecTo(value, vect)) - { - if(ConvertPythonToGameObject(value, &obj, true, "")) - { - PyErr_Clear(); - vect = MT_Vector3(obj->NodeGetWorldPosition()); - } - else - { - PyErr_SetString(PyExc_TypeError, "Error in getScreenPosition. Expected a Vector3 or a KX_GameObject or a string for a name of a KX_GameObject"); - return NULL; - } - } - - GLdouble modelMatrix[16]; - GLdouble projMatrix[16]; - GLint viewport[4]; - GLdouble win[3]; - - glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); - - gluProject(vect[0], vect[1], vect[2], modelMatrix, projMatrix, viewport, &win[0], &win[1], &win[2]); - - vect[0] = win[0] / (viewport[0] + viewport[2]); - vect[1] = win[1] / (viewport[1] + viewport[3]); - - PyObject* ret = PyTuple_New(2); - if(ret){ - PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(vect[0])); - PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(vect[1])); - return ret; - } - - return NULL; -} - -static PyObject* gPyGetScreenVect(PyObject*, PyObject* args) -{ - double x,y; - if (!PyArg_ParseTuple(args,"dd:getScreenVect",&x,&y)) - return NULL; - - MT_Vector3 vect; - MT_Point3 campos, screenpos; - - GLdouble modelMatrix[16]; - GLdouble projMatrix[16]; - GLint viewport[4]; - GLdouble win[3]; - - glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); - - vect[0] = x * viewport[2]; - vect[1] = y * viewport[3]; - - vect[0] += viewport[0]; - vect[1] += viewport[1]; - - glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vect[2]); - gluUnProject(vect[0], vect[1], vect[2], modelMatrix, projMatrix, viewport, &win[0], &win[1], &win[2]); - - campos = gp_Rasterizer->GetCameraPosition(); - screenpos = MT_Point3(win[0], win[1], win[2]); - vect = campos-screenpos; - - vect.normalize(); - return PyObjectFrom(vect); -} - -static PyObject* gPyGetScreenRay(PyObject* self, PyObject* args) -{ - KX_Camera* cam; - MT_Vector3 vect; - double x,y,dist; - char *propName = NULL; - - if (!PyArg_ParseTuple(args,"ddd|s:getScreenRay",&x,&y,&dist,&propName)) - return NULL; - - PyObject* argValue = PyTuple_New(2); - if (argValue) { - PyTuple_SET_ITEM(argValue, 0, PyFloat_FromDouble(x)); - PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(y)); - } - - if(!PyVecTo(gPyGetScreenVect(self,argValue), vect)) - { - Py_DECREF(argValue); - PyErr_SetString(PyExc_TypeError, - "Error in getScreenRay. Invalid 2D coordinate. Expected a normalized 2D screen coordinate and an optional property argument"); - return NULL; - } - Py_DECREF(argValue); - - cam = gp_KetsjiScene->GetActiveCamera(); - dist *= -1.0; - - argValue = (propName?PyTuple_New(3):PyTuple_New(2)); - if (argValue) { - PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect)); - PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist)); - if (propName) - PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName)); - - PyObject* ret= cam->PyrayCastTo(argValue,NULL); - Py_DECREF(argValue); - return ret; - } - - return NULL; -} - static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args) { return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetHeight() : 0)); @@ -1047,12 +925,6 @@ static PyObject* gPyDrawLine(PyObject*, PyObject* args) } static struct PyMethodDef rasterizer_methods[] = { - {"getScreenPosition",(PyCFunction) gPyGetScreenPosition, - METH_O, "getScreenPosition doc"}, - {"getScreenVect",(PyCFunction) gPyGetScreenVect, - METH_VARARGS, "getScreenVect doc"}, - {"getScreenRay",(PyCFunction) gPyGetScreenRay, - METH_VARARGS, "getScreenRay doc"}, {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, METH_VARARGS, "getWindowWidth doc"}, {"getWindowHeight",(PyCFunction) gPyGetWindowHeight, diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 5ec6f31e30c..b5dc89e4002 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -5555,6 +5555,49 @@ class KX_Camera(KX_GameObject): @type right: int @type top: int """ + def getScreenPosition(arg): + """ + Gets the position of an object projected on screen space. + + Example: + # For an object in the middle of the screen, coord = [0.5,0.5] + coord = camera.getScreenPosition(object) + + @param arg: L{KX_GameObject}, object name or list [x, y, z] + @rtype: list [x, y] + @return: the object's position in screen coordinates. + """ + def getScreenVect(x, y): + """ + Gets the vector from the camera position in the screen coordinate direction. + + Example: + # Gets the vector of the camera front direction: + m_vect = camera.getScreenVect(0.5,0.5) + + @type x: float + @type y: float + @rtype: 3d vector + @return: the vector from a screen coordinate. + """ + def getScreenRay(x, y, dist, property): + """ + Look towards a screen coordinate (x,y) and find first object hit within dist that matches prop. + The ray is similar to KX_GameObject->rayCastTo. + + Example: + # Gets an object with a property "wall" in front of the camera within a distance of 100: + target = camera.getScreenRay(0.5,0.5,100,"wall") + + @type x: float + @type y: float + @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other + @type dist: float + @param property: property name that object must have; can be omitted => detect any object + @type property: string + @rtype: L{KX_GameObject} + @return: the first object hit or None if no object or object does not match prop + """ # Util func to extract all attrs """ diff --git a/source/gameengine/PyDoc/Rasterizer.py b/source/gameengine/PyDoc/Rasterizer.py index 25877364836..bafcfece473 100644 --- a/source/gameengine/PyDoc/Rasterizer.py +++ b/source/gameengine/PyDoc/Rasterizer.py @@ -43,50 +43,6 @@ Example Uses an L{SCA_MouseSensor}, and two L{KX_ObjectActuator}s to implement M @var KX_BLENDER_GLSL_MATERIAL: Materials approximating blender materials with GLSL. """ - -def getScreenPosition(arg): - """ - Gets the position of an object projected on screen space. - - Example: - # For an object in the middle of the screen, coord = [0.5,0.5] - coord = Rasterizer.getScreenPosition(object) - - @param arg: L{KX_GameObject}, object name or list [x, y, z] - @rtype: list [x, y] - @return: the object's position in screen coordinates. - """ -def getScreenVect(x, y): - """ - Gets the vector from the camera position in the screen coordinate direction. - - Example: - # Gets the vector of the camera front direction: - m_vect = Rasterizer.getScreenVect(0.5,0.5) - - @type x: float - @type y: float - @rtype: 3d vector - @return: the vector from a screen coordinate. - """ -def getScreenRay(x, y, dist, property): - """ - Look towards a screen coordinate (x,y) and find first object hit within dist that matches prop. - The ray is similar to KX_GameObject->rayCastTo. - - Example: - # Gets an object with a property "wall" in front of the camera within a distance of 100: - target = Rasterizer.getScreenRay(0.5,0.5,100,"wall") - - @type x: float - @type y: float - @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other - @type dist: float - @param property: property name that object must have; can be omitted => detect any object - @type property: string - @rtype: L{KX_GameObject} - @return: the first object hit or None if no object or object does not match prop - """ def getWindowWidth(): """ Gets the width of the window (in pixels) From c0844b7938ec21e1fcd2ceea11ef5ae18e39c070 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 20 May 2009 08:45:42 +0000 Subject: [PATCH 281/444] BGE logic patch: fix another incompatibility with YF. Previous patch was not sorting the state actuators. This was causing some problems with YoFrankie that relies on the order of actuators when multiple state actuators are activated at once. Active state actuators will now be sorted per object. This doesn't change the fact that state actuators are executed before all other actuators as before. Incidently, made the logic loop faster. --- source/gameengine/GameLogic/SCA_IActuator.cpp | 2 ++ source/gameengine/GameLogic/SCA_IActuator.h | 3 +- source/gameengine/GameLogic/SCA_ILogicBrick.h | 28 +++++++++++++++++ source/gameengine/GameLogic/SCA_IObject.cpp | 3 +- source/gameengine/GameLogic/SCA_IObject.h | 6 ++++ .../gameengine/GameLogic/SCA_LogicManager.cpp | 30 ++++++++++--------- .../gameengine/GameLogic/SCA_LogicManager.h | 3 -- source/gameengine/Ketsji/KX_StateActuator.cpp | 12 ++++++-- source/gameengine/SceneGraph/SG_QList.h | 2 +- 9 files changed, 65 insertions(+), 24 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index c2be36d5108..be7c2651686 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -67,6 +67,8 @@ void SCA_IActuator::Activate(SG_DList& head) } } +// this function is only used to deactivate actuators outside the logic loop +// e.g. when an object is deleted. void SCA_IActuator::Deactivate() { if (QDelink()) diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 2bd92c343b9..27afcbc386b 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -33,8 +33,7 @@ #include /* - * Use of SG_DList : element of actuator being deactivated - * Head: SCA_LogicManager::m_removedActuators + * Use of SG_DList : None * Use of SG_QList : element of activated actuator list of their owner * Head: SCA_IObject::m_activeActuators */ diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index 90881c0536f..779e5397a6a 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -92,6 +92,34 @@ public: it.add_back(this); } + // insert in a QList at position corresponding to m_Execute_Priority + // inside a longer list that contains elements of other objects. + // Sorting is done only between the elements of the same object. + // head is the head of the combined list + // current points to the first element of the object in the list, NULL if none yet + void InsertSelfActiveQList(SG_QList& head, SG_QList** current) + { + if (!*current) + { + // first element can be put anywhere + head.QAddBack(this); + *current = this; + return; + } + // note: we assume current points actually to one o our element, skip the tests + SG_QList::iterator it(head,*current); + if (m_Execute_Priority <= (*it)->m_Execute_Priority) + { + // this element comes before the first + *current = this; + } + else + { + for(++it; !it.end() && (*it)->m_gameobj == m_gameobj && m_Execute_Priority > (*it)->m_Execute_Priority; ++it); + } + it.add_back(this); + } + virtual bool LessComparedTo(SCA_ILogicBrick* other); virtual PyObject* py_getattro(PyObject *attr); diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 2b87a7c1526..9876f2512c0 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -41,7 +41,8 @@ MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0); SG_QList SCA_IObject::m_activeBookmarkedControllers; -SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0) +SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0), m_firstState(NULL) + { m_suspended = false; } diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index c4f346059d4..eae427741ca 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -52,6 +52,7 @@ class SCA_IObject : public CValue Py_Header; protected: + friend class KX_StateActuator; friend class SCA_IActuator; friend class SCA_IController; SCA_SensorList m_sensors; @@ -97,6 +98,11 @@ protected: */ unsigned int m_state; + /** + * pointer inside state actuator list for sorting + */ + SG_QList* m_firstState; + public: SCA_IObject(PyTypeObject* T=&Type); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index 7acec465921..83271288154 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -212,17 +212,22 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame) (*ie)->UpdateFrame(); SG_DList::iterator io(m_activeActuators); - for (io.begin(); !io.end(); ++io) + for (io.begin(); !io.end(); ) { - SG_QList::iterator ia(*(*io)); - for (ia.begin(); !ia.end(); ++ia) + SG_QList* ahead = *io; + // increment now so that we can remove the current element + ++io; + SG_QList::iterator ia(*ahead); + for (ia.begin(); !ia.end(); ) { SCA_IActuator* actua = *ia; + // increment first to allow removal of inactive actuators. + ++ia; if (!actua->Update(curtime, frame)) { - // cannot deactive the actuator now as it will disturb the list - m_removedActuators.AddBack(actua); - actua->SetActive(false); + // this actuator is not active anymore, remove + actua->QDelink(); + actua->SetActive(false); } else if (actua->IsNoLink()) { // This actuator has no more links but it still active @@ -235,14 +240,11 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame) actua->AddEvent(event); } } - } - - for (SCA_IActuator* act = (SCA_IActuator*)m_removedActuators.Remove(); - act != NULL; - act = (SCA_IActuator*)m_removedActuators.Remove()) - { - act->Deactivate(); - act->SetActive(false); + if (ahead->QEmpty()) + { + // no more active controller, remove from main list + ahead->Delink(); + } } } diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index fe7b40b3ba4..53e75e1eaee 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -87,9 +87,6 @@ class SCA_LogicManager GEN_Map m_map_gamemeshname_to_blendobj; GEN_Map m_map_blendobj_to_gameobj; - - // head of actuators being deactivated during the logic update - SG_DList m_removedActuators; public: SCA_LogicManager(); virtual ~SCA_LogicManager(); diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index 5f9730d7e10..f6979eee0f4 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -73,7 +73,10 @@ KX_StateActuator::Update() { bool bNegativeEvent = IsNegativeEvent(); unsigned int objMask; - + + // execution of state actuator means that we are in the execution phase, reset this pointer + // because all the active actuator of this object will be removed for sure. + m_gameobj->m_firstState = NULL; RemoveAllEvents(); if (bNegativeEvent) return false; @@ -102,6 +105,8 @@ KX_StateActuator::Update() return false; } +// this function is only used to deactivate actuators outside the logic loop +// e.g. when an object is deleted. void KX_StateActuator::Deactivate() { if (QDelink()) @@ -115,9 +120,10 @@ void KX_StateActuator::Deactivate() void KX_StateActuator::Activate(SG_DList& head) { - // no need to sort the state actuators - if (m_stateActuatorHead.QAddBack(this)) + // sort the state actuators per object on the global list + if (QEmpty()) { + InsertSelfActiveQList(m_stateActuatorHead, &m_gameobj->m_firstState); // add front to make sure it runs before other actuators head.AddFront(&m_stateActuatorHead); } diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h index 7a6b2e466c9..d8afc33ea4f 100644 --- a/source/gameengine/SceneGraph/SG_QList.h +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -49,7 +49,7 @@ public: T* m_current; public: typedef iterator _myT; - iterator(SG_QList& head) : m_head(head), m_current(NULL) {} + iterator(SG_QList& head, SG_QList* current=NULL) : m_head(head) { m_current = (T*)current; } ~iterator() {} void begin() From ac0766c64b62ca74cb29b3d58c40d2ce92ec5b9b Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 20 May 2009 12:13:37 +0000 Subject: [PATCH 282/444] Fix for [#18785] Crash rendering hair particle system --- source/blender/render/intern/source/convertblender.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index cd141799f64..79ab661e578 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1766,7 +1766,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(parent->num < psmd->dm->getNumFaces(psmd->dm)) num = parent->num; - get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd); + get_particle_uvco_mcol(part->from, psmd->dm, parent->fuv, num, &sd); } dosimplify = psys_render_simplify_params(psys, cpa, simplify); From fcdb34f593735f977589e925c4c66883603d2bbc Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 20 May 2009 21:34:50 +0000 Subject: [PATCH 283/444] BGE #18664: Incorrect behavior for objects when unparented. A parented object is made static in all cases. --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 13aac74edca..bf965f677c6 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1571,8 +1571,8 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, } - if (parent && (parent->gameflag & OB_DYNAMIC)) { - + if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) { + // parented object cannot be dynamic KX_GameObject *parentgameobject = converter->FindGameObject(parent); objprop.m_dynamic_parent = parentgameobject; //cannot be dynamic: From 3daa8bd4ef5a52c40b01827b55df3807a1917eea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 20 May 2009 23:31:58 +0000 Subject: [PATCH 284/444] fix for [#18772] c3d_import script crashes Patch from Roger Wickes update to 2.48 sFrame, eFrame, fps. [#18794] GE API conversion script: 2.48 -> 2.49 patch from Alex Fraser (z0r), will test further in the next few days. --- This is text plug in and standalone script that updates Blender 2.48 Game Engine scripts to be compatible with the 2.49 API. The script contains a mapping of attribute names to functions that do the conversion. Most of the mappings were extracted from the documentation in GameTypes.py. Where the conversion is ambiguous, the script will not change the source except to insert a warning as a comment. This means that the script does not completely automate the conversion process, but will do a lot of the work. The script still needs a fair bit of testing. Many of the mappings have not been tested and could result in broken scripts. I'm submitting this patch now to start the review process early. I think I might need help if it is to be included in 2.49. --- release/scripts/c3d_import.py | 7 +- release/scripts/textplugin_convert_ge.py | 677 +++++++++++++++++++++++ source/gameengine/PyDoc/GameTypes.py | 85 ++- 3 files changed, 764 insertions(+), 5 deletions(-) create mode 100644 release/scripts/textplugin_convert_ge.py diff --git a/release/scripts/c3d_import.py b/release/scripts/c3d_import.py index bfe691c394c..98f643cbab9 100644 --- a/release/scripts/c3d_import.py +++ b/release/scripts/c3d_import.py @@ -527,9 +527,10 @@ def setupAnim(StartFrame, EndFrame, VideoFrameRate): if VideoFrameRate>120: VideoFrameRate=120 # set up anim panel for them context=scn.getRenderingContext() - context.startFrame(StartFrame) - context.endFrame(EndFrame) - context.framesPerSec(int(VideoFrameRate)) + context.sFrame=StartFrame + context.eFrame=EndFrame + context.fps=int(VideoFrameRate) + Blender.Set("curframe",StartFrame) Blender.Redraw() return diff --git a/release/scripts/textplugin_convert_ge.py b/release/scripts/textplugin_convert_ge.py new file mode 100644 index 00000000000..4a472247dcc --- /dev/null +++ b/release/scripts/textplugin_convert_ge.py @@ -0,0 +1,677 @@ +#!BPY +""" +Name: 'Convert BGE 2.49' +Blender: 246 +Group: 'TextPlugin' +Shortcut: '' +Tooltip: 'Attemps to update deprecated usage of game engine API.' +""" + +# +# Copyright 2009 Alex Fraser +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import string +import re + +COMMENTCHAR = '#' + +class ParseError(Exception): pass +class ConversionError(Exception): pass + +def findBalancedParens(lines, row, col, openChar = '(', closeChar = ')'): + """Finds a balanced pair of parentheses, searching from lines[row][col]. + The opening parenthesis must be on the starting line. + + Returns a 4-tuple containing the row and column of the opening paren, and + the row and column of the matching paren. + + Throws a ParseError if the first character is not openChar, or if a matching + paren cannot be found.""" + + # + # Find the opening coordinates. + # + oRow = row + oCol = col + line = lines[oRow] + while oCol < len(line): + if line[oCol] == openChar: + break + elif line[oCol] == COMMENTCHAR: + break + oCol = oCol + 1 + + if oCol >= len(line) or line[oCol] != openChar or not re.match(r'^\s*$', line[col:oCol]): + raise ParseError, "Can't find opening parenthesis. '%s'" % openChar + + # + # Find the closing coordinates. + # + eRow = oRow + eCol = oCol + 1 + level = 1 + while eRow < len(lines) and level > 0: + line = lines[eRow] + while eCol < len(line) and level > 0: + c = line[eCol] + if c == openChar: + # Found a nested paren. + level = level + 1 + elif c == closeChar: + # Exiting one level of nesting. + level = level - 1 + if level == 0: + # Back to top level! + return (oRow, oCol), (eRow, eCol) + elif c == COMMENTCHAR: + # Comment. Skip the rest of the line. + break + eCol = eCol + 1 + eRow = eRow + 1 + eCol = 0 + raise ParseError, "Couldn't find closing parenthesis." + +def findLastAssignment(lines, row, attrName): + """Finds the most recent assignment of `attrName' before `row'. Returns + everything after the '=' sign or None, if there was no match.""" + contRegex = re.compile(r'[^#]*?' + # Don't search in comments. + attrName + + r'\s*=\s*(.*)') # Assignment + + cRow = row - 1 + while cRow >= 0: + match = contRegex.search(lines[cRow]) + if match: + return match.group(1) + cRow = cRow - 1 + return None + +def replaceSubstr(s, start, end, newSubStr): + """Replace the contents of `s' between `start' and `end' with + `newSubStr'.""" + return s[:start] + newSubStr + s[end:] + +def replaceNextParens(lines, row, colStart, newOpenChar, newCloseChar, + oldOpenChar = '(', oldCloseChar = ')'): + """Replace the next set of parentheses with different characters. The + opening parenthesis must be located on line `row', and on or after + `colStart'. The closing parenthesis may be on the same line or any following + line. The strings are edited in-place. + + Throws a ParseError if the set of parentheses can't be found. In this case, + the strings in `lines' will be untouched.""" + try: + pOpen, pClose = findBalancedParens(lines, row, colStart, oldOpenChar, + oldCloseChar) + except ParseError: + raise + + # Replacement may change string length. Replace closing paren first. + r, c = pClose + lines[r] = replaceSubstr(lines[r], c, c + 1, newCloseChar) + # Replace opening paren. + r, c = pOpen + lines[r] = replaceSubstr(lines[r], c, c + 1, newOpenChar) + +def replaceSimpleGetter(lines, row, colStart, colEnd, newName): + """Replace a call to a simple getter function with a reference to a + property, e.g. foo.getBar() -> foo.bar + + The function identifier being replaced must be on line `row' and + between `colStart' and `colEnd'. The opening parenthesis must follow + immediately (whitespace is allowed). The closing parenthesis may be on the + same or following lines. + + Throws a ConversionError if the parentheses can't be found. In this case + the content of `lines' will be untouched.""" + try: + replaceNextParens(lines, row, colEnd, newOpenChar = '', newCloseChar = '') + except ParseError: + raise ConversionError, ("Deprecated function reference.") + + lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName) + +def replaceSimpleSetter(lines, row, colStart, colEnd, newName): + """Replace a call to a simple setter function with a reference to a + property, e.g. foo.setBar(baz) -> foo.bar = baz + + The function identifier being replaced must be on line `row' and + between `colStart' and `colEnd'. The opening parenthesis must follow + immediately (whitespace is allowed). The closing parenthesis may be on the + same or following lines. + + Throws a ConversionError if the parentheses can't be found. In this case + the content of `lines' will be untouched.""" + try: + replaceNextParens(lines, row, colEnd, newOpenChar = '', newCloseChar = '') + except ParseError: + raise ConversionError, ("Deprecated function reference.") + + lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName + ' = ') + +def replaceKeyedGetter(lines, row, colStart, colEnd, newName): + """Replace a call to a keyed getter function with a reference to a + property, e.g. foo.getBar(baz) -> foo.bar[baz] + + The function identifier being replaced must be on line `row' and + between `colStart' and `colEnd'. The opening parenthesis must follow + immediately (whitespace is allowed). The closing parenthesis may be on the + same or following lines. + + Throws a ConversionError if the parentheses can't be found. In this case + the content of `lines' will be untouched.""" + try: + replaceNextParens(lines, row, colEnd, newOpenChar = '[', newCloseChar = ']') + except ParseError: + raise ConversionError, ("Deprecated function reference.") + + lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName) + +def replaceGetXYPosition(lines, row, colStart, colEnd, axis): + '''SCA_MouseSensor.getXPosition; SCA_MouseSensor.getYPosition. + This is like a keyed getter, but the key is embedded in the attribute + name. + + Throws a ConversionError if the parentheses can't be found. In this case + the content of `lines' will be untouched.''' + try: + (openRow, openCol), (closeRow, closeCol) = findBalancedParens(lines, + row, colEnd) + except ParseError: + raise ConversionError, "Deprecated function reference." + if closeRow != row: + raise ConversionError, "Can't modify multiple lines." + + lines[row] = replaceSubstr(lines[row], openCol, closeCol + 1, + "[%s]" % axis) + + lines[row] = replaceSubstr(lines[row], colStart, colEnd, 'position') + +def replaceRename(lines, row, colStart, colEnd, newName): + """Replace an identifier with another, e.g. foo.getBar() -> foo.getBaz() + + The identifier being replaced must be on line `row' and between `colStart' + and `colEnd'.""" + lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName) + +def replaceAddActiveActuator(lines, row, colStart, colEnd, closure): + '''Extra work needs to be done here to find out the name of the controller, + and whether the actuator should be activated or deactivated. + + Throws a ConversionError if the actuator, controller or condition can't be + found. In this case the content of `lines' will be untouched.''' + try: + (openRow, openCol), (closeRow, closeCol) = findBalancedParens(lines, row, colEnd) + except ParseError: + ConversionError, "Can't find arguments." + + if closeRow != openRow: + raise ConversionError, ("Can't perform conversion: arguments span multiple lines.") + + args = lines[row][openCol + 1:closeCol] + match = re.search(r'([a-zA-Z_]\w*)' # Actuator identifier + r',\s*' + r'([0-9a-zA-Z_]\w*)', # Condition (boolean) + args) + if not match: + raise ConversionError, "Can't find arguments." + + actuator = match.group(1) + condition = match.group(2) + controller = None + + assn = findLastAssignment(lines, row, actuator) + if assn: + match = re.search(r'([a-zA-Z_]\w*)' # Controller identifier + r'\s*\.\s*' # Dot + r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier + assn) + if match: + controller = match.group(1) + + if not controller: + raise ConversionError, "Can't find actuator's controller." + + gameLogicStart = lines[row].rfind("GameLogic", 0, colStart) + if gameLogicStart < 0: + raise ConversionError, "Can't find GameLogic identifier." + + newExpr = None + if condition in ['1', 'True']: + newExpr = "%s.activate(%s)" % (controller, actuator) + elif condition in ['0', 'False']: + newExpr = "%s.deactivate(%s)" % (controller, actuator) + else: + newExpr = "(lambda: %s and (%s.activate(%s) or True) or %s.deactivate(%s))()" % ( + condition, controller, actuator, controller, actuator) + lines[row] = replaceSubstr(lines[row], gameLogicStart, closeCol + 1, newExpr) + +def getObject(line, attributeStart): + match = re.search(r'([a-zA-Z_]\w*)\s*\.\s*$', line[0:attributeStart]) + if not match: + return None + return match.group(1) + +def replaceGetActuator(lines, row, colStart, colEnd, closure): + '''getActuator is ambiguous: it could belong to SCA_IController or + SCA_ActuatorSensor. Try to resolve. + + Raises a ConversionError if the parentheses can't be found, or if the + ambiguity can't be resolved.''' + # Get the name of the object this attribute is attached to. + obName = getObject(lines[row], colStart) + if obName: + # Try to find out whether the object is a controller. + assn = findLastAssignment(lines, row, obName) + if assn and re.search(r'GameLogic\s*\.\s*getCurrentController', assn): + # It is (probably) a controller! + replaceKeyedGetter(lines, row, colStart, colEnd, 'actuators') + return + + raise ConversionError, "Ambiguous: addActiveActuator -> actuators[key] (SCA_IController) or actuator (SCA_ActuatorSensor)." + +# +# Deprecated attribute information. The format is: +# deprecatedAttributeName: {(conversionFunction, closure): classList} +# Usually the closure will be the name of the superceding attribute. +# +# If an attribute maps to more than one function/attribute pair, the conversion +# is ambiguous and can't be performed. +# +attributeRenameDict = { + # Special cases + 'addActiveActuator': {(replaceAddActiveActuator, None): []}, + 'getActuator': {(replaceGetActuator, None): ['SCA_IController', 'SCA_ActuatorSensor']}, + 'getXPosition': {(replaceGetXYPosition, '0'): ['SCA_MouseSensor']}, + 'getYPosition': {(replaceGetXYPosition, '1'): ['SCA_MouseSensor']}, + + # Unimplemented! There are probably more of these below that would cause errors. + #'getLinearVelocity': {(replaceSimpleGetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, + #'setLinearVelocity': {(replaceSimpleSetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, + #'getAngularVelocity': {(replaceSimpleGetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, + #'setAngularVelocity': {(replaceSimpleSetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, + + # Generic converters + 'enableViewport': {(replaceSimpleSetter, 'useViewport'): ['KX_Camera']}, + 'getAction': {(replaceSimpleGetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, + 'getActuators': {(replaceKeyedGetter, 'actuators'): ['SCA_IController']}, + 'getAxis': {(replaceSimpleGetter, 'axis'): ['SCA_JoystickSensor']}, + 'getAxisValue': {(replaceSimpleGetter, 'axisSingle'): ['SCA_JoystickSensor']}, + 'getBlendin': {(replaceSimpleGetter, 'blendIn'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'getBodies': {(replaceSimpleGetter, 'bodies'): ['KX_NetworkMessageSensor']}, + 'getButton': {(replaceSimpleGetter, 'button'): ['SCA_JoystickSensor']}, + 'getButtonValue': {(replaceRename, 'getButtonActiveList'): ['SCA_JoystickSensor']}, + 'getCamera': {(replaceSimpleGetter, 'camera'): ['KX_SceneActuator']}, + 'getConeOrigin': {(replaceSimpleGetter, 'coneOrigin'): ['KX_RadarSensor']}, + 'getConeTarget': {(replaceSimpleGetter, 'coneTarget'): ['KX_RadarSensor']}, + 'getContinue': {(replaceSimpleGetter, 'useContinue'): ['BL_ActionActuator']}, + 'getCurrentlyPressedKeys': {(replaceSimpleGetter, 'events'): ['SCA_KeyboardSensor']}, + 'getDelay': {(replaceSimpleGetter, 'delay'): ['SCA_DelaySensor']}, + 'getDistribution': {(replaceSimpleGetter, 'distribution'): ['SCA_RandomActuator']}, + 'getDuration': {(replaceSimpleGetter, 'duration'): ['SCA_DelaySensor']}, + 'getEnd': {(replaceSimpleGetter, 'frameEnd'): ['BL_ShapeActionActuator', + 'KX_IpoActuator', + 'BL_ActionActuator']}, + 'getExecutePriority': {(replaceSimpleGetter, 'executePriority'): ['SCA_ILogicBrick']}, + 'getFile': {(replaceSimpleGetter, 'fileName'): ['KX_GameActuator']}, + 'getFilename': {(replaceSimpleGetter, 'fileName'): ['KX_SoundActuator']}, + 'getForceIpoActsLocal': {(replaceSimpleGetter, 'useIpoLocal'): ['KX_IpoActuator']}, + 'getFrame': {(replaceSimpleGetter, 'frame'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, + 'getFrameMessageCount': {(replaceSimpleGetter, 'frameMessageCount'): ['KX_NetworkMessageSensor']}, + 'getFrameProperty': {(replaceSimpleGetter, 'framePropName'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'getFrequency': {(replaceSimpleGetter, 'frequency'): ['SCA_ISensor']}, + 'getGain': {(replaceSimpleGetter, 'volume'): ['KX_SoundActuator', 'KX_CDActuator']}, + 'getHat': {(replaceSimpleGetter, 'hat'): ['SCA_JoystickSensor']}, + 'getHeight': {(replaceSimpleGetter, 'height'): ['KX_CameraActuator']}, + 'getHitNormal': {(replaceSimpleGetter, 'hitNormal'): ['KX_MouseFocusSensor', 'KX_RaySensor']}, + 'getHitObject': {(replaceSimpleGetter, 'hitObject'): ['KX_MouseFocusSensor', + 'KX_RaySensor', + 'KX_TouchSensor']}, + 'getHitObjectList': {(replaceSimpleGetter, 'hitObjectList'): ['KX_TouchSensor']}, + 'getHitPosition': {(replaceSimpleGetter, 'hitPosition'): ['KX_MouseFocusSensor', + 'KX_RaySensor']}, + 'getHold1': {(replaceSimpleGetter, 'hold1'): ['SCA_KeyboardSensor']}, + 'getHold2': {(replaceSimpleGetter, 'hold2'): ['SCA_KeyboardSensor']}, + 'getIndex': {(replaceSimpleGetter, 'index'): ['SCA_JoystickSensor']}, + 'getInvert': {(replaceSimpleGetter, 'invert'): ['SCA_ISensor']}, + 'getIpoAdd': {(replaceSimpleGetter, 'useIpoAdd'): ['KX_IpoActuator']}, + 'getIpoAsForce': {(replaceSimpleGetter, 'useIpoAsForce'): ['KX_IpoActuator']}, + 'getKey': {(replaceSimpleGetter, 'key'): ['SCA_KeyboardSensor']}, + 'getLastCreatedObject': {(replaceSimpleGetter, 'objectLastCreated'): ['KX_SCA_AddObjectActuator']}, + 'getLevel': {(replaceSimpleGetter, 'level'): ['SCA_ISensor']}, + 'getLightList': {(replaceSimpleGetter, 'lights'): ['KX_Scene']}, + 'getLooping': {(replaceSimpleGetter, 'looping'): ['KX_SoundActuator']}, + 'getMass': {(replaceSimpleGetter, 'mass'): ['KX_GameObject']}, + 'getMax': {(replaceSimpleGetter, 'max'): ['KX_CameraActuator']}, + 'getMesh': {(replaceSimpleGetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, + 'getMin': {(replaceSimpleGetter, 'min'): ['KX_CameraActuator']}, + 'getName': {(replaceSimpleGetter, 'name'): ['KX_Scene']}, + 'getNumAxes': {(replaceSimpleGetter, 'numAxis'): ['SCA_JoystickSensor']}, + 'getNumButtons': {(replaceSimpleGetter, 'numButtons'): ['SCA_JoystickSensor']}, + 'getNumHats': {(replaceSimpleGetter, 'numHats'): ['SCA_JoystickSensor']}, + 'getObject': {(replaceSimpleGetter, 'object'): ['KX_SCA_AddObjectActuator', + 'KX_CameraActuator', + 'KX_TrackToActuator', + 'KX_ParentActuator']}, + 'getObjectList': {(replaceSimpleGetter, 'objects'): ['KX_Scene']}, + 'getOperation': {(replaceSimpleGetter, 'mode'): ['KX_SCA_DynamicActuator']}, + 'getOrientation': {(replaceSimpleGetter, 'worldOrientation'): ['KX_GameObject']}, + 'getOwner': {(replaceSimpleGetter, 'owner'): ['SCA_ILogicBrick']}, + 'getPara1': {(replaceSimpleGetter, 'para1'): ['SCA_RandomActuator']}, + 'getPara2': {(replaceSimpleGetter, 'para2'): ['SCA_RandomActuator']}, + 'getParent': {(replaceSimpleGetter, 'parent'): ['KX_GameObject']}, + 'getPitch': {(replaceSimpleGetter, 'pitch'): ['KX_SoundActuator']}, + 'getPosition': {(replaceSimpleGetter, 'worldPosition'): ['KX_GameObject']}, + 'getPressedKeys': {(replaceSimpleGetter, 'events'): ['SCA_KeyboardSensor']}, + 'getPriority': {(replaceSimpleGetter, 'priority'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'getProjectionMatrix': {(replaceSimpleGetter, 'projection_matrix'): ['KX_Camera']}, + 'getProperty': {(replaceSimpleGetter, 'propName'): ['SCA_PropertySensor', + 'SCA_RandomActuator']}, + 'getRayDirection': {(replaceSimpleGetter, 'rayDirection'): ['KX_MouseFocusSensor', + 'KX_RaySensor']}, + 'getRaySource': {(replaceSimpleGetter, 'raySource'): ['KX_MouseFocusSensor']}, + 'getRayTarget': {(replaceSimpleGetter, 'rayTarget'): ['KX_MouseFocusSensor']}, + 'getRepeat': {(replaceSimpleGetter, 'repeat'): ['SCA_DelaySensor']}, + 'getRollOffFactor': {(replaceSimpleGetter, 'rollOffFactor'): ['KX_SoundActuator']}, + 'getScene': {(replaceSimpleGetter, 'scene'): ['KX_SceneActuator']}, + 'getScript': {(replaceSimpleGetter, 'script'): ['SCA_PythonController']}, + 'getSeed': {(replaceSimpleGetter, 'seed'): ['SCA_RandomActuator']}, + 'getSensor': {(replaceKeyedGetter, 'sensors'): ['SCA_IController']}, + 'getSensors': {(replaceKeyedGetter, 'sensors'): ['SCA_IController']}, + 'getStart': {(replaceSimpleGetter, 'frameStart'): ['BL_ShapeActionActuator', + 'KX_IpoActuator', + 'BL_ActionActuator']}, + 'getState': {(replaceSimpleGetter, 'state'): ['SCA_IController', 'KX_GameObject']}, + 'getSubject': {(replaceSimpleGetter, 'subject'): ['KX_NetworkMessageSensor']}, + 'getSubjects': {(replaceSimpleGetter, 'subjects'): ['KX_NetworkMessageSensor']}, + 'getThreshold': {(replaceSimpleGetter, 'threshold'): ['SCA_JoystickSensor']}, + 'getTime': {(replaceSimpleGetter, 'time'): ['KX_SCA_AddObjectActuator', 'KX_TrackToActuator']}, + 'getTouchMaterial': {(replaceSimpleGetter, 'useMaterial'): ['KX_TouchSensor']}, + 'getType': {(replaceSimpleGetter, 'mode'): ['SCA_PropertySensor']}, + 'getUse3D': {(replaceSimpleGetter, 'use3D'): ['KX_TrackToActuator']}, + 'getUseNegPulseMode': {(replaceSimpleGetter, 'useNegPulseMode'): ['SCA_ISensor']}, + 'getUsePosPulseMode': {(replaceSimpleGetter, 'usePosPulseMode'): ['SCA_ISensor']}, + 'getUseRestart': {(replaceSimpleGetter, 'useRestart'): ['KX_SceneActuator']}, + 'getValue': {(replaceSimpleGetter, 'value'): ['SCA_PropertySensor', 'SCA_PropertyActuator']}, + 'getVisible': {(replaceSimpleGetter, 'visible'): ['KX_GameObject']}, + 'getXY': {(replaceSimpleGetter, 'useXY'): ['KX_CameraActuator']}, + 'isConnected': {(replaceSimpleGetter, 'connected'): ['SCA_JoystickSensor']}, + 'isPositive': {(replaceSimpleGetter, 'positive'): ['SCA_ISensor']}, + 'isTriggered': {(replaceSimpleGetter, 'triggered'): ['SCA_ISensor']}, + 'set': {(replaceSimpleSetter, 'visibility'): ['KX_VisibilityActuator']}, + 'setAction': {(replaceSimpleSetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, + 'setActuator': {(replaceSimpleSetter, 'actuator'): ['SCA_ActuatorSensor']}, + 'setAxis': {(replaceSimpleSetter, 'axis'): ['SCA_JoystickSensor']}, + 'setBlendin': {(replaceSimpleSetter, 'blendIn'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'setBlendtime': {(replaceSimpleSetter, 'blendTime'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'setBodyType': {(replaceSimpleSetter, 'usePropBody'): ['KX_NetworkMessageActuator']}, + 'setButton': {(replaceSimpleSetter, 'button'): ['SCA_JoystickSensor']}, + 'setCamera': {(replaceSimpleSetter, 'camera'): ['KX_SceneActuator']}, + 'setContinue': {(replaceSimpleSetter, 'useContinue'): ['BL_ActionActuator']}, + 'setDelay': {(replaceSimpleSetter, 'delay'): ['SCA_DelaySensor']}, + 'setDuration': {(replaceSimpleSetter, 'duration'): ['SCA_DelaySensor']}, + 'setEnd': {(replaceSimpleSetter, 'frameEnd'): ['BL_ShapeActionActuator', + 'KX_IpoActuator', + 'BL_ActionActuator']}, + 'setExecutePriority': {(replaceSimpleSetter, 'executePriority'): ['SCA_ILogicBrick']}, + 'setFile': {(replaceSimpleSetter, 'fileName'): ['KX_GameActuator']}, + 'setFilename': {(replaceSimpleSetter, 'fileName'): ['KX_SoundActuator']}, + 'setForceIpoActsLocal': {(replaceSimpleSetter, 'useIpoLocal'): ['KX_IpoActuator']}, + 'setFrame': {(replaceSimpleSetter, 'frame'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, + 'setFrameProperty': {(replaceSimpleSetter, 'framePropName'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'setFrequency': {(replaceSimpleSetter, 'frequency'): ['SCA_ISensor']}, + 'setGain': {(replaceSimpleSetter, 'volume'): ['KX_SoundActuator', 'KX_CDActuator']}, + 'setHat': {(replaceSimpleSetter, 'hat'): ['SCA_JoystickSensor']}, + 'setHeight': {(replaceSimpleSetter, 'height'): ['KX_CameraActuator']}, + 'setHold1': {(replaceSimpleSetter, 'hold1'): ['SCA_KeyboardSensor']}, + 'setHold2': {(replaceSimpleSetter, 'hold2'): ['SCA_KeyboardSensor']}, + 'setIndex': {(replaceSimpleSetter, 'index'): ['SCA_JoystickSensor']}, + 'setInvert': {(replaceSimpleSetter, 'invert'): ['SCA_ISensor']}, + 'setIpoAdd': {(replaceSimpleSetter, 'useIpoAdd'): ['KX_IpoActuator']}, + 'setIpoAsForce': {(replaceSimpleSetter, 'useIpoAsForce'): ['KX_IpoActuator']}, + 'setKey': {(replaceSimpleSetter, 'key'): ['SCA_KeyboardSensor']}, + 'setLevel': {(replaceSimpleSetter, 'level'): ['SCA_ISensor']}, + 'setLooping': {(replaceSimpleSetter, 'looping'): ['KX_SoundActuator']}, + 'setMask': {(replaceSimpleSetter, 'mask'): ['KX_StateActuator']}, + 'setMax': {(replaceSimpleSetter, 'max'): ['KX_CameraActuator']}, + 'setMesh': {(replaceSimpleSetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, + 'setMin': {(replaceSimpleSetter, 'min'): ['KX_CameraActuator']}, + 'setObject': {(replaceSimpleSetter, 'object'): ['KX_SCA_AddObjectActuator', + 'KX_CameraActuator', + 'KX_TrackToActuator', + 'KX_ParentActuator']}, + 'setOperation': {(replaceSimpleSetter, 'mode'): ['KX_SCA_DynamicActuator'], + (replaceSimpleSetter, 'operation'): ['KX_StateActuator']}, + 'setOrientation': {(replaceSimpleSetter, 'localOrientation'): ['KX_GameObject'], + (replaceSimpleSetter, 'orientation'): ['KX_SoundActuator']}, + 'setPitch': {(replaceSimpleSetter, 'pitch'): ['KX_SoundActuator']}, + 'setPosition': {(replaceSimpleSetter, 'localPosition'): ['KX_GameObject'], + (replaceSimpleSetter, 'position'): ['KX_SoundActuator']}, + 'setPriority': {(replaceSimpleSetter, 'priority'): ['BL_ShapeActionActuator', + 'BL_ActionActuator']}, + 'setProjectionMatrix': {(replaceSimpleSetter, 'projection_matrix'): ['KX_Camera']}, + 'setProperty': {(replaceSimpleSetter, 'propName'): ['KX_IpoActuator', + 'SCA_PropertySensor', + 'SCA_RandomActuator']}, + 'setRepeat': {(replaceSimpleSetter, 'repeat'): ['SCA_DelaySensor']}, + 'setRollOffFactor': {(replaceSimpleSetter, 'rollOffFactor'): ['KX_SoundActuator']}, + 'setScene': {(replaceSimpleSetter, 'scene'): ['KX_SceneActuator']}, + 'setScript': {(replaceSimpleSetter, 'script'): ['SCA_PythonController']}, + 'setSeed': {(replaceSimpleSetter, 'seed'): ['SCA_RandomActuator']}, + 'setStart': {(replaceSimpleSetter, 'frameStart'): ['BL_ShapeActionActuator', + 'KX_IpoActuator', + 'BL_ActionActuator']}, + 'setState': {(replaceSimpleSetter, 'state'): ['KX_GameObject']}, + 'setSubject': {(replaceSimpleSetter, 'subject'): ['KX_NetworkMessageActuator']}, + 'setSubjectFilterText': {(replaceSimpleSetter, 'subject'): ['KX_NetworkMessageSensor']}, + 'setThreshold': {(replaceSimpleSetter, 'threshold'): ['SCA_JoystickSensor']}, + 'setTime': {(replaceSimpleSetter, 'time'): ['KX_SCA_AddObjectActuator', 'KX_TrackToActuator']}, + 'setToPropName': {(replaceSimpleSetter, 'propName'): ['KX_NetworkMessageActuator']}, + 'setType': {(replaceSimpleSetter, 'mode'): ['SCA_PropertySensor']}, + 'setUse3D': {(replaceSimpleSetter, 'use3D'): ['KX_TrackToActuator']}, + 'setUseNegPulseMode': {(replaceSimpleSetter, 'useNegPulseMode'): ['SCA_ISensor']}, + 'setUsePosPulseMode': {(replaceSimpleSetter, 'usePosPulseMode'): ['SCA_ISensor']}, + 'setUseRestart': {(replaceSimpleSetter, 'useRestart'): ['KX_SceneActuator']}, + 'setValue': {(replaceSimpleSetter, 'value'): ['SCA_PropertySensor', 'SCA_PropertyActuator']}, + 'setVelocity': {(replaceSimpleSetter, 'velocity'): ['KX_SoundActuator']}, + 'setXY': {(replaceSimpleSetter, 'useXY'): ['KX_CameraActuator']} +} + +def convert248to249(lines, log = True, logErrors = True): + # Regular expression for finding attributes. For the string 'a.b', this + # returns three groups: ['a.b', 'a.', 'b']. The last is the attribute name. + attrRegex = re.compile(r'\.\s*' # Dot + r'([a-zA-Z_]\w*)') # Identifier + + row = 0 + sourceRow = 0 + col = 0 + nconverted = 0 + nerrors = 0 + while row < len(lines): + originalLine = lines[row] + changed = False + while col < len(lines[row]): + # Don't search past comment. We have to check each iteration + # because the line contents may have changed. + commentStart = lines[row].find('#', col) + if commentStart < 0: + commentStart = len(lines[row]) + + # Search for an attribute identifier. + match = attrRegex.search(lines[row], col, commentStart) + if not match: + break + + attrName = match.group(1) + if attributeRenameDict.has_key(attrName): + # name is deprecated. + conversionDict = attributeRenameDict[attrName] + + if len(conversionDict.keys()) > 1: + # Ambiguous! Can't convert. + print "ERROR: source line %d, ambiguous conversion:" % sourceRow + if logErrors: + lines.insert(row, "##248## ERROR: ambiguous conversion.\n") + row = row + 1 + for conversion in conversionDict.keys(): + _, newAttrName = conversion + classes = conversionDict[conversion] + print "\t%s -> %s (classes %s)" % (attrName, newAttrName, classes) + if logErrors: + lines.insert(row, "##248##%s -> %s (classes %s)\n" % + (attrName, newAttrName, classes)) + row = row + 1 + nerrors = nerrors + 1 + + else: + # Conversion is well-defined. Execute. + func, newAttrName = conversionDict.keys()[0] + try: + func(lines, row, match.start(1), match.end(1), newAttrName) + except ConversionError as e: + # Insert a comment saying the conversion failed. + print "ERROR: source line %d, %s: %s\n" % ( + sourceRow, attrName, e) + if logErrors: + lines.insert(row, + "##248## ERROR: %s: %s\n" % + (attrName, e)) + row = row + 1 + nerrors = nerrors + 1 + else: + changed = True + nconverted = nconverted + 1 + # Search the rest of this line. + col = match.start(1) + if changed and log: + if originalLine[-1] != '\n': + originalLine = originalLine + '\n' + lines.insert(row, "##248##%s" % originalLine) + row = row + 1 + row = row + 1 + sourceRow = sourceRow + 1 + col = 0 + return nconverted, nerrors + +def usage(): + print "Usage: blender248to249.py [options] [outfile]" + print "Options:" + print "\t--nolog Don't include old lines as comments." + print "\t--quieterrors Don't insert errors as comments." + +def runAsConsoleScript(): + '''Called when being run as a console script.''' + try: + opts, args = getopt.getopt(sys.argv[1:], "", ["nolog", "quieterrors"]) + except getopt.GetoptError, err: + # print help information and exit: + print str(err) + usage() + sys.exit(2) + + log = True + logErrors = True + for o, a in opts: + if o == "--nolog": + log = False + elif o == "--quieterrors": + logErrors = False + + try: + inpath = args.pop(0) + except IndexError: + usage() + sys.exit(2) + try: + outpath = args.pop(0) + except IndexError: + outpath = inpath + + infile = io.FileIO(inpath, 'r') + # arbitrary file size of around 100kB + lines = infile.readlines(100000) + infile.close() + + nconverted, nerrors = convert248to249(lines, log, logErrors) + + outfile = io.FileIO(outpath, 'w') + outfile.writelines(lines) + outfile.close() + print "Conversion finished. Modified %d attributes." % nconverted + print "There were %d errors." % nerrors + print "Please review all the changes." + +def runAsTextPlugin(): + '''Called when run as a text plugin.''' + + import Blender + from Blender import Window, sys, Draw + import BPyTextPlugin, bpy + + # Gets the active text object, there can be many in one blend file. + txt = bpy.data.texts.active + + # Silently return if the script has been run with no active text + if not txt: + return + + Window.WaitCursor(1) + try: + lines = txt.asLines() + for i in range(0, len(lines)): + if not lines[i].endswith('\n'): + lines[i] = lines[i] + '\n' + + nconverted, nerrors = convert248to249(lines) + + Blender.SaveUndoState('Convert GE 249') + txt.clear() + for line in lines: + txt.write(line) + + message = "Converted %d attributes." % nconverted + if nerrors == 1: + message = message + " There was 1 error (see console)." + if nerrors > 1: + message = message + " There were %d errors (see console)." % nerrors + message = message + "|Please review all the changes." + Draw.PupMenu(message) + + finally: + Window.WaitCursor(0) + +def main(): + try: + import Blender + except ImportError: + runAsConsoleScript() + else: + runAsTextPlugin() + +# This lets you import the script without running it +if __name__ == "__main__": + import sys + import getopt + import io + main() diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index b5dc89e4002..47c27a5c3c9 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -151,16 +151,22 @@ class SCA_ISensor(SCA_ILogicBrick): def isPositive(): """ True if this sensor brick is in a positive state. + + @deprecated: use L{positive} """ def isTriggered(): """ True if this sensor brick has triggered the current controller. + + @deprecated: use L{triggered} """ def getUsePosPulseMode(): """ True if the sensor is in positive pulse mode. + + @deprecated: use L{usePosPulseMode} """ def setUsePosPulseMode(pulse): """ @@ -168,6 +174,7 @@ class SCA_ISensor(SCA_ILogicBrick): @type pulse: boolean @param pulse: If True, will activate positive pulse mode for this sensor. + @deprecated: use L{usePosPulseMode} """ def getFrequency(): """ @@ -175,6 +182,7 @@ class SCA_ISensor(SCA_ILogicBrick): @rtype: integer @return: the pulse frequency in 1/50 sec. + @deprecated: use L{frequency} """ def setFrequency(freq): """ @@ -182,10 +190,13 @@ class SCA_ISensor(SCA_ILogicBrick): @type freq: integer @return: the pulse frequency in 1/50 sec. + @deprecated: use L{frequency} """ def getUseNegPulseMode(): """ True if the sensor is in negative pulse mode. + + @deprecated: use L{useNegPulseMode} """ def setUseNegPulseMode(pulse): """ @@ -193,10 +204,13 @@ class SCA_ISensor(SCA_ILogicBrick): @type pulse: boolean @param pulse: If True, will activate negative pulse mode for this sensor. + @deprecated: use L{useNegPulseMode} """ def getInvert(): """ True if this sensor activates on negative events. + + @deprecated: use L{invert} """ def setInvert(invert): """ @@ -204,6 +218,7 @@ class SCA_ISensor(SCA_ILogicBrick): @type invert: boolean @param invert: true if activates on negative events; false if activates on positive events. + @deprecated: use L{invert} """ def getLevel(): """ @@ -215,6 +230,7 @@ class SCA_ISensor(SCA_ILogicBrick): @rtype: boolean @return: true if sensor is level sensitive, false if it is edge sensitive + @deprecated: use L{level} """ def setLevel(level): """ @@ -222,6 +238,7 @@ class SCA_ISensor(SCA_ILogicBrick): @param level: Detect level instead of edge? (KX_TRUE, KX_FALSE) @type level: boolean + @deprecated: use L{level} """ #} @@ -315,7 +332,7 @@ class BL_ActionActuator(SCA_IActuator): @ivar useContinue: The actions continue option, True or False. When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. - @type: boolean + @type useContinue: boolean @ivar framePropName: The name of the property that is set to the current frame number. @type framePropName: string """ @@ -2575,7 +2592,7 @@ class KX_NetworkMessageSensor(SCA_ISensor): @type subject: string @ivar frameMessageCount: The number of messages received since the last frame. (Read-only) - @type framemessageCount: int + @type frameMessageCount: int @ivar subjects: The list of message subjects received. (Read-only) @type subjects: list of strings @ivar bodies: The list of message bodies received. (Read-only) @@ -5614,3 +5631,67 @@ for name, val in locals().items(): for a in attrs: print a """ + + +# Util func to construct a mapping from deprecated attrs to new ones. +""" +import types +import re +import pprint +depAttrs = {} +for name, val in locals().items(): + if name.startswith('__'): + continue + if type(val) == types.ClassType: + print "\t# %s" % name + + # Inspect each attribute. + for attrName in dir(val): + if attrName.startswith('__'): + continue + attr = getattr(val, attrName) + + # Check whether this attribute is deprecated by searching each line. + newAttrName = None + for line in attr.__doc__.split('\n'): + match = re.search(r'@deprecated.*L{(\w+)}', line) + if match: + newAttrName = match.group(1) + break + if not newAttrName: + continue + + # Store the mappings to new attributes in a list (because there + # could be collisions). + if not depAttrs.has_key(attrName): + depAttrs[attrName] = {} + mapping = depAttrs[attrName] + + for line in val.__doc__.split('\n'): + if ("@type %s:" % newAttrName) in line: + # The attribute is being replaced in this class (i.e. the + # deprecated attribute wasn't inherited from a parent). We + # have a winner! + funcType = None + if 'sequence' in line: + funcType = 'Keyed' + else: + funcType = 'Simple' + + if attrName.startswith('get') or attrName.startswith('is'): + func = "replace%sGetter" % funcType + elif attrName.startswith('set') or attrName.startswith('enable'): + func = "replace%sSetter" % funcType + else: + func = 'UNKNOWN' + + # Another mapping, from a conversion tuple to lists of class + # names. + conversion = (func, newAttrName) + if not mapping.has_key(conversion): + mapping[conversion] = [] + mapping[conversion].append(name) + break + +pprint.pprint(depAttrs, width = 100) +""" From 3f584de8ecf76ad084b15eb4fb1e78e827ab1328 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 21 May 2009 07:28:02 +0000 Subject: [PATCH 285/444] [#18795] Subdivide Smooth can give wrong vcol weights given by subdivide are not normalized, if that was fixed could avoid clamping. --- source/blender/blenkernel/intern/customdata.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 6d5b86fa874..4038ccb1ea7 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -33,7 +33,7 @@ */ #include "BKE_customdata.h" - +#include "BKE_utildefines.h" // CLAMP #include "BLI_blenlib.h" #include "BLI_linklist.h" #include "BLI_mempool.h" @@ -421,6 +421,14 @@ static void layerInterp_mloopcol(void **sources, float *weights, col.b += src->b * weight; } } + + /* Subdivide smooth or fractal can cause problems without clamping + * although weights should also not cause this situation */ + CLAMP(col.a, 0.0f, 255.0f); + CLAMP(col.r, 0.0f, 255.0f); + CLAMP(col.g, 0.0f, 255.0f); + CLAMP(col.b, 0.0f, 255.0f); + mc->a = (int)col.a; mc->r = (int)col.r; mc->g = (int)col.g; @@ -496,6 +504,14 @@ static void layerInterp_mcol(void **sources, float *weights, } for(j = 0; j < 4; ++j) { + + /* Subdivide smooth or fractal can cause problems without clamping + * although weights should also not cause this situation */ + CLAMP(col[j].a, 0.0f, 255.0f); + CLAMP(col[j].r, 0.0f, 255.0f); + CLAMP(col[j].g, 0.0f, 255.0f); + CLAMP(col[j].b, 0.0f, 255.0f); + mc[j].a = (int)col[j].a; mc[j].r = (int)col[j].r; mc[j].g = (int)col[j].g; From 5fc6afe2405833b9a4963bf66829b736998eec73 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 21 May 2009 10:25:40 +0000 Subject: [PATCH 286/444] == Sequencer == This fixes: [#18007] Audio playback of a scene strip containing audio is broken. (needed a different recursion protection than video render code, since video and audio render can be called simultaneously because of SDL audio thread callbacks) Also: we don't display a wait cursor, if the scene strip has DOSEQ enabled. (no need to wait, it is the sequencer which is realtime by definition :) --- source/blender/include/BSE_seqaudio.h | 6 +- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/src/seqaudio.c | 166 +++++++++++++++++----- source/blender/src/sequence.c | 9 +- 4 files changed, 139 insertions(+), 43 deletions(-) diff --git a/source/blender/include/BSE_seqaudio.h b/source/blender/include/BSE_seqaudio.h index 64aa50c661d..1886b3e8771 100644 --- a/source/blender/include/BSE_seqaudio.h +++ b/source/blender/include/BSE_seqaudio.h @@ -43,10 +43,10 @@ void audio_mixdown(); void audio_makestream(bSound *sound); -void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown); +void audiostream_play(int startframe, uint32_t duration, int mixdown); void audiostream_fill(uint8_t* mixdown, int len); -void audiostream_start(uint32_t frame); -void audiostream_scrub(uint32_t frame); +void audiostream_start(int frame); +void audiostream_scrub(int frame); void audiostream_stop(void); int audiostream_pos(void); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 36df11ac2e8..a885cbeb2af 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -668,6 +668,7 @@ typedef struct Scene { #define R_STAMP_INFO 0x4000 #define R_FULL_SAMPLE 0x8000 #define R_COMP_RERENDER 0x10000 +#define R_RECURS_PROTECTION 0x20000 /* r->stamp */ #define R_STAMP_TIME 0x0001 diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index 0bc40674350..078750ca118 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -95,6 +95,12 @@ static int audio_playing=0; static int audio_initialised=0; static int audio_startframe=0; static double audio_starttime = 0.0; +static Scene * audio_scene = 0; /* we can't use G.scene, since + Sequence Scene strips can change G.scene + (and SDL-audio-fill callback can be + called while we have G.scene changed!) + */ + ///// // /* local protos ------------------- */ @@ -217,7 +223,7 @@ void audiostream_fill(uint8_t *mixdown, int len) #ifndef DISABLE_SDL for (i = 0; i < len; i += 64) { CFRA = (int) ( ((float)(audio_pos-64) - /( G.scene->audio.mixrate*4 )) + /( audio_scene->audio.mixrate*4 )) * FPS ); audio_fill(mixdown + i, NULL, @@ -238,7 +244,7 @@ static void audio_levels(uint8_t *buf, int len, float db, float facf, float pan) if (pan>=0) { facr = 1.0; facl = 1.0-pan; } else { facr = pan+1.0; facl = 1.0; } - fac = pow(10.0, ((-(db+G.scene->audio.main))/20.0)) / facf; + fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0)) / facf; facl /= fac; facr /= fac; @@ -294,7 +300,8 @@ void audio_makestream(bSound *sound) #ifndef DISABLE_SDL static void audio_fill_ram_sound(Sequence *seq, void * mixdown, - uint8_t * sstream, int len) + uint8_t * sstream, int len, + int cfra) { uint8_t* cvtbuf; bSound* sound; @@ -303,10 +310,10 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown, sound = seq->sound; audio_makestream(sound); if ((seq->curposstreamlen -len) && (seq->curpos>=0) && - (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA)) + (seq->startdisp <= cfra) && ((seq->enddisp) > cfra)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, CFRA); + do_seq_ipo(seq, cfra); facf = seq->facf0; } else { facf = 1.0; @@ -328,16 +335,16 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown, #ifndef DISABLE_SDL static void audio_fill_hd_sound(Sequence *seq, void * mixdown, uint8_t * sstream, - int len) + int len, int cfra) { uint8_t* cvtbuf; float facf; if ((seq->curpos >= 0) && - (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA)) + (seq->startdisp <= cfra) && ((seq->enddisp) > cfra)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, CFRA); + do_seq_ipo(seq, cfra); facf = seq->facf0; } else { facf = 1.0; @@ -346,7 +353,7 @@ static void audio_fill_hd_sound(Sequence *seq, sound_hdaudio_extract(seq->hdaudio, (short*) cvtbuf, seq->curpos / 4, - G.scene->audio.mixrate, + audio_scene->audio.mixrate, 2, len / 4); audio_levels(cvtbuf, len, seq->level, facf, seq->pan); @@ -365,19 +372,66 @@ static void audio_fill_hd_sound(Sequence *seq, #ifndef DISABLE_SDL static void audio_fill_seq(Sequence * seq, void * mixdown, - uint8_t *sstream, int len, int advance_only) + uint8_t *sstream, int len, int cfra, + int advance_only); + +static void audio_fill_scene_strip(Sequence * seq, void * mixdown, + uint8_t *sstream, int len, int cfra, + int advance_only) +{ + Editing *ed; + + /* prevent eternal loop */ + seq->scene->r.scemode |= R_RECURS_PROTECTION; + + ed = seq->scene->ed; + + if (ed) { + int sce_cfra = seq->sfra + seq->anim_startofs + + cfra - seq->startdisp; + + audio_fill_seq(ed->seqbasep->first, + mixdown, + sstream, len, sce_cfra, + advance_only); + } + + /* restore */ + seq->scene->r.scemode &= ~R_RECURS_PROTECTION; +} +#endif + +#ifndef DISABLE_SDL +static void audio_fill_seq(Sequence * seq, void * mixdown, + uint8_t *sstream, int len, int cfra, + int advance_only) { while(seq) { if (seq->type == SEQ_META && (!(seq->flag & SEQ_MUTE))) { - if (seq->startdisp <= CFRA && seq->enddisp > CFRA) { + if (seq->startdisp <= cfra && seq->enddisp > cfra) { audio_fill_seq(seq->seqbase.first, mixdown, sstream, len, - advance_only); + cfra, advance_only); } else { audio_fill_seq(seq->seqbase.first, mixdown, sstream, len, - 1); + cfra, 1); + } + } + if (seq->type == SEQ_SCENE + && (!(seq->flag & SEQ_MUTE)) + && seq->scene + && (seq->scene->r.scemode & R_DOSEQ) + && !(seq->scene->r.scemode & R_RECURS_PROTECTION)) { + if (seq->startdisp <= cfra && seq->enddisp > cfra) { + audio_fill_scene_strip( + seq, mixdown, sstream, len, + cfra, advance_only); + } else { + audio_fill_scene_strip( + seq, mixdown, sstream, len, + cfra, 1); } } if ( (seq->type == SEQ_RAM_SOUND) && @@ -387,7 +441,8 @@ static void audio_fill_seq(Sequence * seq, void * mixdown, seq->curpos += len; } else { audio_fill_ram_sound( - seq, mixdown, sstream, len); + seq, mixdown, sstream, len, + cfra); } } if ( (seq->type == SEQ_HD_SOUND) && @@ -405,7 +460,8 @@ static void audio_fill_seq(Sequence * seq, void * mixdown, } if (seq->hdaudio) { audio_fill_hd_sound(seq, mixdown, - sstream, len); + sstream, len, + cfra); } } } @@ -420,10 +476,15 @@ static void audio_fill(void *mixdown, uint8_t *sstream, int len) Editing *ed; Sequence *seq; - ed = G.scene->ed; - if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) { + if (!audio_scene) { + return; + } + + ed = audio_scene->ed; + if((ed) && (!(audio_scene->audio.flag & AUDIO_MUTE))) { seq = ed->seqbasep->first; - audio_fill_seq(seq, mixdown, sstream, len, 0); + audio_fill_seq(seq, mixdown, sstream, len, + audio_scene->r.cfra, 0); } audio_pos += len; @@ -463,7 +524,7 @@ static int audio_init(SDL_AudioSpec *desired) } #endif -static int audiostream_play_seq(Sequence * seq, uint32_t startframe) +static int audiostream_play_seq(Sequence * seq, int startframe) { char name[FILE_MAXDIR+FILE_MAXFILE]; int have_sound = 0; @@ -475,14 +536,38 @@ static int audiostream_play_seq(Sequence * seq, uint32_t startframe) have_sound = 1; } } + if (seq->type == SEQ_SCENE + && seq->scene + && (seq->scene->r.scemode & R_DOSEQ) + && !(seq->scene->r.scemode & R_RECURS_PROTECTION)) { + Editing *ed; + + /* prevent eternal loop */ + seq->scene->r.scemode |= R_RECURS_PROTECTION; + + ed = seq->scene->ed; + + if (ed) { + int sce_cfra = seq->sfra + seq->anim_startofs + + startframe - seq->startdisp; + + if (audiostream_play_seq(ed->seqbasep->first, + sce_cfra)) { + have_sound = 1; + } + } + + /* restore */ + seq->scene->r.scemode &= ~R_RECURS_PROTECTION; + } if ((seq->type == SEQ_RAM_SOUND) && (seq->sound)) { have_sound = 1; - seq->curpos = (int)( (FRA2TIME( - (double) startframe - - (double) seq->start + - (double) - seq->anim_startofs) - * ((float)G.scene->audio.mixrate) + seq->curpos = (int)( (FRA2TIME(((double) startframe) - + ((double) seq->start) + + ((double) + seq->anim_startofs)) + * ((float)audio_scene + ->audio.mixrate) * 4 )); } if ((seq->type == SEQ_HD_SOUND)) { @@ -494,11 +579,13 @@ static int audiostream_play_seq(Sequence * seq, uint32_t startframe) seq->hdaudio = sound_open_hdaudio(name); } - seq->curpos = (int)( (FRA2TIME((double) startframe - - (double) seq->start + - (double) - seq->anim_startofs) - * ((float)G.scene->audio.mixrate) + + seq->curpos = (int)( (FRA2TIME(((double) startframe) - + ((double) seq->start) + + ((double) + seq->anim_startofs)) + * ((float)audio_scene + ->audio.mixrate) * 4 )); } seq= seq->next; @@ -506,14 +593,16 @@ static int audiostream_play_seq(Sequence * seq, uint32_t startframe) return have_sound; } -void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown) +void audiostream_play(int startframe, uint32_t duration, int mixdown) { #ifndef DISABLE_SDL static SDL_AudioSpec desired; Editing *ed; int have_sound = 0; - ed= G.scene->ed; + audio_scene = G.scene; + + ed= audio_scene->ed; if(ed) { have_sound = audiostream_play_seq(ed->seqbasep->first, startframe); @@ -525,7 +614,7 @@ void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown) } if (U.mixbufsize && !audio_initialised && !mixdown) { - desired.freq=G.scene->audio.mixrate; + desired.freq=audio_scene->audio.mixrate; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=U.mixbufsize; @@ -538,7 +627,7 @@ void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown) audio_startframe = startframe; audio_pos = ( ((int)( FRA2TIME(startframe) - *(G.scene->audio.mixrate)*4 )) & (~3) ); + *(audio_scene->audio.mixrate)*4 )) & (~3) ); audio_starttime = PIL_check_seconds_timer(); /* if audio already is playing, just reseek, otherwise @@ -553,12 +642,12 @@ void audiostream_play(uint32_t startframe, uint32_t duration, int mixdown) #endif } -void audiostream_start(uint32_t frame) +void audiostream_start(int frame) { audiostream_play(frame, 0, 0); } -void audiostream_scrub(uint32_t frame) +void audiostream_scrub(int frame) { if (U.mixbufsize) audiostream_play(frame, 4096/U.mixbufsize, 0); } @@ -568,6 +657,7 @@ void audiostream_stop(void) #ifndef DISABLE_SDL SDL_PauseAudio(1); audio_playing=0; + audio_scene=0; #endif } @@ -575,9 +665,9 @@ int audiostream_pos(void) { int pos; - if (U.mixbufsize) { + if (U.mixbufsize && audio_scene) { pos = (int) (((double)(audio_pos-U.mixbufsize) - / ( G.scene->audio.mixrate*4 )) + / ( audio_scene->audio.mixrate*4 )) * FPS ); } else { /* fallback to seconds_timer when no audio available */ pos = (int) ((PIL_check_seconds_timer() - audio_starttime) diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index cd42c3d4085..edc68d016a1 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1884,7 +1884,10 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, if (!sce_valid) { se->ok = STRIPELEM_FAILED; } else if (se->ibuf==NULL && sce_valid) { - waitcursor(1); + /* no need to display a waitcursor on sequencer + scene strips */ + if (!(sce->r.scemode & R_DOSEQ)) + waitcursor(1); /* Hack! This function can be called from do_render_seq(), in that case the seq->scene can already have a Render initialized with same name, @@ -1935,7 +1938,9 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, /* restore */ G.scene->r.scemode |= doseq; - if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */ + if((G.f & G_PLAYANIM)==0 /* bad, is set on do_render_seq */ + && !(sce->r.scemode & R_DOSEQ)) + waitcursor(0); CFRA = oldcfra; set_last_seq(oldseq); From 06a7155b681cdb02c6b75b9934f9235efcc6c297 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 21 May 2009 13:32:15 +0000 Subject: [PATCH 287/444] BGE: user control to compound shape and setParent. Compound shape control ====================== 1) GUI control It is now possible to control which child shape is added to a parent compound shape in the Physics buttons. The "Compound" shape button becomes "Add to parent" on child objects and determines whether the child shape is to be added to the top parent compound shape when the game is stated. Notes: * "Compound" is only available to top parent objects (objects without parent). * Nesting of compound shape is not possible: a child object with "Add to parent" button set will be added to the top parent compound shape, regardless of its position in the parent-child hierarchy and even if its immediate parent doesn't have the "Add to parent" button set. 2) runtime control It is now possible to control the compound shape at runtime: The SetParent actuator has a new "Compound" button that indicates whether the object shape should be added to the compound shape of the parent object, provided the parent has a compound shape of course. If not, the object retain it's individual state while parented. Similarly, the KX_GameObject.setParent() python function has a new compound parameter. Notes: * When an object is dynamically added to a compound shape, it looses temporarily all its physics capability to the benefit of the parent: it cannot register collisions and the characteristics of its shape are lost (ghost, sensor, dynamic, etc.). * Nested compound shape is not supported: if the object being parented is already a compound shape, it is not added to the compound parent (as if the Compound option was not set in the actuator or the setParent function). * To ensure compatibility with old blend files, the Blender subversion is changed to 2.48.5 and the old blend files are automatically converted to match the old behavior: all children of a Compound object will have the "Add to parent" button set automatically. Child ghost control =================== It is now possible to control if an object should becomes ghost or solid when parented. This is only applicable if the object is not added to the parent compound shape (see above). A new "Ghost" button is available on the SetParent actuator to that effect. Similarly the KX_GameObject.setParent() python function has a new compound parameter. Notes: * This option is not applicable to sensor objects: they stay ghost all the time. * Make sure the child object does not enter in collision with the parent shape when the Ghost option if off and the parent is dynamic: the collision creates a reaction force but the parent cannot escape the child, so the force builds up and produces eratic movements. * The collision capability of an ordinary object (dynamic or static) is limited when it is parented: it becomes automatically static and can only detect dynamic and sensor objects. * A sensor object retain its full collision capability when parented: it can detect static and dynamic object. Python control ============== KX_GameObject.setParent(parent,compound,ghost): Sets this object's parent. Control the shape status with the optional compound and ghost parameters: compound=1: the object shape should be added to the parent compound shape (default) compound=0: the object should keep its individual shape. In that case you can control if it should be ghost or not: ghost=1 if the object should be made ghost while parented (default) ghost=0 if the object should be solid while parented Note: if the object type is sensor, it stays ghost regardless of ghost parameter parent: KX_GameObject reference or string (object name w/o OB prefix) --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 16 +++++++ source/blender/makesdna/DNA_actuator_types.h | 8 +++- source/blender/src/buttons_logic.c | 26 ++++++++--- .../Converter/BL_BlenderDataConversion.cpp | 7 +-- .../Converter/KX_ConvertActuators.cpp | 6 +++ .../Ketsji/KX_ConvertPhysicsObjects.cpp | 44 +++++++------------ source/gameengine/Ketsji/KX_GameObject.cpp | 21 +++++---- source/gameengine/Ketsji/KX_GameObject.h | 4 +- .../gameengine/Ketsji/KX_ParentActuator.cpp | 8 +++- source/gameengine/Ketsji/KX_ParentActuator.h | 5 +++ source/gameengine/PyDoc/GameTypes.py | 22 +++++++++- 12 files changed, 118 insertions(+), 51 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index d49a5425b61..aa2366661f8 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,7 +41,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 248 -#define BLENDER_SUBVERSION 4 +#define BLENDER_SUBVERSION 5 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0f233410f4e..25c8a928a3b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8106,6 +8106,22 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) { + Object *ob; + for(ob = main->object.first; ob; ob= ob->id.next) { + if(ob->parent) { + /* check if top parent has compound shape set and if yes, set this object + to compound shaper as well (was the behaviour before, now it's optional) */ + Object *parent= newlibadr(fd, lib, ob->parent); + while (parent->parent != NULL) { + parent = newlibadr(fd, lib, parent->parent); + } + if (parent->gameflag & OB_CHILD) + ob->gameflag |= OB_CHILD; + } + } + } + if (main->versionfile < 249) { Scene *sce; for (sce= main->scene.first; sce; sce= sce->id.next) diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 81c02779cba..f713b4a8acc 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -215,7 +215,8 @@ typedef struct bTwoDFilterActuator{ }bTwoDFilterActuator; typedef struct bParentActuator { - char pad[4]; + char pad[2]; + short flag; int type; struct Object *ob; } bParentActuator; @@ -483,6 +484,11 @@ typedef struct FreeCamera { /* parentactuator->type */ #define ACT_PARENT_SET 0 #define ACT_PARENT_REMOVE 1 + +/* parentactuator->flag */ +#define ACT_PARENT_COMPOUND 1 +#define ACT_PARENT_GHOST 2 + #endif diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 2f8933b593b..b7039673dfc 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -2747,11 +2747,22 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh if(parAct->type==ACT_PARENT_SET) { - ysize= 48; + ysize= 68; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(parAct->ob), "Set this object as parent"); + uiBlockBeginAlign(block); + uiDefButBitI(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, + "Compound", + xco + 40, yco - 64, (width - 80)/2, 19, &parAct->flag, + 0.0, 0.0, 0, 0, + "Add this object shape to the parent shape (only if the parent shape is already compound)"); + uiDefButBitI(block, TOGN, ACT_PARENT_GHOST, B_REDR, + "Ghost", + xco + 40 + ((width - 80)/2), yco - 64, (width - 80)/2, 19, &parAct->flag, + 0.0, 0.0, 0, 0, + "Make this object ghost while parented (only if not compound)"); + uiBlockEndAlign(block); } else if(parAct->type==ACT_PARENT_REMOVE) { @@ -3480,9 +3491,14 @@ static void buttons_bullet(uiBlock *block, Object *ob) } if (ob->body_type!=OB_BODY_TYPE_SOFT) { - uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 240,105,110,19, - &ob->gameflag, 0, 0, 0, 0, - "Add Children"); + if (ob->parent) + uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Add to parent", 240,105,110,19, + &ob->gameflag, 0, 0, 0, 0, + "Add this shape to the parent compound shape"); + else + uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 240,105,110,19, + &ob->gameflag, 0, 0, 0, 0, + "Create a compound shape with the children's shape that are tagged for addition"); } } uiBlockEndAlign(block); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index bf965f677c6..82edd4f218b 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1377,10 +1377,11 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, } bool isCompoundChild = false; + bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD); - if (parent && (parent->gameflag & OB_DYNAMIC)) { + if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) { - if ((parent->gameflag & OB_CHILD) != 0) + if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD)) { isCompoundChild = true; } @@ -1406,7 +1407,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0; objprop.m_isCompoundChild = isCompoundChild; - objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0; + objprop.m_hasCompoundChildren = hasCompoundChildren; objprop.m_margin = blenderobject->margin; // ACTOR is now a separate feature objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0; diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 98df34aa4a9..2b832996c45 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -1123,6 +1123,8 @@ void BL_ConvertActuators(char* maggiename, { bParentActuator *parAct = (bParentActuator *) bact->data; int mode = KX_ParentActuator::KX_PARENT_NODEF; + bool addToCompound = true; + bool ghost = true; KX_GameObject *tmpgob = NULL; switch(parAct->type) @@ -1130,6 +1132,8 @@ void BL_ConvertActuators(char* maggiename, case ACT_PARENT_SET: mode = KX_ParentActuator::KX_PARENT_SET; tmpgob = converter->FindGameObject(parAct->ob); + addToCompound = !(parAct->flag & ACT_PARENT_COMPOUND); + ghost = !(parAct->flag & ACT_PARENT_GHOST); break; case ACT_PARENT_REMOVE: mode = KX_ParentActuator::KX_PARENT_REMOVE; @@ -1140,6 +1144,8 @@ void BL_ConvertActuators(char* maggiename, KX_ParentActuator *tmpparact = new KX_ParentActuator(gameobj, mode, + addToCompound, + ghost, tmpgob); baseact = tmpparact; break; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index d81b6d5a653..406339586cc 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -949,39 +949,27 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, assert(colShape->isCompound()); btCompoundShape* compoundShape = (btCompoundShape*)colShape; - // compute the local transform from parent, this may include a parent inverse node + // compute the local transform from parent, this may include several node in the chain SG_Node* gameNode = gameobj->GetSGNode(); - SG_Node* parentInverseNode = gameNode->GetSGParent(); - if (parentInverseNode && parentInverseNode->GetSGClientObject() != NULL) - // this is not a parent inverse node, cancel it - parentInverseNode = NULL; - // now combine the parent inverse node and the game node - MT_Point3 childPos = gameNode->GetLocalPosition(); - MT_Matrix3x3 childRot = gameNode->GetLocalOrientation(); - MT_Vector3 childScale = gameNode->GetLocalScale(); - if (parentInverseNode) - { - const MT_Point3& parentInversePos = parentInverseNode->GetLocalPosition(); - const MT_Matrix3x3& parentInverseRot = parentInverseNode->GetLocalOrientation(); - const MT_Vector3& parentInverseScale = parentInverseNode->GetLocalScale(); - childRot = parentInverseRot * childRot; - childScale = parentInverseScale * childScale; - childPos = parentInversePos+parentInverseScale*(parentInverseRot*childPos); - } + SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode(); + // relative transform + MT_Vector3 parentScale = parentNode->GetWorldScaling(); + parentScale[0] = MT_Scalar(1.0)/parentScale[0]; + parentScale[1] = MT_Scalar(1.0)/parentScale[1]; + parentScale[2] = MT_Scalar(1.0)/parentScale[2]; + MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale; + MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed(); + MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale); + MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation(); - shapeInfo->m_childScale.setValue(childScale.x(),childScale.y(),childScale.z()); + shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]); bm->setLocalScaling(shapeInfo->m_childScale); - - shapeInfo->m_childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z())); - float rotval[12]; - childRot.getValue(rotval); - btMatrix3x3 newRot; - newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]); - newRot = newRot.transpose(); + shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]); + float rot[12]; + relativeRot.getValue(rot); + shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot); - shapeInfo->m_childTrans.setBasis(newRot); parentShapeInfo->AddShape(shapeInfo); - compoundShape->addChildShape(shapeInfo->m_childTrans,bm); //do some recalc? //recalc inertia for rigidbody diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 63d508e6250..0c191257f41 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -224,7 +224,7 @@ KX_GameObject* KX_GameObject::GetParent() } -void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj) +void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj, bool addToCompound, bool ghost) { // check on valid node in case a python controller holds a reference to a deleted object if (obj && GetSGNode() && obj->GetSGNode() && GetSGNode()->GetSGParent() != obj->GetSGNode()) @@ -245,7 +245,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj) if (m_pPhysicsController1) { - m_pPhysicsController1->SuspendDynamics(true); + m_pPhysicsController1->SuspendDynamics(ghost); } // Set us to our new scale, position, and orientation scale2[0] = 1.0/scale2[0]; @@ -266,7 +266,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj) Release(); // if the new parent is a compound object, add this object shape to the compound shape. // step 0: verify this object has physical controller - if (m_pPhysicsController1) + if (m_pPhysicsController1 && addToCompound) { // step 1: find the top parent (not necessarily obj) KX_GameObject* rootobj = (KX_GameObject*)obj->GetSGNode()->GetRootSGParent()->GetSGClientObject(); @@ -1160,7 +1160,7 @@ PyMethodDef KX_GameObject::Methods[] = { {"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_NOARGS}, {"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS}, {"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O}, - {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O}, + {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_VARARGS}, {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS}, {"setOcclusion",(PyCFunction) KX_GameObject::sPySetOcclusion, METH_VARARGS}, {"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS}, @@ -2147,15 +2147,20 @@ PyObject* KX_GameObject::PyGetParent() Py_RETURN_NONE; } -PyObject* KX_GameObject::PySetParent(PyObject* value) +PyObject* KX_GameObject::PySetParent(PyObject* args) { KX_Scene *scene = KX_GetActiveScene(); + PyObject* pyobj; KX_GameObject *obj; + int addToCompound=1, ghost=1; - if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject")) + if (!PyArg_ParseTuple(args,"O|ii:setParent", &pyobj, &addToCompound, &ghost)) { + return NULL; // Python sets a simple error + } + if (!ConvertPythonToGameObject(pyobj, &obj, true, "gameOb.setParent(obj): KX_GameObject")) return NULL; - - this->SetParent(scene, obj); + if (obj) + this->SetParent(scene, obj, addToCompound, ghost); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 0011b8407fd..c89b8f30779 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -171,7 +171,7 @@ public: /** * Sets the parent of this object to a game object */ - void SetParent(KX_Scene *scene, KX_GameObject *obj); + void SetParent(KX_Scene *scene, KX_GameObject *obj, bool addToCompound=true, bool ghost=true); /** * Removes the parent of this object to a game object @@ -858,7 +858,7 @@ public: KX_PYMETHOD_VARARGS(KX_GameObject,ApplyImpulse); KX_PYMETHOD_O(KX_GameObject,SetCollisionMargin); KX_PYMETHOD_NOARGS(KX_GameObject,GetParent); - KX_PYMETHOD_O(KX_GameObject,SetParent); + KX_PYMETHOD_VARARGS(KX_GameObject,SetParent); KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent); KX_PYMETHOD_NOARGS(KX_GameObject,GetChildren); KX_PYMETHOD_NOARGS(KX_GameObject,GetChildrenRecursive); diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 38ad9aec33b..cd2ed456c48 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -48,10 +48,14 @@ KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, int mode, + bool addToCompound, + bool ghost, SCA_IObject *ob, PyTypeObject* T) : SCA_IActuator(gameobj, T), m_mode(mode), + m_addToCompound(addToCompound), + m_ghost(ghost), m_ob(ob) { if (m_ob) @@ -121,7 +125,7 @@ bool KX_ParentActuator::Update() switch (m_mode) { case KX_PARENT_SET: if (m_ob) - obj->SetParent(scene, (KX_GameObject*)m_ob); + obj->SetParent(scene, (KX_GameObject*)m_ob, m_addToCompound, m_ghost); break; case KX_PARENT_REMOVE: obj->RemoveParent(scene); @@ -179,6 +183,8 @@ PyMethodDef KX_ParentActuator::Methods[] = { PyAttributeDef KX_ParentActuator::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object), KX_PYATTRIBUTE_INT_RW("mode", KX_PARENT_NODEF+1, KX_PARENT_MAX-1, true, KX_ParentActuator, m_mode), + KX_PYATTRIBUTE_BOOL_RW("compound", KX_ParentActuator, m_addToCompound), + KX_PYATTRIBUTE_BOOL_RW("ghost", KX_ParentActuator, m_ghost), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index 6af0888e2ba..148375e994c 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -46,6 +46,9 @@ class KX_ParentActuator : public SCA_IActuator /** Mode */ int m_mode; + /** option */ + bool m_addToCompound; + bool m_ghost; /** Object to set as parent */ SCA_IObject *m_ob; @@ -63,6 +66,8 @@ class KX_ParentActuator : public SCA_IActuator KX_ParentActuator(class SCA_IObject* gameobj, int mode, + bool addToCompound, + bool ghost, SCA_IObject *ob, PyTypeObject* T=&Type); virtual ~KX_ParentActuator(); diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 47c27a5c3c9..3f9b627247f 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -1896,12 +1896,23 @@ class KX_GameObject(SCA_IObject): @rtype: L{KX_GameObject} @return: this object's parent object, or None if this object has no parent. """ - def setParent(parent): + def setParent(parent,compound,ghost): """ - Sets this object's parent. + Sets this object's parent. + Control the shape status with the optional compound and ghost parameters: + compound=1: the object shape should be added to the parent compound shape (default) + compound=0: the object should keep its individual shape. + In that case you can control if it should be ghost or not: + ghost=1 if the object should be made ghost while parented (default) + ghost=0 if the object should be solid while parented + Note: if the object type is sensor, it stays ghost regardless of ghost parameter @type parent: L{KX_GameObject} @param parent: new parent object. + @type compound: int + @param compound: whether the shape should be added to the parent compound shape + @type ghost: int + @param ghost: whether the object should be ghost while parented """ def removeParent(): """ @@ -2937,6 +2948,13 @@ class KX_ParentActuator(SCA_IActuator): @type object: KX_GameObject or None @ivar mode: The mode of this actuator @type mode: int from 0 to 1 L{GameLogic.Parent Actuator} + @ivar compound: Whether the object shape should be added to the parent compound shape when parenting + Effective only if the parent is already a compound shape + @type compound: bool + @ivar ghost: whether the object should be made ghost when parenting + Effective only if the shape is not added to the parent compound shape + @type ghost: bool + """ def setObject(object): """ From 1388beebdbb93939434982d0059873aa055f455c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 21 May 2009 14:11:12 +0000 Subject: [PATCH 288/444] build without SDL in GCC 4.4 --- intern/SoundSystem/sdl/SND_SDLCDDevice.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp b/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp index b1bac964c61..5054c39e8a1 100644 --- a/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp +++ b/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp @@ -43,6 +43,8 @@ #ifndef DISABLE_SDL #include +#else +#include #endif SND_SDLCDDevice::SND_SDLCDDevice() : From d54126f78edbb48073fe979395de92dca255fd7e Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Thu, 21 May 2009 17:54:45 +0000 Subject: [PATCH 289/444] rvk1_torvk2.py patch committed by jean-michel soler (jms) [#18765] Update of the rvk1_torvk2.py bundled script: The script has been modified to use the last management of the modifiers in the python api and corrected too. Now it can copy the mesh object when it is alone and also a shape keys to the second one if needed. --- release/scripts/rvk1_torvk2.py | 396 +++++++++++++++++++-------------- 1 file changed, 232 insertions(+), 164 deletions(-) diff --git a/release/scripts/rvk1_torvk2.py b/release/scripts/rvk1_torvk2.py index a48d065813a..d013343c05c 100644 --- a/release/scripts/rvk1_torvk2.py +++ b/release/scripts/rvk1_torvk2.py @@ -2,7 +2,7 @@ # coding: utf-8 """ Registration info for Blender menus: <- these words are ignored Name: 'Deformed mesh to Rvk' -Blender: 243 +Blender: 248 Group: 'Mesh' Tip: 'Copy deform data (not surf. subdiv) of active obj to rvk of the 2nd selected obj' """ @@ -11,21 +11,24 @@ __author__ = "Jean-Michel Soler (jms)" __url__ = ("blender", "blenderartists.org", "Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_rvk1versrvk2.htm", "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "2007/04/27" +__version__ = "2009/05/18" __bpydoc__ = """\ -"DEFORM to RVK2" copies deform data (except EDGESPLIT,DECIMATE,SUBSURF,BOOLEAN, -BUILD,MIRROR,ARRAY) of the active object to the RVK (relative vertex key) of -the other selected object. +"DEFORM to RVK2" copies deformed data (except all data with not exactly +the same number of vertices like EDGESPLIT,DECIMATE,SUBSURF, BOOLEAN, +BUILD, MIRROR, ARRAY) of the active object to the RVK (relative vertex +key, now called Shapes key) of the other selected object. It is presupposed that the second mesh object is built exactly like the first one. In fact, it is better to use a true copy with at least one basic shape -key. +key. If there is no other object selected, the script can create a copy. The new version of this scrit (Blender 2.43) manages the modifier changes. There are a lot of modifiers but only the ones which just deforms the shape -can be used : LATTICE, CURVE, WAVE, ARMATURE. You can unset these modifiers -from the script. +can be used : LATTICE, CURVE, WAVE, ARMATURE, CAST, DISPLACE, SMOOTH. +SIMPLEDEFORM and SHRINKWRAP are not correctly seen before Blender 2.49, but +they can be copied too. You can unset one or more of these modifiers from +the script. Usage: @@ -37,9 +40,9 @@ the rvk it will also ask whether it should replace or add a new vertex group. """ - #---------------------------------------------- -# jm soler (c) 2004-2007 : 'Deformed mesh to Rvk' released under GPL licence +# jm soler (c) 2004-2009 : 'Deformed mesh to Rvk' +# released under GPL licence #---------------------------------------------- """ Ce programme est libre, vous pouvez le redistribuer et/ou @@ -72,11 +75,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ -# Copy the rvk (1, or armature, lattice, or -# any mesh deformation except surface -# sbdivision) of the active object to rvk (2) of -# the second selected object. Create rvk or modify -# absolute key if needed. #---------------------------------------------- # official Page : # http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_rvk1versrvk2.htm @@ -90,7 +88,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Communiquer les problemes et erreurs sur: # http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender #--------------------------------------------- -#--------------------------------------------- import Blender from Blender import NMesh,Draw,Object,Modifier @@ -99,175 +96,246 @@ DEBUG=0 def Value(t): exec "t=Modifier.Types.%s"%t - return t + return t -def deform2rvk(): +def copy_shapes(RVK1,RVK2): POSSMOD_list=['EDGESPLIT', - 'DECIMATE', - 'SUBSURF', - 'BOOLEAN', - 'BUILD', - 'MIRROR', - 'ARRAY'] + 'DECIMATE', + 'SUBSURF', + 'BOOLEAN', + 'BUILD', + 'MIRROR', + 'ARRAY', + 'BEVEL', + 'EXPLODE'] AUTHMOD_list=['LATTICE', - 'CURVE', - 'WAVE', - 'ARMATURE'] - - MODIFIERS=0 + 'CURVE', + 'WAVE', + 'ARMATURE', + 'SMOOTH', + 'SIMPLEDEFORM', + 'SHRINKWRAP', + 'CAST', + 'DISPLACE', + 'MESHDEFORM'] + BMOD=[['Possible Modifiers'], - ['Allowed Modifiers']] - - # ================================================================= - # at leat 2 objects =============================================== - # ================================================================= - if len(Object.GetSelected())>1 : - RVK1=Object.GetSelected()[0] - RVK2=Object.GetSelected()[1] - # ============================================================= - # must be 2 meshes ============================================ - # ============================================================= - if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh': - FRAME=Blender.Get('curframe') + ['Allowed Modifiers']] + # ============================================================= + # must be 2 meshes ============================================ + # ============================================================= + if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh': + #MODIFIERS=0 + FRAME=Blender.Get('curframe') + DATA2=RVK2.getData() + if DEBUG: print DATA2.getKey() + # ============================================================ + # at least the second must have a shape key ================== + # ============================================================ + def select_modifier(RVK1, RVK2, DATA2): + # ====================================================== + # in case of modifiers, use ============================= + # ====================================================== + if RVK1.modifiers: + #MODIFIERS=1 + POSSMOD=[Value(t) for t in POSSMOD_list] + AUTHMOD=[Value(t) for t in AUTHMOD_list] + if DEBUG: print 'POSSMOD:',POSSMOD,'\nAUTHMOD:', AUTHMOD + MODRVK1=RVK1.modifiers + block = [] + # =================================================== + # === Bloc Menu Modifiers ===1 doc ================= + # =================================================== + m=0 + for mod in MODRVK1: + if DEBUG: print mod.type + if mod.type in POSSMOD: + BMOD[0].append([Draw.Create(0),mod.type, + m, + POSSMOD_list[POSSMOD.index(mod.type)], + mod[Modifier.Settings.RENDER]==1, + mod[Modifier.Settings.EDITMODE]==1 + ]) + elif mod.type in AUTHMOD: + BMOD[1].append([Draw.Create(1), + mod.type, + m, + AUTHMOD_list[AUTHMOD.index(mod.type)], + mod[Modifier.Settings.RENDER]==1, + mod[Modifier.Settings.EDITMODE]==1 + ]) + m+=1 + # =================================================== + # === Bloc Menu Modifiers ===2 display ============= + # =================================================== + block.append(BMOD[1][0]) + for B in BMOD[1][1:]: + block.append((B[3],B[0],"")) + block.append(BMOD[0][0]) + block.append("not alredy implemented") + block.append("in this script.") + for B in BMOD[0][1:]: + block.append((B[3],B[0],"")) + retval = Blender.Draw.PupBlock("MESH 2 RVK", block) + # =================================================== + # === unset Modifiers ============================= + # =================================================== + for B in BMOD[0][1:]: + if DEBUG: print B[2] + MODRVK1[B[2]][Modifier.Settings.RENDER]=0 + for B in BMOD[1]: + if not B[1]: + MODRVK1[B[2]][Modifier.Settings.RENDER]=0 + # =================================================== + # === update Modifiers ============================= + # =================================================== + #RVK1.makeDisplayList() + # ======================================================= + # === get deformed mesh ================================ + # ======================================================= + RVK1NAME=Object.GetSelected()[0].getName() + meshrvk1=NMesh.GetRawFromObject(RVK1NAME) + if DEBUG: print len(meshrvk1.verts) + # ======================================================= + # === get normal mesh for vertex group ================= + # ======================================================= + DATA1=RVK1.getData() + # ======================================================= + # === get destination mesh ============================ + # ======================================================= DATA2=RVK2.getData() - if DEBUG: print DATA2.getKey() - # ============================================================ - # at least the second must have a shape key ================== - # ============================================================ - if DATA2.getKey(): - # ====================================================== - # in case of modifiers use ============================= - # ====================================================== + if DEBUG: print len(meshrvk1.verts) + if DEBUG: print len(DATA2.verts) + # ======================================================== + # ===== is there the same number of vertices ============= + # ======================================================== + if len(meshrvk1.verts)==len(DATA2.verts): + name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 " + result = Draw.PupMenu(name) + if result==1: + # ===================================================== + # ===== Do we save vertex groups ? =================== + # ===================================================== + GROUPNAME2=DATA2.getVertGroupNames() + if len(GROUPNAME2)!=0: + for GROUP2 in GROUPNAME2: + DATA2.removeVertGroup(GROUP2) + GROUPNAME1=DATA1.getVertGroupNames() + if len(GROUPNAME1)!=0: + for GROUP1 in GROUPNAME1: + DATA2.addVertGroup(GROUP1) + DATA2.assignVertsToGroup(GROUP1,DATA1.getVertsFromGroup(GROUP1),1.0,'replace') + # ======================================================== + # ===== now copy the vertices coords ===================== + # ======================================================== + for v in meshrvk1.verts: + i= meshrvk1.verts.index(v) + v1=DATA2.verts[i] + for n in [0,1,2]: + v1.co[n]=v.co[n] + DATA2.update() + DATA2.insertKey(FRAME,'relative') + DATA2.update() + RVK2.makeDisplayList() + if RVK1.modifiers: - MODIFIERS=1 - POSSMOD=[Value(t) for t in POSSMOD_list] - AUTHMOD=[Value(t) for t in AUTHMOD_list] - if DEBUG: print 'POSSMOD:',POSSMOD,'\nAUTHMOD:', AUTHMOD - MODRVK1=RVK1.modifiers - block = [] - # =================================================== - # === Bloc Menu Modifiers ===1 doc ================= - # =================================================== - m=0 - for mod in MODRVK1: - if DEBUG: print mod.type - if mod.type in POSSMOD: - BMOD[0].append([Draw.Create(0),mod.type, - m, - POSSMOD_list[POSSMOD.index(mod.type)], - mod[Modifier.Settings.RENDER]==1, - mod[Modifier.Settings.EDITMODE]==1 - ]) - elif mod.type in AUTHMOD: - BMOD[1].append([Draw.Create(1), - mod.type, - m, - AUTHMOD_list[AUTHMOD.index(mod.type)], - mod[Modifier.Settings.RENDER]==1, - mod[Modifier.Settings.EDITMODE]==1 - ]) - m+=1 - # =================================================== - # === Bloc Menu Modifiers ===2 display ============= - # =================================================== - block.append(BMOD[1][0]) - for B in BMOD[1][1:]: - block.append((B[3],B[0],"")) - block.append(BMOD[0][0]) - block.append("not alredy implemented") - block.append("in this script.") - for B in BMOD[0][1:]: - block.append((B[3],B[0],"")) - retval = Blender.Draw.PupBlock("MESH 2 RVK", block) # =================================================== # === unset Modifiers ============================= # =================================================== for B in BMOD[0][1:]: - if DEBUG: print B[2] - MODRVK1[B[2]][Modifier.Settings.RENDER]=0 + MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2] for B in BMOD[1]: if not B[1]: - MODRVK1[B[2]][Modifier.Settings.RENDER]=0 - # =================================================== - # === update Modifiers ============================= - # =================================================== - #RVK1.makeDisplayList() - # ======================================================= - # === get deformed mesh ================================ - # ======================================================= - RVK1NAME=Object.GetSelected()[0].getName() - meshrvk1=NMesh.GetRawFromObject(RVK1NAME) - if DEBUG: print len(meshrvk1.verts) - # ======================================================= - # === get normal mesh for vertex group ================= - # ======================================================= - DATA1=RVK1.getData() - # ======================================================= - # === get destination mesh ============================ - # ======================================================= - DATA2=RVK2.getData() - if DEBUG: print len(meshrvk1.verts) - if DEBUG: print len(DATA2.verts) - # ======================================================== - # ===== is there the same number of vertices ============= - # ======================================================== - if len(meshrvk1.verts)==len(DATA2.verts): - name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 " - result = Draw.PupMenu(name) - if result==1: - # ===================================================== - # ===== Do we save vertex groups ? =================== - # ===================================================== - GROUPNAME2=DATA2.getVertGroupNames() - if len(GROUPNAME2)!=0: - for GROUP2 in GROUPNAME2: - DATA2.removeVertGroup(GROUP2) - GROUPNAME1=DATA1.getVertGroupNames() - if len(GROUPNAME1)!=0: - for GROUP1 in GROUPNAME1: - DATA2.addVertGroup(GROUP1) - DATA2.assignVertsToGroup(GROUP1,DATA1.getVertsFromGroup(GROUP1),1.0,'replace') - # ======================================================== - # ===== now copy the vertices coords ===================== - # ======================================================== - for v in meshrvk1.verts: - i= meshrvk1.verts.index(v) - v1=DATA2.verts[i] - for n in [0,1,2]: - v1.co[n]=v.co[n] - DATA2.update() - DATA2.insertKey(FRAME,'relative') - DATA2.update() - RVK2.makeDisplayList() - if MODIFIERS: - # =================================================== - # === unset Modifiers ============================= - # =================================================== - for B in BMOD[0][1:]: MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2] - for B in BMOD[1]: - if not B[1]: - MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2] - else: - name = "Meshes Objects must the same number of vertices %t| Ok. %x1" - result = Draw.PupMenu(name) - return + else: - name = "Second Object must have at least a shape key %t| Ok. %x1" + name = "Meshes Objects must have the same number of vertices %t|Ok. %x1" result = Draw.PupMenu(name) - return + return + if DATA2.getKey(): + select_modifier(RVK1, RVK2, DATA2) else: - name = "Object must be Meshes %t| Ok. %x1" + name = "Second Object must have at least a shape key %t| Ok. %x1| Add one ? %x2" result = Draw.PupMenu(name) - return - else : - name = "At least 2 Meshes as to be selected %t| Ok. %x1" + if result : + RVK2.insertShapeKey() + DATA2=RVK2.getData() + select_modifier(RVK1, RVK2, DATA2) + else: + return + else: + name = "Object must be Meshes %t| Ok. %x1" result = Draw.PupMenu(name) return + +def deform2rvk(): + scn = Blender.Scene.GetCurrent() + # ================================================================= + # at leat 2 objects =============================================== + # ================================================================= + if len(scn.objects.selected) >1 : + RVK1 = Object.GetSelected()[0] + RVK2=Object.GetSelected()[1] + if RVK2.getType()=='Mesh' : + copy_shapes(RVK1,RVK2) + # ================================================================= + # ... but if only one...=========================================== + # ================================================================= + elif len(scn.objects.selected)==1: + name = "At least 2 Meshes must be selected %t| Ok. %x1| Add one ? %x2" + result = Draw.PupMenu(name) + RVK1 = Object.GetSelected()[0] + if result and RVK1.getType()=='Mesh' : + Blender.Object.Duplicate(mesh=1) + RVK2=scn.objects.active + mod = RVK2.modifiers + for m in mod : + RVK2.modifiers.remove(m) + RVK2.LocX+=2.0 + copy_shapes(RVK1,RVK2) + scn.objects.selected=[] + RVK2.sel=1 + RVK1.sel=1 + # ================================================================ + # ... and not a mesh...=========================================== + # ================================================================ + elif result: + name = "Selected object must be a mesh %t| Ok. %x1" + result = Draw.PupMenu(name) + return + else : + return + # ================================================================ + # ... if not object at all. ===================================== + # ================================================================ + else: + name = "At least one Mesh object must be selected %t| Ok. %x1" + result = Draw.PupMenu(name) + return + Blender.Redraw() + EDITMODE=Blender.Window.EditMode() Blender.Window.EditMode(0) -deform2rvk() -Blender.Window.EditMode(EDITMODE) \ No newline at end of file +END = 0 +DEFAULT= Blender.Get('curframe') + +while not END: + deform2rvk() + name = "Do you want to copy at a new frame %t| Yes ? %x1| No ? %x2" + result = Draw.PupMenu(name) + if result == 1: + msg = "Frame :" + inputresult = Draw.PupIntInput(msg, DEFAULT , Blender.Get('staframe'), Blender.Get('endframe')) + print inputresult + if inputresult != None: + Blender.Set('curframe',inputresult) + Blender.Window.RedrawAll() + else: + END = 1 + else: + END = 1 + +Blender.Window.EditMode(EDITMODE) From 036ebc55233241bf9bd8149f855185cfcfb1ab67 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 21 May 2009 18:10:19 +0000 Subject: [PATCH 290/444] BGE: GUI control over frame rate, logic rate, physics rate and physics subrate. Four new buttons in World settings to control frame rate: fps: Nominal frame rate in frame per second. Also sets the physics timestep = 1/fps phys: Maximum number of physics timestep per game frame in case the actual fps is less than nominal. This allows the physics to keep up with real time even if the graphics slows down the game. sub: Fixed number of simulation substeps per physic timestep. Improves the precision of the physics simulation. Useful for fast moving objects for example. log: Maximum number of logic steps per game frame in case the actual fps is less than nominal. This allows the logic system to follow the physics simulation. Upper bound = phys (setting the value higher than phys has no effect). On games with heavy logic system, it is useful to set this value to 1, to keep logic time under control. All these values were already accessible from Python except phys: GameLogic.getMaxPhysicsFrame(): Gets the maximum number of physics frame per render frame. GameLogic.setMaxPhysicsFrame(phys): Sets the maximum number of physics timestep that are executed per render frame. Higher value allows physics to keep up with realtime even if graphics slows down the game. Physics timestep is fixed and equal to 1/tickrate (see setLogicTicRate) maxphysics/ticrate is the maximum delay of the renderer that physics can compensate. phys: integer --- source/blender/blenkernel/intern/world.c | 4 +++ source/blender/blenloader/intern/readfile.c | 7 ++++ source/blender/makesdna/DNA_world_types.h | 1 + source/blender/src/buttons_shading.c | 17 ++++++--- .../Converter/BL_BlenderDataConversion.cpp | 2 ++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 36 +++++++++++++++---- source/gameengine/Ketsji/KX_KetsjiEngine.h | 9 +++++ source/gameengine/Ketsji/KX_PythonInit.cpp | 17 +++++++++ source/gameengine/PyDoc/GameLogic.py | 19 ++++++++++ 9 files changed, 102 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 6635ef29d51..d47f4efeb4e 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -109,6 +109,10 @@ World *add_world(char *name) wrld->mode = WO_DBVT_CULLING; // DBVT culling by default wrld->occlusionRes = 128; wrld->preview = NULL; + wrld->ticrate = 60; + wrld->maxlogicstep = 5; + wrld->physubstep = 1; + wrld->maxphystep = 5; return wrld; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 25c8a928a3b..bda0348f2ca 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8108,6 +8108,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) { Object *ob; + World *wrld; for(ob = main->object.first; ob; ob= ob->id.next) { if(ob->parent) { /* check if top parent has compound shape set and if yes, set this object @@ -8120,6 +8121,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ob->gameflag |= OB_CHILD; } } + for(wrld=main->world.first; wrld; wrld= wrld->id.next) { + wrld->ticrate = 60; + wrld->maxlogicstep = 5; + wrld->physubstep = 1; + wrld->maxphystep = 5; + } } if (main->versionfile < 249) { diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index f599364ed66..5f6e47acac4 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -90,6 +90,7 @@ typedef struct World { short mode; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; /* here it's aligned */ + short ticrate, maxlogicstep, physubstep, maxphystep; float misi, miststa, mistdist, misthi; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 79f95d1bf5f..12219944945 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2198,16 +2198,25 @@ static void world_panel_mistaph(World *wrld) /* Gravitation for the game worlds */ uiDefButF(block, NUMSLI,0, "Grav ", 150,180,150,19, &(wrld->gravity), 0.0, 25.0, 0, 0, "Sets the gravitation constant of the game world"); + uiDefButS(block, NUM, B_REDR, "fps:", + 10, 160, 70, 19, &wrld->ticrate, 1.0, 120.0, 0, 0, "Sets the nominal number of game frames per second. Physics fixed timestep = 1/fps, independently of actual frame rate"); + uiDefButS(block, NUM, B_REDR, "log:", + 80, 160, 70, 19, &wrld->maxlogicstep, 1.0, 5.0, 0, 0, "Sets the maxmimum number of logic frame per game frame if graphics slows down the game, higher value allows better synchronization with physics"); + uiDefButS(block, NUM, B_REDR, "phys:", + 150, 160, 75, 19, &wrld->maxphystep, 1.0, 5.0, 0, 0, "Sets the maximum number of physics step per game frame if graphics slows down the game, higher value allows physics to keep up with realtime"); + uiDefButS(block, NUM, B_REDR, "sub:", + 225, 160, 75, 19, &wrld->physubstep, 1.0, 5.0, 0, 0, "Sets the number of simulation substep per physic timestep, higher value give better physics precision"); + if (wrld->physicsEngine == WOPHY_BULLET) { - uiDefButBitS(block, TOG, WO_DBVT_CULLING, B_REDR, "DBVT culling", 10,160,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for view frustrum and occlusion culling"); + uiDefButBitS(block, TOG, WO_DBVT_CULLING, B_REDR, "DBVT culling", 10,140,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for view frustrum and occlusion culling"); if (wrld->mode & WO_DBVT_CULLING) uiDefButS(block, NUM, B_REDR, "Occlu Res:", - 150, 160, 150, 19, &wrld->occlusionRes, 128.0, 1024.0, 0, 0, "Sets the size of the occlusion buffer in pixel, use higher value for better precsion (slower)"); + 150, 140, 150, 19, &wrld->occlusionRes, 128.0, 1024.0, 0, 0, "Sets the size of the occlusion buffer in pixel, use higher value for better precsion (slower)"); } #endif uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, WO_MIST, B_WORLDPRV2,"Mist", 10,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation"); + uiDefButBitS(block, TOG, WO_MIST, B_WORLDPRV2,"Mist", 10,115,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation"); uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); @@ -2222,7 +2231,7 @@ static void world_panel_mistaph(World *wrld) uiBlockEndAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, WO_STARS, B_WORLDPRV2, "Stars",160,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation"); + uiDefButBitS(block, TOG, WO_STARS, B_WORLDPRV2, "Stars",160,115,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation"); uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 82edd4f218b..f3024197a8a 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2499,6 +2499,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (occlusion) kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes); } + if (blenderscene->world) + kxscene->GetPhysicsEnvironment()->setNumTimeSubSteps(blenderscene->world->physubstep); // now that the scenegraph is complete, let's instantiate the deformers. // We need that to create reusable derived mesh and physic shapes diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 4107ed7d82e..983059d0c70 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -77,6 +77,8 @@ #include "RAS_FramingManager.h" #include "stdio.h" +#include "DNA_world_types.h" +#include "DNA_scene_types.h" // If define: little test for Nzc: guarded drawing. If the canvas is // not valid, skip rendering this frame. @@ -98,6 +100,7 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE; int KX_KetsjiEngine::m_maxLogicFrame = 5; +int KX_KetsjiEngine::m_maxPhysicsFrame = 5; double KX_KetsjiEngine::m_anim_framerate = 25.0; double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; @@ -393,8 +396,20 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo) m_firstframe = true; m_bInitialized = true; - m_ticrate = DEFAULT_LOGIC_TIC_RATE; - m_maxLogicFrame = 5; + // there is always one scene enabled at startup + World* world = m_scenes[0]->GetBlenderScene()->world; + if (world) + { + m_ticrate = world->ticrate; + m_maxLogicFrame = world->maxlogicstep; + m_maxPhysicsFrame = world->maxphystep; + } + else + { + m_ticrate = DEFAULT_LOGIC_TIC_RATE; + m_maxLogicFrame = 5; + m_maxPhysicsFrame = 5; + } if (m_game2ipo) { @@ -545,14 +560,13 @@ else // PIL_sleep_ms(1); KX_SceneList::iterator sceneit; - int frameOut = 5; - if (frames>frameOut) + if (frames>m_maxPhysicsFrame) { // printf("framedOut: %d\n",frames); - m_frameTime+=(frames-frameOut)*timestep; - frames = frameOut; + m_frameTime+=(frames-m_maxPhysicsFrame)*timestep; + frames = m_maxPhysicsFrame; } @@ -1736,6 +1750,16 @@ void KX_KetsjiEngine::SetMaxLogicFrame(int frame) m_maxLogicFrame = frame; } +int KX_KetsjiEngine::GetMaxPhysicsFrame() +{ + return m_maxPhysicsFrame; +} + +void KX_KetsjiEngine::SetMaxPhysicsFrame(int frame) +{ + m_maxPhysicsFrame = frame; +} + double KX_KetsjiEngine::GetAnimFrameRate() { return m_anim_framerate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index cc9b9198db7..5c14c63dd04 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -104,6 +104,7 @@ private: double m_remainingTime; static int m_maxLogicFrame; /* maximum number of consecutive logic frame */ + static int m_maxPhysicsFrame; /* maximum number of consecutive physics frame */ static double m_ticrate; static double m_anim_framerate; /* for animation playback only - ipo and action */ @@ -292,6 +293,14 @@ public: * Sets the maximum number of logic frame before render frame */ static void SetMaxLogicFrame(int frame); + /** + * Gets the maximum number of physics frame before render frame + */ + static int GetMaxPhysicsFrame(); + /** + * Sets the maximum number of physics frame before render frame + */ + static void SetMaxPhysicsFrame(int frame); /** * Gets the framerate for playing animations. (actions and ipos) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index fb99eab7747..3626d7baa9a 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -308,6 +308,21 @@ static PyObject* gPyGetMaxLogicFrame(PyObject*) return PyInt_FromLong(KX_KetsjiEngine::GetMaxLogicFrame()); } +static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args) +{ + int frame; + if (!PyArg_ParseTuple(args, "i:setMaxPhysicsFrame", &frame)) + return NULL; + + KX_KetsjiEngine::SetMaxPhysicsFrame(frame); + Py_RETURN_NONE; +} + +static PyObject* gPyGetMaxPhysicsFrame(PyObject*) +{ + return PyInt_FromLong(KX_KetsjiEngine::GetMaxPhysicsFrame()); +} + static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args) { float ticrate; @@ -501,6 +516,8 @@ static struct PyMethodDef game_methods[] = { {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (PY_METHODCHAR)"stop using the audio dsp (for performance reasons)"}, {"getMaxLogicFrame", (PyCFunction) gPyGetMaxLogicFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of logic frame per render frame"}, {"setMaxLogicFrame", (PyCFunction) gPySetMaxLogicFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of logic frame per render frame"}, + {"getMaxPhysicsFrame", (PyCFunction) gPyGetMaxPhysicsFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of physics frame per render frame"}, + {"setMaxPhysicsFrame", (PyCFunction) gPySetMaxPhysicsFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of physics farme per render frame"}, {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the logic tic rate"}, {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (PY_METHODCHAR)"Sets the logic tic rate"}, {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the physics tic rate"}, diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 1bc406daf09..3ec30a63c58 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -387,6 +387,23 @@ def setMaxLogicFrame(maxlogic): @param maxlogic: The new maximum number of logic frame per render frame. Valid values: 1..5 @type maxlogic: integer """ +def getMaxPhysicsFrame(): + """ + Gets the maximum number of physics frame per render frame. + + @return: The maximum number of physics frame per render frame + @rtype: interger + """ +def setMaxPhysicsFrame(maxphysics): + """ + Sets the maximum number of physics timestep that are executed per render frame. + Higher value allows physics to keep up with realtime even if graphics slows down the game. + Physics timestep is fixed and equal to 1/tickrate (see setLogicTicRate) + maxphysics/ticrate is the maximum delay of the renderer that physics can compensate. + + @param maxphysics: The new maximum number of physics timestep per render frame. Valid values: 1..5. + @type maxphysics: integer + """ def getLogicTicRate(): """ Gets the logic update frequency. @@ -406,6 +423,7 @@ def setLogicTicRate(ticrate): """ def getPhysicsTicRate(): """ + NOT IMPLEMENTED Gets the physics update frequency @return: The physics update frequency in Hz @@ -413,6 +431,7 @@ def getPhysicsTicRate(): """ def setPhysicsTicRate(ticrate): """ + NOT IMPLEMENTED Sets the physics update frequency The physics update frequency is the number of times the physics system is executed every second. From 7f5acd68755cb36aa7f679ffbd41cc3c6d9cbf58 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 21 May 2009 19:38:49 +0000 Subject: [PATCH 291/444] BGE remove parent: unparented object keeps the linear and angular velocity it had while being parented. --- source/gameengine/Ketsji/KX_GameObject.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 0c191257f41..3740972ba29 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -312,6 +312,18 @@ void KX_GameObject::RemoveParent(KX_Scene *scene) rootobj->m_pPhysicsController1->RemoveCompoundChild(m_pPhysicsController1); } m_pPhysicsController1->RestoreDynamics(); + if (m_pPhysicsController1->IsDyna() && rootobj->m_pPhysicsController1) + { + // dynamic object should remember the velocity they had while being parented + MT_Point3 childPoint = GetSGNode()->GetWorldPosition(); + MT_Point3 rootPoint = rootobj->GetSGNode()->GetWorldPosition(); + MT_Point3 relPoint; + relPoint = (childPoint-rootPoint); + MT_Vector3 linVel = rootobj->m_pPhysicsController1->GetVelocity(relPoint); + MT_Vector3 angVel = rootobj->m_pPhysicsController1->GetAngularVelocity(); + m_pPhysicsController1->SetLinearVelocity(linVel, false); + m_pPhysicsController1->SetAngularVelocity(angVel, false); + } } // graphically, the object hasn't change place, no need to update m_pGraphicController } From e191618cb5906ad50c7b6a75f52ad54cc6a812f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 22 May 2009 03:22:56 +0000 Subject: [PATCH 292/444] - Deprecated Mathutils.CrossVecs(v1,v2) for v1.cross(v2), (same with .DotVecs -> v1.dot(v2), for CrossQuats and DotQuats too) - Grouped Mathutils deprecated functions - Dont include source code in bpy epydocs --- source/blender/python/api2_2x/Mathutils.h | 8 +-- .../blender/python/api2_2x/doc/Mathutils.py | 44 ++++++++++++++++ .../blender/python/api2_2x/doc/epy_docgen.sh | 2 +- source/blender/python/api2_2x/quat.c | 38 ++++++++++++++ source/blender/python/api2_2x/quat.h | 2 + source/blender/python/api2_2x/vector.c | 52 +++++++++++++++++-- source/blender/python/api2_2x/vector.h | 4 +- 7 files changed, 140 insertions(+), 10 deletions(-) diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index b511f2046a6..789470d43c6 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -45,8 +45,6 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2); PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args); PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CrossVecs(PyObject * self, PyObject * args); -PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args); PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args); PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args); PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args); @@ -57,8 +55,6 @@ PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args); PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args); PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args); PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args); -PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args); PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args); PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args); PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args); @@ -75,6 +71,10 @@ PyObject *M_Mathutils_CopyEuler(PyObject * self, PyObject * args); PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args); PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args); PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args); +PyObject *M_Mathutils_CrossVecs(PyObject * self, PyObject * args); +PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args); +PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args); +PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index 52cd5fbcc7f..73a2ce46c4f 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -26,6 +26,8 @@ Example:: angle = DifferenceQuats(quat1, quat2) print angle + +@group Deprecated: CopyMat, CopyVec, CopyQuat, CopyEuler, RotateEuler, MatMultVec, VecMultMat, CrossVecs, DotVecs, CrossQuats, DotQuats """ def Rand (low=0.0, high = 1.0): @@ -129,6 +131,7 @@ def CopyVec(vector): def CrossVecs(vec1, vec2): """ Return the cross product of two vectors. + @attention: B{DEPRECATED} use vector.cross(other) instead. @type vec1: Vector object. @param vec1: A 3d vector. @type vec2: Vector object. @@ -141,6 +144,7 @@ def CrossVecs(vec1, vec2): def DotVecs(vec1, vec2): """ Return the dot product of two vectors. + @attention: B{DEPRECATED} use vector.dot(other) instead. @type vec1: Vector object. @param vec1: A 2d,3d or 4d vector. @type vec2: Vector object. @@ -323,6 +327,7 @@ def CopyQuat(quaternion): def CrossQuats(quat1, quat2): """ Return the cross product of two quaternions. + @attention: B{DEPRECATED} use quat.cross(other) instead. @type quat1: Quaternion object. @param quat1: Quaternion. @type quat2: Quaternion object. @@ -335,6 +340,7 @@ def CrossQuats(quat1, quat2): def DotQuats(quat1, quat2): """ Return the dot product of two quaternions. + @attention: B{DEPRECATED} use quat.dot(other) instead. @type quat1: Quaternion object. @param quat1: Quaternion. @type quat2: Quaternion object. @@ -541,6 +547,26 @@ class Vector: @return: The reflected vector. """ + def cross(other): + """ + Return the cross product of this vector and another. + @note: both vectors must be 3D. + @type other: Vector object + @param other: The other vector to perform the cross product with. + @rtype: Vector + @return: The cross product. + """ + + def dot(other): + """ + Return the dot product of this vector and another. + @note: both vectors must be the same size. + @type other: Vector object + @param other: The other vector to perform the dot product with. + @rtype: float + @return: The dot product. + """ + class Euler: """ The Euler object @@ -740,6 +766,24 @@ class Quaternion: @return: A 3x3 rotation matrix representation of the quaternion. """ + def cross(other): + """ + Return the cross product of this quaternion and another. + @type other: Quaterion object + @param other: The other quaternion to perform the cross product with. + @rtype: Vector + @return: The cross product. + """ + + def dot(other): + """ + Return the dot product of this quaternion and another. + @type other: Quaterion object + @param other: The other quaternion to perform the dot product with. + @rtype: float + @return: The dot product. + """ + class Matrix: """ The Matrix Object diff --git a/source/blender/python/api2_2x/doc/epy_docgen.sh b/source/blender/python/api2_2x/doc/epy_docgen.sh index 0e5350e41ae..3c903e849af 100755 --- a/source/blender/python/api2_2x/doc/epy_docgen.sh +++ b/source/blender/python/api2_2x/doc/epy_docgen.sh @@ -8,4 +8,4 @@ LC_ALL=POSIX epydoc --debug -v -o BPY_API --url "http://www.blender.org" --top API_intro \ - --name "Blender" --no-private --no-frames [A-Z]*.py + --name "Blender" --no-private --no-sourcecode [A-Z]*.py diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c index 14fd5f9ba4c..585b76a34dc 100644 --- a/source/blender/python/api2_2x/quat.c +++ b/source/blender/python/api2_2x/quat.c @@ -41,6 +41,8 @@ char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse"; char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion"; char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with."; char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion"; +char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another"; +char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another"; char Quaternion_copy_doc[] = "() - return a copy of the quat"; //-----------------------METHOD DEFINITIONS ---------------------- struct PyMethodDef Quaternion_methods[] = { @@ -51,6 +53,8 @@ struct PyMethodDef Quaternion_methods[] = { {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, Quaternion_Normalize_doc}, {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, Quaternion_ToEuler_doc}, {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, Quaternion_ToMatrix_doc}, + {"cross", (PyCFunction) Quaternion_Cross, METH_O, Quaternion_Cross_doc}, + {"dot", (PyCFunction) Quaternion_Dot, METH_O, Quaternion_Dot_doc}, {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, {NULL, NULL, 0, NULL} @@ -96,6 +100,40 @@ PyObject *Quaternion_ToMatrix(QuaternionObject * self) return newMatrixObject(mat, 3, 3, Py_NEW); } + +//----------------------------Quaternion.cross(other)------------------ +//return the cross quat +PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value) +{ + float quat[4]; + + if (!QuaternionObject_Check(value)) { + PyErr_SetString( PyExc_TypeError, "quat.cross(value): expected a quaternion argument" ); + return NULL; + } + + QuatMul(quat, self->quat, value->quat); + return newQuaternionObject(quat, Py_NEW); +} + +//----------------------------Quaternion.dot(other)------------------ +//return the dot quat +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); +} + //----------------------------Quaternion.normalize()---------------- //normalize the axis of rotation of [theta,vector] PyObject *Quaternion_Normalize(QuaternionObject * self) diff --git a/source/blender/python/api2_2x/quat.h b/source/blender/python/api2_2x/quat.h index 9f3a919bce0..84a013d9788 100644 --- a/source/blender/python/api2_2x/quat.h +++ b/source/blender/python/api2_2x/quat.h @@ -64,6 +64,8 @@ PyObject *Quaternion_Inverse( QuaternionObject * self ); PyObject *Quaternion_Normalize( QuaternionObject * self ); PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args ); PyObject *Quaternion_ToMatrix( QuaternionObject * self ); +PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value ); +PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value ); PyObject *Quaternion_copy( QuaternionObject * self ); PyObject *newQuaternionObject( float *quat, int type ); diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index f4504a13f72..cb206363dbf 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -47,7 +47,9 @@ char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; -char Vector_reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; +char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; +char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another"; +char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another"; char Vector_copy_doc[] = "() - return a copy of the vector"; char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order"; /*-----------------------METHOD DEFINITIONS ----------------------*/ @@ -59,7 +61,9 @@ struct PyMethodDef Vector_methods[] = { {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, - {"reflect", ( PyCFunction ) Vector_reflect, METH_O, Vector_reflect_doc}, + {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc}, + {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Dot_doc}, + {"dot", ( PyCFunction ) Vector_Dot, METH_O, Vector_Cross_doc}, {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, {NULL, NULL, 0, NULL} @@ -275,7 +279,7 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) return a reflected vector on the mirror normal ((2 * DotVecs(vec, mirror)) * mirror) - vec using arithb.c would be nice here */ -PyObject *Vector_reflect( VectorObject * self, PyObject * value ) +PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) { VectorObject *mirrvec; float mirror[3]; @@ -288,7 +292,7 @@ PyObject *Vector_reflect( VectorObject * self, PyObject * value ) float norm = 0.0f; if (!VectorObject_Check(value)) { - PyErr_SetString( PyExc_TypeError, "expected a vector argument" ); + PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" ); return NULL; } mirrvec = (VectorObject *)value; @@ -322,6 +326,46 @@ PyObject *Vector_reflect( VectorObject * self, PyObject * value ) return newVectorObject(reflect, self->size, Py_NEW); } +PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) +{ + VectorObject *vecCross = NULL; + + if (!VectorObject_Check(value)) { + PyErr_SetString( PyExc_TypeError, "vec.cross(value): expected a vector argument" ); + return NULL; + } + + if(self->size != 3 || value->size != 3) { + PyErr_SetString(PyExc_AttributeError, "vec.cross(value): expects both vectors to be 3D\n"); + return NULL; + } + + vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW); + Crossf(vecCross->vec, self->vec, value->vec); + return (PyObject *)vecCross; +} + +PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) +{ + double dot = 0.0; + int x; + + if (!VectorObject_Check(value)) { + PyErr_SetString( PyExc_TypeError, "vec.cross(value): expected a vector argument" ); + return NULL; + } + + if(self->size != value->size) { + PyErr_SetString(PyExc_AttributeError, "vec.dot(value): expects both vectors to have the same size\n"); + return NULL; + } + + for(x = 0; x < self->size; x++) { + dot += self->vec[x] * value->vec[x]; + } + return PyFloat_FromDouble(dot); +} + /*----------------------------Vector.copy() -------------------------------------- return a copy of the vector */ PyObject *Vector_copy(VectorObject * self) diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h index 9ec2eff8047..94827935ebb 100644 --- a/source/blender/python/api2_2x/vector.h +++ b/source/blender/python/api2_2x/vector.h @@ -51,7 +51,9 @@ PyObject *Vector_Resize2D( VectorObject * self ); PyObject *Vector_Resize3D( VectorObject * self ); PyObject *Vector_Resize4D( VectorObject * self ); PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); -PyObject *Vector_reflect( VectorObject * self, PyObject * value ); +PyObject *Vector_Reflect( VectorObject * self, PyObject * value ); +PyObject *Vector_Cross( VectorObject * self, VectorObject * value ); +PyObject *Vector_Dot( VectorObject * self, VectorObject * value ); PyObject *Vector_copy( VectorObject * self ); PyObject *newVectorObject(float *vec, int size, int type); From 612f3b326662498207e6e051feeceaac81e09343 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 22 May 2009 03:45:46 +0000 Subject: [PATCH 293/444] Removed use of CrossVecs, DotVecs, CrossQuats and DotQuats for all scripts except import_dxf and colladaImEx/translator.py --- release/scripts/bpymodules/BPyMathutils.py | 3 +- release/scripts/bpymodules/BPyMesh.py | 6 ++-- release/scripts/bpymodules/BPyMesh_redux.py | 5 ++- release/scripts/bpymodules/BPyWindow.py | 2 +- release/scripts/bpymodules/mesh_gradient.py | 6 ++-- release/scripts/mesh_skin.py | 8 ++--- release/scripts/mesh_unfolder.py | 6 ++-- release/scripts/uvcalc_quad_clickproj.py | 4 +-- release/scripts/uvcalc_smart_project.py | 18 +++++------ release/scripts/vertexpaint_selfshadow_ao.py | 3 +- release/scripts/wizard_curve2tree.py | 34 ++++++++++---------- 11 files changed, 45 insertions(+), 50 deletions(-) diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py index bfa1dcc3c61..4882e9aaf21 100644 --- a/release/scripts/bpymodules/BPyMathutils.py +++ b/release/scripts/bpymodules/BPyMathutils.py @@ -132,7 +132,6 @@ modified for Blender/Mathutils by Campell Barton ###################################################################### # Public interface ###################################################################### -from Blender.Mathutils import DotVecs def convexHull(point_list_2d): """Calculate the convex hull of a set of vectors The vectors can be 3 or 4d but only the Xand Y are used. @@ -197,7 +196,7 @@ def plane2mat(plane, normalize= False): up= cent - ((plane[0]+plane[1])/2.0) right= cent - ((plane[1]+plane[2])/2.0) - z= CrossVecs(up, right) + z= up.cross(right) if normalize: up.normalize() diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py index 6bbfaa463d0..292f7a4b91e 100644 --- a/release/scripts/bpymodules/BPyMesh.py +++ b/release/scripts/bpymodules/BPyMesh.py @@ -569,12 +569,11 @@ def face_edges(me): def facesPlanerIslands(me): - DotVecs= Blender.Mathutils.DotVecs def roundvec(v): return round(v[0], 4), round(v[1], 4), round(v[2], 4) - face_props= [(cent, no, roundvec(no), DotVecs(cent, no)) for f in me.faces for no, cent in ((f.no, f.cent),)] + face_props= [(cent, no, roundvec(no), cent.dot(no)) for f in me.faces for no, cent in ((f.no, f.cent),)] face_edge_users= face_edges(me) islands= [] @@ -607,7 +606,7 @@ def facesPlanerIslands(me): face_prop2= face_props[fidx2] # normals are the same? if face_prop1[2]==face_prop2[2]: - if abs(face_prop1[3] - DotVecs(face_prop1[1], face_prop2[0])) < 0.000001: + if abs(face_prop1[3] - face_prop1[1].dot(face_prop2[0])) < 0.000001: used_faces[fidx2]= 1 island.append(fidx2) islands.append([me.faces[i] for i in island]) @@ -616,7 +615,6 @@ def facesPlanerIslands(me): def facesUvIslands(me, PREF_IMAGE_DELIMIT=True): - DotVecs= Blender.Mathutils.DotVecs def roundvec(v): return round(v[0], 4), round(v[1], 4) diff --git a/release/scripts/bpymodules/BPyMesh_redux.py b/release/scripts/bpymodules/BPyMesh_redux.py index 1bcc6e9f7c8..5955d696fbd 100644 --- a/release/scripts/bpymodules/BPyMesh_redux.py +++ b/release/scripts/bpymodules/BPyMesh_redux.py @@ -25,7 +25,6 @@ import Blender import bpy Vector= Blender.Mathutils.Vector Ang= Blender.Mathutils.AngleBetweenVecs -CrossVecs= Blender.Mathutils.CrossVecs MidpointVecs= Blender.Mathutils.MidpointVecs import BPyMesh @@ -198,8 +197,8 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=2.0, REMOVE_DOUBLES=False, FACE_AREA_WEI # the point of collapsing. # Enlarge so we know they intersect: self.length*2 - cv1= CrossVecs(v1no, CrossVecs(v1no, v1co-v2co)) - cv2= CrossVecs(v2no, CrossVecs(v2no, v2co-v1co)) + cv1= v1no.cross(v1no.cross(v1co-v2co)) + cv2= v2no.cross(v2no.cross(v2co-v1co)) # Scale to be less then the edge lengths. cv2.length = cv1.length = 1 diff --git a/release/scripts/bpymodules/BPyWindow.py b/release/scripts/bpymodules/BPyWindow.py index f48f5dfc0ad..d3fd4fa88b5 100644 --- a/release/scripts/bpymodules/BPyWindow.py +++ b/release/scripts/bpymodules/BPyWindow.py @@ -1,6 +1,6 @@ import Blender from Blender import Mathutils, Window, Scene, Draw, Mesh -from Blender.Mathutils import CrossVecs, Matrix, Vector, Intersect +from Blender.Mathutils import Matrix, Vector, Intersect # DESCRIPTION: # screen_x, screen_y the origin point of the pick ray diff --git a/release/scripts/bpymodules/mesh_gradient.py b/release/scripts/bpymodules/mesh_gradient.py index 936f4958467..e582a30152b 100644 --- a/release/scripts/bpymodules/mesh_gradient.py +++ b/release/scripts/bpymodules/mesh_gradient.py @@ -6,7 +6,7 @@ import BPyWindow mouseViewRay= BPyWindow.mouseViewRay from Blender import Mathutils, Window, Scene, Draw, sys -from Blender.Mathutils import CrossVecs, Vector, Intersect, LineIntersect, AngleBetweenVecs +from Blender.Mathutils import Vector, Intersect, LineIntersect, AngleBetweenVecs LMB= Window.MButs['L'] def mouseup(): @@ -101,11 +101,11 @@ def vertexGradientPick(ob, MODE): # make a line 90d to the grad in screenspace. if (OriginA-OriginB).length <= eps: # Persp view. same origin different direction - cross_grad= CrossVecs(DirectionA, DirectionB) + cross_grad= DirectionA.cross(DirectionB) ORTHO= False else: # Ortho - Same direction, different origin - cross_grad= CrossVecs(DirectionA, OriginA-OriginB) + cross_grad= DirectionA.cross(OriginA-OriginB) ORTHO= True cross_grad.normalize() diff --git a/release/scripts/mesh_skin.py b/release/scripts/mesh_skin.py index a554e128b41..4a330a516fb 100644 --- a/release/scripts/mesh_skin.py +++ b/release/scripts/mesh_skin.py @@ -52,7 +52,7 @@ A pop-up will provide further options, if the results of a method are not adequa import Blender import bpy from Blender import Window -from Blender.Mathutils import MidpointVecs, Vector, CrossVecs +from Blender.Mathutils import MidpointVecs, Vector from Blender.Mathutils import AngleBetweenVecs as _AngleBetweenVecs_ import BPyMessages @@ -119,7 +119,7 @@ class edgeLoop(object): # GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP. self.normal = Vector() for e in self.edges: - n = CrossVecs(self.centre-e.co1, self.centre-e.co2) + n = (self.centre-e.co1).cross(self.centre-e.co2) # Do we realy need tot normalize? n.normalize() self.normal += n @@ -149,7 +149,7 @@ class edgeLoop(object): a = n1-n2 b = n1-n3 - normal1 = CrossVecs(a,b) + normal1 = a.cross(b) normal1.normalize() n1 = e.co2 @@ -159,7 +159,7 @@ class edgeLoop(object): a = n1-n2 b = n1-n3 - normal2 = CrossVecs(a,b) + normal2 = a.cross(b) normal2.normalize() # Reuse normal1 var diff --git a/release/scripts/mesh_unfolder.py b/release/scripts/mesh_unfolder.py index 906e0f0a300..f5c19a92bd0 100644 --- a/release/scripts/mesh_unfolder.py +++ b/release/scripts/mesh_unfolder.py @@ -164,8 +164,8 @@ class Fold: sangle = Mathutils.AngleBetweenVecs(self.refPolyNormal, self.polyNormal) if(sangle!=sangle): sangle=0.0 - ncp = Mathutils.CrossVecs(self.refPolyNormal, self.polyNormal) - dp = Mathutils.DotVecs(ncp, self.edge.vector) + ncp = self.refPolyNormal.cross(self.polyNormal) + dp = ncp.dot(self.edge.vector) if(dp>0.0): return +sangle else: @@ -855,7 +855,7 @@ class Poly: p.resize3D() q = a-c q.resize3D() - return CrossVecs(p,q) + return p.cross(q) def makeEdges(self): self.edges = [] for i in xrange(self.nPoints()): diff --git a/release/scripts/uvcalc_quad_clickproj.py b/release/scripts/uvcalc_quad_clickproj.py index 130a7e5af77..298103e4d5f 100644 --- a/release/scripts/uvcalc_quad_clickproj.py +++ b/release/scripts/uvcalc_quad_clickproj.py @@ -46,7 +46,7 @@ import BPyWindow mouseViewRay= BPyWindow.mouseViewRay from Blender import Mathutils, Window, Scene, Draw, sys -from Blender.Mathutils import CrossVecs, Vector, Matrix, LineIntersect, Intersect #, AngleBetweenVecs, Intersect +from Blender.Mathutils import Vector, Matrix, LineIntersect, Intersect #, AngleBetweenVecs, Intersect LMB= Window.MButs.L RMB= Window.MButs.R @@ -229,7 +229,7 @@ def main(): y_axis_length = line_a_len x_axis_length = (line_isect_b_pair[1]-face_corner_main).length - proj_y_component = CrossVecs(proj_x_component, proj_z_component) + proj_y_component = proj_x_component.cross(proj_z_component) proj_y_component.length = 1/y_axis_length proj_x_component.length = 1/x_axis_length diff --git a/release/scripts/uvcalc_smart_project.py b/release/scripts/uvcalc_smart_project.py index 55d6ebfaa6f..9d9bd2aaefd 100644 --- a/release/scripts/uvcalc_smart_project.py +++ b/release/scripts/uvcalc_smart_project.py @@ -43,7 +43,7 @@ selected faces, or all faces. from Blender import Object, Draw, Window, sys, Mesh, Geometry -from Blender.Mathutils import CrossVecs, Matrix, Vector, RotationMatrix, DotVecs +from Blender.Mathutils import Matrix, Vector, RotationMatrix import bpy from math import cos @@ -96,7 +96,7 @@ def pointInTri2D(v, v1, v2, v3): side1 = v2 - v1 side2 = v3 - v1 - nor = CrossVecs(side1, side2) + nor = side1.cross(side2) l1 = [side1[0], side1[1], side1[2]] l2 = [side2[0], side2[1], side2[2]] @@ -804,11 +804,11 @@ def VectoMat(vec): a3 = vec.__copy__().normalize() up = Vector(0,0,1) - if abs(DotVecs(a3, up)) == 1.0: + if abs(a3.dot(up)) == 1.0: up = Vector(0,1,0) - a1 = CrossVecs(a3, up).normalize() - a2 = CrossVecs(a3, a1) + a1 = a3.cross(up).normalize() + a2 = a3.cross(a1) return Matrix([a1[0], a1[1], a1[2]], [a2[0], a2[1], a2[2]], [a3[0], a3[1], a3[2]]) @@ -1001,7 +1001,7 @@ def main(): for fIdx in xrange(len(tempMeshFaces)-1, -1, -1): # Use half the angle limit so we dont overweight faces towards this # normal and hog all the faces. - if DotVecs(newProjectVec, tempMeshFaces[fIdx].no) > USER_PROJECTION_LIMIT_HALF_CONVERTED: + if newProjectVec.dot(tempMeshFaces[fIdx].no) > USER_PROJECTION_LIMIT_HALF_CONVERTED: newProjectMeshFaces.append(tempMeshFaces.pop(fIdx)) # Add the average of all these faces normals as a projectionVec @@ -1027,7 +1027,7 @@ def main(): # Get the closest vec angle we are to. for p in projectVecs: - temp_angle_diff= DotVecs(p, tempMeshFaces[fIdx].no) + temp_angle_diff= p.dot(tempMeshFaces[fIdx].no) if angleDifference < temp_angle_diff: angleDifference= temp_angle_diff @@ -1066,14 +1066,14 @@ def main(): i = len(projectVecs) # Initialize first - bestAng = DotVecs(fvec, projectVecs[0]) + bestAng = fvec.dot(projectVecs[0]) bestAngIdx = 0 # Cycle through the remaining, first alredy done while i-1: i-=1 - newAng = DotVecs(fvec, projectVecs[i]) + newAng = fvec.dot(projectVecs[i]) if newAng > bestAng: # Reverse logic for dotvecs bestAng = newAng bestAngIdx = i diff --git a/release/scripts/vertexpaint_selfshadow_ao.py b/release/scripts/vertexpaint_selfshadow_ao.py index d641fd12111..54c67fd27e2 100644 --- a/release/scripts/vertexpaint_selfshadow_ao.py +++ b/release/scripts/vertexpaint_selfshadow_ao.py @@ -45,7 +45,6 @@ import BPyMesh def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY): Window.WaitCursor(1) - DotVecs = Mathutils.DotVecs Ang= Mathutils.AngleBetweenVecs BPyMesh.meshCalcNormals(me) @@ -63,7 +62,7 @@ def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PRE for v in f.v: vno=v.no # get a scaled down normal. - dot= DotVecs(vno, v.co) - DotVecs(vno, fc) + dot= vno.dot(v.co) - vno.dot(fc) vert_tone_count[v.index]+=1 try: a= Ang(vno, fno) diff --git a/release/scripts/wizard_curve2tree.py b/release/scripts/wizard_curve2tree.py index 1965f9a5070..07b45c1986f 100644 --- a/release/scripts/wizard_curve2tree.py +++ b/release/scripts/wizard_curve2tree.py @@ -39,7 +39,7 @@ __bpydoc__ = """\ import bpy import Blender import BPyMesh -from Blender.Mathutils import Vector, Matrix, CrossVecs, AngleBetweenVecs, LineIntersect, TranslationMatrix, ScaleMatrix, RotationMatrix, Rand +from Blender.Mathutils import Vector, Matrix, AngleBetweenVecs, LineIntersect, TranslationMatrix, ScaleMatrix, RotationMatrix, Rand from Blender.Geometry import ClosestPointOnLine from Blender.Noise import randuvec @@ -496,12 +496,12 @@ class tree: # Align this with the existing branch angle = AngleBetweenVecsSafe(zup, parent_pt.no) - cross = CrossVecs(zup, parent_pt.no) + cross = zup.cross(parent_pt.no) mat_align = RotationMatrix(angle, 3, 'r', cross) # Use the bend on the point to work out which way to make the branch point! - if parent_pt.prev: cross = CrossVecs(parent_pt.no, parent_pt.prev.no - parent_pt.no) - else: cross = CrossVecs(parent_pt.no, parent_pt.next.no - parent_pt.no) + if parent_pt.prev: cross = parent_pt.no.cross(parent_pt.prev.no - parent_pt.no) + else: cross = parent_pt.no.cross(parent_pt.next.no - parent_pt.no) if parent_pt.branch.parent_pt: angle = AngleBetweenVecsSafe(parent_pt.branch.parent_pt.no, parent_pt.no) @@ -1065,8 +1065,8 @@ class tree: l = line_normal.length - cross1 = CrossVecs( seg.no, line_normal ) - cross2 = CrossVecs( pt.no, line_normal ) + cross1 = seg.no.cross(line_normal) + cross2 = pt.no.cross(line_normal) angle_line = min(AngleBetweenVecsSafe(cross1, cross2), AngleBetweenVecsSafe(cross1, -cross2)) angle_leaf_no_diff = min(AngleBetweenVecsSafe(line_normal, seg.no), AngleBetweenVecsSafe(line_normal, -seg.no)) @@ -1914,8 +1914,8 @@ class tree: # endpoints dont rotate if pt.next != None: - cross1 = CrossVecs(zup, pt.no) # use this to offset the leaf later - cross2 = CrossVecs(cross1, pt.no) + cross1 = zup.cross(pt.no) # use this to offset the leaf later + cross2 = cross1.cross(pt.no) if odd_even ==0: mat_yaw = RotationMatrix(leaf_branch_angle, 3, 'r', cross2) else: @@ -1939,7 +1939,7 @@ class tree: # Randomize pitch and roll for the leaf # work out the axis to pitch and roll - cross1 = CrossVecs(zup, leaf_no) # use this to offset the leaf later + cross1 = zup.cross(leaf_no) # use this to offset the leaf later if leaf_branch_pitch_rand or leaf_branch_pitch_angle: angle = -leaf_branch_pitch_angle @@ -2480,7 +2480,7 @@ class bpoint(object): def calcVerts(self): if self.prev == None: if self.branch.parent_pt: - cross = CrossVecs(self.no, self.branch.parent_pt.no) * RotationMatrix(-45, 3, 'r', self.no) + cross = self.no.cross(self.branch.parent_pt.no) * RotationMatrix(-45, 3, 'r', self.no) else: # parentless branch - for best results get a cross thats not the same as the normal, in rare cases this happens. @@ -2493,9 +2493,9 @@ class bpoint(object): else: cross = xup else: - cross = CrossVecs(self.prev.vecs[0], self.no) + cross = self.prev.vecs[0].cross(self.no) - self.vecs[0] = Blender.Mathutils.CrossVecs(self.no, cross) + self.vecs[0] = self.no.cross(cross) self.vecs[0].length = abs(self.radius) mat = RotationMatrix(90, 3, 'r', self.no) self.vecs[1] = self.vecs[0] * mat @@ -2660,8 +2660,8 @@ class branch: self_normal = self.bpoints[1].co - self.parent_pt.co # We only want the angle in relation to the parent points normal # modify self_normal to make this so - cross = CrossVecs(self_normal, self.parent_pt.no) - self_normal = CrossVecs(self.parent_pt.no, cross) # CHECK + cross = self_normal.cross(self.parent_pt.no) + self_normal = self.parent_pt.no.cross(cross) # CHECK #try: angle = AngleBetweenVecs(parent_normal, self_normal) #except: return 0.0 @@ -2670,7 +2670,7 @@ class branch: # see if we need to rotate positive or negative # USE DOT PRODUCT! - cross = CrossVecs(parent_normal, self_normal) + cross = parent_normal.cross(self_normal) if AngleBetweenVecsSafe(cross, self.parent_pt.no) > 90: angle = -angle @@ -3018,7 +3018,7 @@ class branch: scales = [] for cos_ls in (cos1, cos2): - cross = CrossVecs(cos_ls[-1], zup) + cross = cos_ls[-1].cross(zup) mat = RotationMatrix(AngleBetweenVecsSafe(cos_ls[-1], zup), 3, 'r', cross) cos_ls[:] = [co*mat for co in cos_ls] @@ -3029,7 +3029,7 @@ class branch: for co in cos_ls: xy_nor.x += co.x xy_nor.y += co.y - cross = CrossVecs(xy_nor, xup) + cross = xy_nor.cross(xup) # Also scale them here so they are 1.0 tall always scale = 1.0/(cos_ls[0]-cos_ls[-1]).length From ec60c74f081b006a6e8aebefe930a37aac95b865 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 22 May 2009 06:12:18 +0000 Subject: [PATCH 294/444] Fix for: energy IPO not supported in glsl mode (reported in the forum). in fact I redid part of the last "fix", making it working properly now. Before we were changing Lamp->la . This is the Blender Lamp, we shouldn't touch it. So this part of the code is correct now. Things that could be tackled: - color attribute is returning negative values when NEGATIVE is toggled - objects with no material (default gray one) still don't support lamp spots (not spot lamp but the spot of the lamps) --- source/blender/gpu/intern/gpu_material.c | 12 +++++------- source/gameengine/Ketsji/KX_Light.cpp | 7 ------- source/gameengine/Ketsji/KX_Light.h | 1 - 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 93604e76527..818b67170c7 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1308,14 +1308,12 @@ void GPU_lamp_update(GPULamp *lamp, int lay, float obmat[][4]) void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy) { - lamp->la->energy = energy; - lamp->la->r = fabs(r); - lamp->la->g = fabs(g); - lamp->la->b = fabs(b); + lamp->energy = energy; + if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy; - lamp->col[0]= lamp->la->r*lamp->energy; - lamp->col[1]= lamp->la->g*lamp->energy; - lamp->col[2]= lamp->la->b*lamp->energy; + lamp->col[0]= r* lamp->energy; + lamp->col[1]= g* lamp->energy; + lamp->col[2]= b* lamp->energy; } static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 1496f34c5f2..fe575384a35 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -61,11 +61,6 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_rendertools->AddLight(&m_lightobj); m_glsl = glsl; m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene(); - - m_initialvalues[0] = lightobj.m_red; - m_initialvalues[1] = lightobj.m_green; - m_initialvalues[2] = lightobj.m_blue; - m_initialvalues[3] = lightobj.m_energy; }; @@ -76,8 +71,6 @@ KX_LightObject::~KX_LightObject() if((lamp = GetGPULamp())) { float obmat[4][4] = {{0}}; GPU_lamp_update(lamp, 0, obmat); - GPU_lamp_update_colors(lamp, m_initialvalues[0], m_initialvalues[1], - m_initialvalues[2], m_initialvalues[3]); } m_rendertools->RemoveLight(&m_lightobj); diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 690231ff090..35f25515e3b 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -44,7 +44,6 @@ class KX_LightObject : public KX_GameObject Py_Header; protected: RAS_LightObject m_lightobj; - float m_initialvalues [4]; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj bool m_glsl; Scene* m_blenderscene; From 66ed4325f488d408f4a9179decced37bd1d816ad Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 22 May 2009 09:48:05 +0000 Subject: [PATCH 295/444] the debug option for BGE scripts only reloaded modules but not packages submodules. Now reload all the submodules too. It was also hiding the error message if there was a syntax error which wasnt so helpful. --- .../GameLogic/SCA_PythonController.cpp | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index d58259457e6..8140dbd53db 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -324,10 +324,7 @@ bool SCA_PythonController::Import() } PyObject *mod = PyImport_ImportModule((char *)py_function_path[0].Ptr()); - if(mod && m_debug) { - Py_DECREF(mod); /* getting a new one so dont hold a ref to the old one */ - mod= PyImport_ReloadModule(mod); - } + /* Dont reload yet, do this within the loop so packages reload too */ if(mod==NULL) { ErrorPrint("Python module not found"); @@ -339,18 +336,29 @@ bool SCA_PythonController::Import() PyObject *base= mod; for(unsigned int i=1; i < py_function_path.size(); i++) { + if(m_debug) { + Py_DECREF(base); /* getting a new one so dont hold a ref to the old one */ + base= PyImport_ReloadModule(base); + if (base==NULL) { + m_function= NULL; + break; + } + } + m_function = PyObject_GetAttrString(base, py_function_path[i].Ptr()); Py_DECREF(base); base = m_function; /* for the next loop if there is on */ if(m_function==NULL) { - PyErr_Clear(); /* print our own error below */ break; } } if(m_function==NULL) { - printf("Python module error \"%s\":\n \"%s\" module found but function missing\n", GetName().Ptr(), m_scriptText.Ptr()); + if(PyErr_Occurred()) + ErrorPrint("Python controller found the module but could not access the function"); + else + printf("Python module error \"%s\":\n \"%s\" module found but function missing\n", GetName().Ptr(), m_scriptText.Ptr()); return false; } From 794826feaee501d984ce2e6b7459a7f5757b8722 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 22 May 2009 12:31:27 +0000 Subject: [PATCH 296/444] Update to the bolt/nut script, I also replaced some loops with list-comprehension and use mesh.transform(matrix) rather then transforming every vert in a loop. V2.00 22/05/09 by Aaron Keith - Better error checking. - Lock Nut and Hex Nut meshes added. - Pre-sets for common metric bolts and nuts. - Improved GUI. - Meshes scaled to a smaller size - Fixed bug when using crest and root percent other than 10% - Can now create meshes in Edit Mode. This will add to the current mesh and align with the current view. --- release/scripts/wizard_bolt_factory.py | 923 +++++++++---------------- 1 file changed, 343 insertions(+), 580 deletions(-) diff --git a/release/scripts/wizard_bolt_factory.py b/release/scripts/wizard_bolt_factory.py index 572cd763c18..6a280eccc58 100644 --- a/release/scripts/wizard_bolt_factory.py +++ b/release/scripts/wizard_bolt_factory.py @@ -1,40 +1,51 @@ #!BPY - +# -*- coding: latin-1 -*- """ Name: 'Bolt Factory' -Blender: 249 +Blender: 248 Group: 'Wizards' -Tooltip: 'Create models of various types to screw fasteners.' +Tooltip: 'Create models of various types of screw fasteners.' """ __author__ = " Aaron Keith (Spudmn) " -__version__ = "1.50 " -__url__ = ["blender", "http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Misc/Bolt_Factory"] -__email__= [""] +__version__ = "2.00 2009/05/22" +__url__ = ["Author's site,http://sourceforge.net/projects/boltfactory/", "Blender,http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Misc/Bolt_Factory"] __bpydoc__ = """\ Bolt_Factory.py Bolt Factory is a Python script for Blender 3D. -The script allows the user to create models of various types to screw fasteners. - -This version is very much a work in progress. - -This is my first attempt to program in Python. This version is unpolished and -doesn't do much error checking. Therefore if the user sets strange -variable the model created will be as equally strange. +The script allows the user to create models of various types of screw fasteners. For best results set the material to smooth and apply a Edge Split modifier with default settings. -To Do: -Better error checking. -Nuts to go with the bolts. -Pre-sets for common bolts. -Improved GUI. -More Head and Bit types. -Better documentation. -Fix error with mesh when using crest and root percent other than 10. + +History: + +V2.00 22/05/09 by Aaron Keith + +- Better error checking. +- Lock Nut and Hex Nut meshes added. +- Pre-sets for common metric bolts and nuts. +- Improved GUI. +- Meshes scaled to a smaller size +- Fixed bug when using crest and root percent other than 10% +- Can now create meshes in Edit Mode. This will add to the + current mesh and align with the current view. + +V1.00 01/04/08 by Aaron Keith + +- This version is very much a work in progress. +- This is my first attempt to program in Python. This version is + unpolished and doesn't do much error checking. Therefore + if the user sets strange variable the model created will be + as equally strange. + +- To Do: +- Better error checking. +- More Head and Bit types. +- Better documentation. """ @@ -44,7 +55,7 @@ Fix error with mesh when using crest and root percent other than 10. # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # -# Copyright (C) 2008: Aaron Keith +# Copyright (C) 2009: Aaron Keith # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -74,62 +85,62 @@ from Blender import Mathutils from Blender.Mathutils import * +#Global_Scale = 0.001 #1 blender unit = X mm +Global_Scale = 0.1 #1 blender unit = X mm +#Global_Scale = 1.0 #1 blender unit = X mm Global_NutRad = 0.0 MAX_INPUT_NUMBER = 50 No_Event,On_Preset_Click,On_Apply_Click,On_Create_Click,On_Hex_Click, On_Cap_Click,On_Dome_Click,On_Pan_Click,On_Bit_None_Click,On_Bit_Allen_Click,On_Bit_Philips_Click,On_Exit_Click,On_Model_Bolt_Click,On_Model_Nut_Click,On_Hex_Nut_Click,On_Lock_Nut_Click,On_Test_Click = range(17) # this is like a ENUM -Head_Type={'HEX' : [Draw.Create(1),On_Hex_Click], - 'CAP' : [Draw.Create(0),On_Cap_Click], - 'DOME': [Draw.Create(0),On_Dome_Click], - 'PAN' : [Draw.Create(0),On_Pan_Click]} +Head_Type={'HEX' : [Draw.Create(1),On_Hex_Click,""], + 'CAP' : [Draw.Create(0),On_Cap_Click,""], + 'DOME': [Draw.Create(0),On_Dome_Click,""], + 'PAN' : [Draw.Create(0),On_Pan_Click,""]} -Bit_Type={'NONE' : [Draw.Create(1),On_Bit_None_Click], - 'ALLEN' : [Draw.Create(0),On_Bit_Allen_Click], - 'PHILLIPS': [Draw.Create(0),On_Bit_Philips_Click]} +Bit_Type={'NONE' : [Draw.Create(1),On_Bit_None_Click,""], + 'ALLEN' : [Draw.Create(0),On_Bit_Allen_Click,""], + 'PHILLIPS': [Draw.Create(0),On_Bit_Philips_Click,""]} -Model_Type={'BOLT' : [Draw.Create(1),On_Model_Bolt_Click], - 'NUT' : [Draw.Create(0),On_Model_Nut_Click]} +Model_Type={'BOLT' : [Draw.Create(1),On_Model_Bolt_Click,"Bolt Settings"], + 'NUT' : [Draw.Create(0),On_Model_Nut_Click,"Nut Settings"]} -Nut_Type={'HEX' : [Draw.Create(1),On_Hex_Nut_Click], - 'LOCK' : [Draw.Create(0),On_Lock_Nut_Click]} +Nut_Type={'HEX' : [Draw.Create(1),On_Hex_Nut_Click,""], + 'LOCK' : [Draw.Create(0),On_Lock_Nut_Click,""]} +Phillips_Bit_Depth = Draw.Create(3.27) +Philips_Bit_Dia = Draw.Create(5.20) -Phillips_Bit_Depth = Draw.Create(1.0) -Philips_Bit_Dia = Draw.Create(1.75) +Allen_Bit_Depth = Draw.Create(4.0) +Allen_Bit_Flat_Distance = Draw.Create(6.0) -Allen_Bit_Depth = Draw.Create(1.0) -Allen_Bit_Flat_Distance = Draw.Create(1.25) +Hex_Head_Height = Draw.Create(5.3) +Hex_Head_Flat_Distance = Draw.Create(13.0) -Hex_Head_Height = Draw.Create(1.0) -Hex_Head_Flat_Distance = Draw.Create(2.25) +Cap_Head_Dia = Draw.Create(13.5) +Cap_Head_Height = Draw.Create(8.0) -Cap_Head_Dia = Draw.Create(2.25) -Cap_Head_Height = Draw.Create(1.5) -Cap_Head_Inside_Rad = 0.0 +Dome_Head_Dia = Draw.Create(16.0) -Dome_Head_Dia = Draw.Create(3.75) +Pan_Head_Dia = Draw.Create(16.0) -Pan_Head_Dia = Draw.Create(5.375) +Shank_Dia = Draw.Create(8.0) +Shank_Length = Draw.Create(0.0) -Shank_Dia = Draw.Create(1.5) -Shank_Length = Draw.Create(0.125) +Thread_Length = Draw.Create(16.0) +Major_Dia = Draw.Create(8.0) +Minor_Dia = Draw.Create(6.917) +Pitch = Draw.Create(1.0) +Crest_Percent = Draw.Create(10) +Root_Percent = Draw.Create(10) -Thread_Length = Draw.Create(2.5) -Major_Dia = Draw.Create(1.5) -Minor_Dia = Draw.Create(1.25) -Pitch = Draw.Create(0.125) -Crest_Percent = Draw.Create(1.25) -Root_Percent = Draw.Create(1.25) +Hex_Nut_Height = Draw.Create(8.0) +Hex_Nut_Flat_Distance = Draw.Create(13.0) -Hex_Nut_Height = Draw.Create(1.0) -Hex_Nut_Flat_Distance = Draw.Create(2.25) - -Preset_Menu = Draw.Create(0.25) -Preset_Length = Draw.Create(1.5) +Preset_Menu = Draw.Create(5) ########################################################################################## @@ -138,14 +149,11 @@ Preset_Length = Draw.Create(1.5) ########################################################################################## ########################################################################################## - +# Returns a list of verts rotated by the given matrix. Used by SpinDup def Rot_Mesh(verts,matrix): - ret = [] - for v in verts: - vec = Vector(v) * matrix - ret.append([vec.x,vec.y,vec.z]) - return ret + return [list(Vector(v) * matrix) for v in verts] +# Returns a list of faces that has there index incremented by offset def Copy_Faces(faces,offset): ret = [] for f in faces: @@ -155,13 +163,8 @@ def Copy_Faces(faces,offset): ret.append(fsub) return ret -def Move_Verts_Up_Z(VERTS,DISTANCE): - ret = [] - for v in VERTS: - ret.append([v[0],v[1],v[2]+DISTANCE]) - return ret - +# Much like Blenders built in SpinDup. def SpinDup(VERTS,FACES,DEGREE,DIVISIONS,AXIS): verts=[] faces=[] @@ -171,22 +174,20 @@ def SpinDup(VERTS,FACES,DEGREE,DIVISIONS,AXIS): step = DEGREE/DIVISIONS # set step so pieces * step = degrees in arc - for i in range(int(DIVISIONS)): + for i in xrange(int(DIVISIONS)): rotmat = Mathutils.RotationMatrix(step*i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis. Rot = Rot_Mesh(VERTS,rotmat) faces.extend(Copy_Faces(FACES,len(verts))) - #print faces verts.extend(Rot) return verts,faces -def Mirror_Verts(VERTS,AXIS): - ret = [] - for v in VERTS: - ret.append([0-v[0],v[1],v[2]]) - return ret +# Returns a list of verts that have been moved up the z axis by DISTANCE +def Move_Verts_Up_Z(VERTS,DISTANCE): + return [[v[0],v[1],v[2]+DISTANCE] for v in VERTS] +# Returns a list of verts and faces that has been mirrored in the AXIS def Mirror_Verts_Faces(VERTS,FACES,AXIS,FLIP_POINT =0): ret_vert = [] ret_face = [] @@ -208,42 +209,15 @@ def Mirror_Verts_Faces(VERTS,FACES,AXIS,FLIP_POINT =0): fsub = [] for i in range(len(f)): fsub.append(f[i]+ offset) - fsub.reverse() # filp the order to make norm point out + fsub.reverse() # flip the order to make norm point out ret_face.append(fsub) return ret_vert,ret_face -def Lath(tool_V1,tool_V2,verts,faces): - - #verts = [] - #faces = []f - - #verts.append([7.0,6.0,0.0]) - #verts.append([7.0+10,6.0-10,0.0]) - #faces.append([3,4]) - - vec1 = Vector(verts[-1]) - vec2 = Vector(verts[-2]) - - VecOut1,VecR2 = LineIntersect(vec1, vec2,Vector(tool_V1), Vector(tool_V2)) - - vec1 = Vector(verts[-2]) - vec2 = Vector(verts[-3]) - - VecOut2,VecR2 = LineIntersect(vec1, vec2,Vector(tool_V1), Vector(tool_V2)) - - if VecOut1 != None: - if VecOut1 == VecOut2: - #print "got it" - faces.append([len(verts),len(verts)+1]) - verts.append([VecOut1.x,VecOut1.y,VecOut1.z]) - verts.append([VecOut2.x,VecOut2.y,VecOut2.z]) - #print verts[-1] - #print verts[-2] - - return verts,faces +# Returns a list of faces that +# make up an array of 4 point polygon. def Build_Face_List_Quads(OFFSET,COLUM,ROW,FLIP = 0): Ret =[] RowStart = 0; @@ -261,7 +235,8 @@ def Build_Face_List_Quads(OFFSET,COLUM,ROW,FLIP = 0): return Ret - +# Returns a list of faces that makes up a fill pattern for a +# circle def Fill_Ring_Face(OFFSET,NUM,FACE_DOWN = 0): Ret =[] Face = [1,2,0] @@ -298,12 +273,23 @@ def Fill_Ring_Face(OFFSET,NUM,FACE_DOWN = 0): return Ret +########################################################################################## +########################################################################################## +## Converter Functions For Bolt Factory +########################################################################################## +########################################################################################## + + def Flat_To_Radius(FLAT): h = (float(FLAT)/2)/cos(radians(30)) - #print h return h - +def Get_Phillips_Bit_Height(Bit_Dia): + Flat_Width_half = (Bit_Dia*(0.5/1.82))/2.0 + Bit_Rad = Bit_Dia / 2.0 + x = Bit_Rad - Flat_Width_half + y = tan(radians(60))*x + return y ########################################################################################## ########################################################################################## @@ -338,6 +324,8 @@ def Error_Check(): global Major_Dia global Minor_Dia global Pitch + global Hex_Nut_Flat_Distance + global Model_Type #global Crest_Percent #global Root_Percent @@ -349,22 +337,48 @@ def Error_Check(): print error_txt Error_Result = TRUE - elif (Pitch.val*7.0) > Thread_Length.val: - error_txt = "Error%t|Thread length must be at least 7 times the pitch" + elif (Model_Type['BOLT'][0].val) and ((Pitch.val*7.0) > Thread_Length.val): + error_txt = "Error%t|Thread length must be at least 7 times the Pitch" Blender.Draw.PupMenu(error_txt) print error_txt Error_Result = TRUE + + elif (Model_Type['NUT'][0].val) and (Hex_Nut_Flat_Distance.val < Major_Dia.val): + error_txt = "Error%t|Nut Flat Distance must be greater than Major Dia" + Blender.Draw.PupMenu(error_txt) + print error_txt + Error_Result = TRUE + + elif (Model_Type['NUT'][0].val) and ((Pitch.val * 2.5 )> Hex_Nut_Height.val): + error_txt = "Error%t|Nut Height must be greater than 2.5 * Pitch" + Blender.Draw.PupMenu(error_txt) + print error_txt + Error_Result = TRUE + + elif (Model_Type['BOLT'][0].val): + Check_Head_Height = None + Check_Bit_Height = None + if (Bit_Type['ALLEN'][0].val): + Check_Bit_Height = Allen_Bit_Depth.val + if (Bit_Type['PHILLIPS'][0].val): + Check_Bit_Height = Phillips_Bit_Depth.val + if (Head_Type['HEX'][0].val): + Check_Head_Height = Hex_Head_Height.val + if (Head_Type['CAP'][0].val): + Check_Head_Height = Cap_Head_Height.val + + if Check_Head_Height != None and Check_Bit_Height != None : + if Check_Bit_Height > Check_Head_Height: + error_txt = "Error%t|Bit Depth must not be greater that Head Height" + Blender.Draw.PupMenu(error_txt) + print error_txt + Error_Result = TRUE + + return Error_Result - - - - - - - ########################################################################################## ########################################################################################## ## Create Allen Bit @@ -372,7 +386,6 @@ def Error_Check(): ########################################################################################## - def Allen_Fill(OFFSET,FLIP= 0): faces = [] Lookup = [[19,1,0], @@ -408,14 +421,22 @@ def Allen_Fill(OFFSET,FLIP= 0): return faces - +def Allen_Bit_Dia(FLAT_DISTANCE): + Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30)) + return (Flat_Radius * 1.05) * 2.0 + +def Allen_Bit_Dia_To_Flat(DIA): + Flat_Radius = (DIA/2.0)/1.05 + return (Flat_Radius * cos (radians(30)))* 2.0 + + def Create_Allen_Bit(FLAT_DISTANCE,HEIGHT): Div = 36 verts = [] faces = [] - Flat_Radius = (float(FLAT_DISTANCE)/2)/cos(radians(30)) + Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30)) OUTTER_RADIUS = Flat_Radius * 1.05 Outter_Radius_Height = Flat_Radius * (0.1/5.77) FaceStart_Outside = len(verts) @@ -453,7 +474,7 @@ def Create_Allen_Bit(FLAT_DISTANCE,HEIGHT): verts.extend(M_Verts) faces.extend(M_Faces) - return verts,faces,OUTTER_RADIUS * 2 + return verts,faces,OUTTER_RADIUS * 2.0 ########################################################################################## @@ -550,6 +571,10 @@ def Create_Phillips_Bit(FLAT_DIA,FLAT_WIDTH,HEIGHT): ########################################################################################## ########################################################################################## +def Max_Pan_Bit_Dia(HEAD_DIA): + HEAD_RADIUS = HEAD_DIA * 0.5 + XRad = HEAD_RADIUS * 1.976 + return (sin(radians(10))*XRad) * 2.0 def Create_Pan_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): @@ -558,15 +583,13 @@ def Create_Pan_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): HOLE_RADIUS = HOLE_DIA * 0.5 HEAD_RADIUS = HEAD_DIA * 0.5 SHANK_RADIUS = SHANK_DIA * 0.5 - - print "hole dia", HOLE_DIA + verts = [] faces = [] Row = 0 BEVEL = HEIGHT * 0.01 #Dome_Rad = HEAD_RADIUS * (1.0/1.75) - Dome_Rad = HEAD_RADIUS * 1.12 RAD_Offset = HEAD_RADIUS * 0.96 OtherRad = HEAD_RADIUS * 0.16 @@ -600,7 +623,6 @@ def Create_Pan_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): for i in range(10,30,10): x = sin(radians(i))*XRad z = cos(radians(i))*ZRad - print x verts.append([x,0.0,(0.0-ZRad)+z]) Row += 1 @@ -662,12 +684,6 @@ def Create_Dome_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): # OtherRad_Z_Offset = 2.52 # - - #averts, afaces = Create_Allen_Bit(8.5,5,5) - #verts.extend(averts) - #faces.extend(afaces) - - #FaceStart = len(verts) FaceStart = FACE_OFFSET verts.append([HOLE_RADIUS,0.0,0.0]) @@ -677,7 +693,6 @@ def Create_Dome_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): for i in range(0,60,10): x = sin(radians(i))*Dome_Rad z = cos(radians(i))*Dome_Rad - #verts.append([x,0.0,(0.0-RAD_Offset)+z]) if ((0.0-RAD_Offset)+z) <= 0: verts.append([x,0.0,(0.0-RAD_Offset)+z]) Row += 1 @@ -696,26 +711,12 @@ def Create_Dome_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2,FACE_OFFSET): Row += 1 - - #for i in range(0,18,1): - # x = i - # verts.append([x,0.0,(0.0-Dome_Height)]) - # Row += 1 - - - #verts.append([SHANK_RADIUS,0.0,(0.0-Dome_Height)-Dome_Height]) - #Row += 1 - - sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) - - #Global_Head_Height = Dome_Height return sVerts,faces,Dome_Height - #return verts,faces @@ -726,11 +727,6 @@ def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2): HEAD_RADIUS = HEAD_DIA * 0.5 SHANK_RADIUS = SHANK_DIA * 0.5 - - print "Head dia" , HEAD_DIA - print "Rad1" , RAD1 - print "Rad2" , RAD2 - verts = [] faces = [] Row = 0 @@ -742,22 +738,15 @@ def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2): verts.append([HOLE_RADIUS,0.0,0.0]) Row += 1 - #verts.append([HEAD_RADIUS-RAD1,0.0,0.0]) - #Row += 1 Done in for loop below - #rad for i in range(0,100,10): - #print i x = sin(radians(i))*RAD1 z = cos(radians(i))*RAD1 verts.append([(HEAD_RADIUS-RAD1)+x,0.0,(0.0-RAD1)+z]) Row += 1 - #verts.append([HEAD_RADIUS,0.0,0.0-RAD1]) - #Row += 1 Done in for loop above - verts.append([HEAD_RADIUS,0.0,0.0-HEIGHT+BEVEL]) Row += 1 @@ -765,34 +754,21 @@ def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2): Row += 1 #rad2 - - -# verts.append([SHANK_RADIUS+RAD2,0.0,0.0-HEIGHT]) -# Row += 1 Done by rad2 below - + for i in range(0,100,10): x = sin(radians(i))*RAD2 z = cos(radians(i))*RAD2 verts.append([(SHANK_RADIUS+RAD2)-x,0.0,(0.0-HEIGHT-RAD2)+z]) Row += 1 -# verts.append([SHANK_RADIUS,0.0,0.0-HEIGHT-RAD2]) -# Row += 1 done by rad2 above - - -# verts.append([SHANK_RADIUS,0.0,0.0-HEIGHT-RAD2-RAD2]) -# Row += 1 sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - #Global_Head_Height = HEIGHT+RAD2 - faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) return sVerts,faces,HEIGHT+RAD2 - #return verts,faces @@ -866,7 +842,6 @@ def Create_Hex_Head(FLAT,HOLE_DIA,SHANK_DIA,HEIGHT): x = tan(radians(0))*Half_Flat dvec = vec1 - Mathutils.Vector([x,Half_Flat,0.0]) - #print dvec.length verts.append([x,Half_Flat,-dvec.length]) @@ -1007,27 +982,6 @@ def Create_Hex_Head(FLAT,HOLE_DIA,SHANK_DIA,HEIGHT): Row += 1 - #Shank -# x = sin(radians(0))*SHANK_RADIUS -# y = cos(radians(0))*SHANK_RADIUS -# vec1 = Mathutils.Vector([x,y,0.0]) -# verts.append([x,y,-HEIGHT-0.5]) -# -# x = sin(radians(60/6))*SHANK_RADIUS -# y = cos(radians(60/6))*SHANK_RADIUS -# vec2 = Mathutils.Vector([x,y,0.0]) -# verts.append([x,y,-HEIGHT-0.5]) -# -# x = sin(radians(60/3))*SHANK_RADIUS -# y = cos(radians(60/3))*SHANK_RADIUS -# vec3 = Mathutils.Vector([x,y,0.0]) -# verts.append([x,y,-HEIGHT-0.5]) -# -# x = sin(radians(60/2))*SHANK_RADIUS -# y = cos(radians(60/2))*SHANK_RADIUS -# vec3 = Mathutils.Vector([x,y,0.0]) -# verts.append([x,y,-HEIGHT-0.5]) - #Global_Head_Height = 0 - (-HEIGHT-0.1) faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1)) @@ -1085,48 +1039,38 @@ def MakeBolt(): Head_Verts = [] Head_Faces= [] Head_Height = 0.0 - - - + ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Flat_Distance.val # set default + Head_Height = Hex_Head_Height.val # will be changed by the Head Functions - + + if Bit_Type['ALLEN'][0].val and Head_Type['PAN'][0].val: + #need to size Allen bit if it is too big. + if Allen_Bit_Dia(Allen_Bit_Flat_Distance.val) > Max_Pan_Bit_Dia(Pan_Head_Dia.val): + ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Dia_To_Flat(Max_Pan_Bit_Dia(Pan_Head_Dia.val)) * 1.05 + print "Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance + #bit Mesh if Bit_Type['ALLEN'][0].val: - #Create_Allen_Bit(FLAT_DISTANCE,OUTTER_RADIUS,HEIGHT): - Bit_Verts,Bit_Faces,Bit_Dia = Create_Allen_Bit(Allen_Bit_Flat_Distance.val,Allen_Bit_Depth.val) + Bit_Verts,Bit_Faces,Bit_Dia = Create_Allen_Bit(ReSized_Allen_Bit_Flat_Distance,Allen_Bit_Depth.val) if Bit_Type['PHILLIPS'][0].val: - #Create_Phillips_Bit(FLAT_RADIUS, FLAT_WIDTH, HEIGHT) - #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(Philips_Bit_Dia.val,3,Phillips_Bit_Depth.val) - #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(3.00,0.4856,1.98) - #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(4,1,2) - #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(3.8,0.9,2.0) - #Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(3.0,0.9,2.0) Bit_Verts,Bit_Faces,Bit_Dia = Create_Phillips_Bit(Philips_Bit_Dia.val,Philips_Bit_Dia.val*(0.5/1.82),Phillips_Bit_Depth.val) #Head Mesh if Head_Type['HEX'][0].val: - #add_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT) Head_Verts,Head_Faces,Head_Height = Create_Hex_Head(Hex_Head_Flat_Distance.val,Bit_Dia,Shank_Dia.val,Hex_Head_Height.val) elif Head_Type['CAP'][0].val: - #add_Cap_Head(HOLE_RADIUS,HEAD_RADIUS,SHANK_RADIUS,HEIGHT,RAD1,RAD2) - #add_Cap_Head(2,5,3,6,1,1) Head_Verts,Head_Faces,Head_Height = Create_Cap_Head(Bit_Dia,Cap_Head_Dia.val,Shank_Dia.val,Cap_Head_Height.val,Cap_Head_Dia.val*(1.0/19.0),Cap_Head_Dia.val*(1.0/19.0)) elif Head_Type['DOME'][0].val: - #add_Dome_Head(HOLE_RADIUS,HEAD_RADIUS,SHANK_RADIUS,HEIGHT,RAD1,RAD2,FACE_OFFSET): Head_Verts,Head_Faces,Head_Height = Create_Dome_Head(Bit_Dia,Dome_Head_Dia.val,Shank_Dia.val,Hex_Head_Height.val,1,1,0) elif Head_Type['PAN'][0].val: - #add_Pan_Head(HOLE_RADIUS,HEAD_RADIUS,SHANK_RADIUS,HEIGHT,RAD1,RAD2,FACE_OFFSET): - #verts, faces = add_Pan_Head(2.6,5,2,6,3.2,1,0) - #Head_Verts,Head_Faces = add_Pan_Head(2.6*2,5*2,2*2,6,3.2,1,0) Head_Verts,Head_Faces,Head_Height = Create_Pan_Head(Bit_Dia,Pan_Head_Dia.val,Shank_Dia.val,Hex_Head_Height.val,1,1,0) - print 'got here' Face_Start = len(verts) verts.extend(Move_Verts_Up_Z(Bit_Verts,Head_Height)) @@ -1143,46 +1087,11 @@ def MakeBolt(): faces.extend(Copy_Faces(Thread_Faces,Face_Start)) return Move_Verts_Up_Z(verts,Thread_Height),faces - #return Move_Verts_Up_Z(verts,0),faces -def Create_Bolt(): - verts = [] - faces = [] - - - if Error_Check() : - return - - - me = Mesh.New('Bolt') # create a new mesh - - verts, faces = MakeBolt() - - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh (also adds edges) - - - - is_editmode = Window.EditMode() # Store edit mode state - if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. - - - scn = Scene.GetCurrent() # link object to current scene - scn.objects.selected = [] - - ob = scn.objects.active = scn.objects.new(me, 'Bolt') - ob.loc = Window.GetCursorPos() - me.remDoubles(0.010) - - if is_editmode: Window.EditMode(1) - - Blender.Redraw() - - ########################################################################################## @@ -1198,8 +1107,7 @@ def Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DI Ret_Row = 0; Height_Offset = Height_Offset + PITCH #Move the offset up so that the verts start at - #at the corect place (Height_Start) - + #at the correct place (Height_Start) Half_Pitch = float(PITCH)/2 Height_Start = Height_Offset - PITCH @@ -1210,10 +1118,6 @@ def Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DI Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - -#theard start - #print Height_Start - #print "Height_Offset" , Height_Offset Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) for j in range(1): @@ -1289,7 +1193,6 @@ def Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV, Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 -#theard start Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV) @@ -1358,8 +1261,6 @@ def Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV, Height_Offset -= Root_to_Crest_Height Ret_Row += 1 - - return Ret_Row,Height_End # send back Height End as this is the lowest point @@ -1376,18 +1277,12 @@ def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_ Half_Pitch = float(PITCH)/2 Deg_Step = 360.0 /float(DIV) Height_Step = float(PITCH)/float(DIV) - - #print "HEIGHT" , HEIGHT Num = int(round((HEIGHT- PITCH)/PITCH)) # less one pitch for the start and end that is 1/2 pitch high - #print "Num" ,Num - Col = 0 Row = 0 - #CREST_PERCENT = 10 - #ROOT_PERCENT = 10 Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100) @@ -1397,18 +1292,10 @@ def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_ FaceStart = len(verts) Row_Inc,Height_Offset = Create_Internal_Thread_Start_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) - #Row_Inc,Height_Offset = Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) Row += Row_Inc - print "start Height_Offset ", Height_Offset - #Global_Thread_Height = 0 - Height_Offset - #faces.extend(Build_Face_List_Quads(FaceStart,DIV,Row -1)) - #return verts,faces - - for j in range(Num): - print j for i in range(DIV+1): x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS @@ -1438,23 +1325,12 @@ def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_ Height_Offset -= Root_to_Crest_Height Row += 1 - print "thread Height_Offset ", Height_Offset - # Row_Inc,Height_Offset = Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) - - # Row += Row_Inc + Row_Inc,Height_Offset = Create_Internal_Thread_End_Verts(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset) Row += Row_Inc - - print "End Height_Offset ", Height_Offset - - faces.extend(Build_Face_List_Quads(FaceStart,DIV,Row -1,INTERNAL)) - #faces.extend(Fill_Ring_Face(len(verts)-DIV,DIV,1)) - - #Global_Thread_Height = 0 - Height_Offset - #print "Global_Thread_Height" ,Global_Thread_Height return verts,faces,0 - Height_Offset @@ -1467,8 +1343,6 @@ def Create_Internal_Thread(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_ - - def Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset): @@ -1542,19 +1416,6 @@ def Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_ return Ret_Row,Height_Offset - - - - - - - - - - - - - def Create_Shank_Verts(START_DIA,OUTTER_DIA,LENGTH,Z_LOCATION = 0): verts = [] @@ -1571,11 +1432,6 @@ def Create_Shank_Verts(START_DIA,OUTTER_DIA,LENGTH,Z_LOCATION = 0): Stright_Length = LENGTH - Taper_Lentgh - print "opp " , Opp - print "Taper_Lentgh " , Taper_Lentgh - print "Stright_Length " , Stright_Length - - Deg_Step = 360.0 /float(DIV) Row = 0 @@ -1600,24 +1456,11 @@ def Create_Shank_Verts(START_DIA,OUTTER_DIA,LENGTH,Z_LOCATION = 0): y = cos(radians(i*Deg_Step))*START_RADIUS z = Height_Offset - 0 verts.append([x,y,z]) - if i == DIV: - print "ring", x,y,z Lowest_Z_Vert = min(Lowest_Z_Vert,z) Height_Offset -= Taper_Lentgh Row += 1 - -# for i in range(DIV+1): -# x = sin(radians(i*Deg_Step))*OUTTER_RADIUS -# y = cos(radians(i*Deg_Step))*OUTTER_RADIUS -# z = Height_Offset - 0 -# verts.append([x,y,z]) -# Lowest_Z_Vert = min(Lowest_Z_Vert,z) -# Height_Offset -= 1 -# Row += 1 - - return verts,Row,Height_Offset @@ -1639,7 +1482,6 @@ def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERC Height_Offset = Z_LOCATION - #Height_Start = Height_Offset - PITCH Height_Start = Height_Offset Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100) @@ -1658,7 +1500,6 @@ def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERC x = sin(radians(i*Deg_Step))*OUTTER_RADIUS y = cos(radians(i*Deg_Step))*OUTTER_RADIUS z = Height_Offset - (Height_Step*i) - print "z", z if z > Cut_off : z = Cut_off verts.append([x,y,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) @@ -1695,8 +1536,6 @@ def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERC Height_Offset -= Root_to_Crest_Height Row += 1 -## return verts,Row,Height_Offset - for j in range(2): for i in range(DIV+1): @@ -1759,12 +1598,6 @@ def Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERC - - - - - - def Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PERCENT,Z_LOCATION = 0): verts = [] @@ -1788,24 +1621,12 @@ def Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,HEIGHT,CREST_PERCENT,ROOT_PER Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0 - - #print "Crest_Height" ,Crest_Height - #print "Crest_to_Root_Height" ,Crest_to_Root_Height - #print "Root_Height" ,Root_Height - #print "Root_to_Crest_Height" ,Root_to_Crest_Height - - - - #Height_Offset = Half_Pitch Height_Offset = Z_LOCATION Lowest_Z_Vert = 0; FaceStart = len(verts) - - - for j in range(Num): for i in range(DIV+1): @@ -1870,12 +1691,9 @@ def Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCEN Height_Offset = Z_LOCATION - Tapper_Height_Start = Height_Offset - PITCH - PITCH - #Tapper_Height_Start = Height_Offset Max_Height = Tapper_Height_Start - PITCH - #Max_Height = Tapper_Height_Start - PITCH - PITCH - PITCH - PITCH - PITCH Lowest_Z_Vert = 0; @@ -1960,24 +1778,17 @@ def Create_External_Thread(SHANK_DIA,SHANK_LENGTH,INNER_DIA,OUTTER_DIA,PITCH,LEN Shank_Verts,Shank_Row,Offset = Create_Shank_Verts(SHANK_DIA,OUTTER_DIA,SHANK_LENGTH,Offset) Total_Row += Shank_Row - print "Shank offset " , Offset - Thread_Start_Verts,Thread_Start_Row,Offset = Create_Thread_Start_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset) Total_Row += Thread_Start_Row - print "Start offset " , Offset Thread_Verts,Thread_Row,Offset = Create_Thread_Verts(INNER_DIA,OUTTER_DIA,PITCH,LENGTH,CREST_PERCENT,ROOT_PERCENT,Offset) Total_Row += Thread_Row - print "Thread offset " , Offset Thread_End_Verts,Thread_End_Row,Offset,Lowest_Z_Vert = Create_Thread_End_Verts(INNER_DIA,OUTTER_DIA,PITCH,CREST_PERCENT,ROOT_PERCENT,Offset ) Total_Row += Thread_End_Row - print "End offset " , Offset - print "Lowest_Z_Vert " , Lowest_Z_Vert - verts.extend(Shank_Verts) @@ -2070,7 +1881,6 @@ def add_Hex_Nut(FLAT,HOLE_DIA,HEIGHT): x = tan(radians(0))*Half_Flat dvec = vec1 - Mathutils.Vector([x,Half_Flat,0.0]) - #print dvec.length verts.append([x,Half_Flat,-dvec.length]) Lowest_Z_Vert = min(Lowest_Z_Vert,-dvec.length) @@ -2147,88 +1957,24 @@ def add_Hex_Nut(FLAT,HOLE_DIA,HEIGHT): return S_verts,S_faces,TopBevelRadius - - - -def add_Nylon_Head_Top(OUTSIDE_RADIUS): - DIV = 36 - verts = [] - faces = [] - Row = 0 - - print "outside" , OUTSIDE_RADIUS - - INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) - EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) - RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) - OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) - - FaceStart = len(verts) - - Start_Height = 0 - 3 - Height_Offset = 0 - Lowest_Z_Vert = 0 - - - x = INNER_HOLE - z = Height_Offset - EDGE_THICKNESS - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - x = INNER_HOLE - z = Height_Offset - 0 - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - - for i in range(0,100,10): - #print i - x = sin(radians(i))*RAD1 - z = cos(radians(i))*RAD1 - verts.append([(OUTSIDE_RADIUS-RAD1)+x,0.0,(Height_Offset-RAD1)+z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - - x = OUTSIDE_RADIUS - 0 - z = Height_Offset - OVER_ALL_HEIGTH - print "ada" , z , OVER_ALL_HEIGTH - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') - sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - - faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) - - #return Move_Verts_Up_Z(verts,Start_Height),faces - return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert - - - def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0): DIV = 36 verts = [] faces = [] Row = 0 - print "outside" , OUTSIDE_RADIUS - - INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) + INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.25/4.75)) EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) + FaceStart = len(verts) Start_Height = 0 - 3 Height_Offset = Z_LOCATION Lowest_Z_Vert = 0 - x = INNER_HOLE z = (Height_Offset - OVER_ALL_HEIGTH) + EDGE_THICKNESS verts.append([x,0.0,z]) @@ -2243,7 +1989,6 @@ def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0): for i in range(180,80,-10): - print i x = sin(radians(i))*RAD1 z = cos(radians(i))*RAD1 verts.append([(OUTSIDE_RADIUS-RAD1)+x,0.0,((Height_Offset - OVER_ALL_HEIGTH)+RAD1)+z]) @@ -2253,7 +1998,6 @@ def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0): x = OUTSIDE_RADIUS - 0 z = Height_Offset - print "ada" , z , OVER_ALL_HEIGTH verts.append([x,0.0,z]) Lowest_Z_Vert = min(Lowest_Z_Vert,z) Row += 1 @@ -2264,65 +2008,6 @@ def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0): faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) return Move_Verts_Up_Z(sVerts,0),faces,Lowest_Z_Vert - #return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert - - - -def add_Nylon_Part_top(OUTSIDE_RADIUS,Z_LOCATION = 0): - DIV = 36 - verts = [] - faces = [] - Row = 0 - - print "outside" , OUTSIDE_RADIUS - - - INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) - EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) - RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) - OVER_ALL_HEIGTH = (OUTSIDE_RADIUS * (2.0/4.75)) - PART_THICKNESS = OVER_ALL_HEIGTH - EDGE_THICKNESS - PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5/4.75)) - - FaceStart = len(verts) - - Start_Height = 0 - 3 - Height_Offset = 0 - Lowest_Z_Vert = 0 - - - x = INNER_HOLE + EDGE_THICKNESS - z = Height_Offset - OVER_ALL_HEIGTH - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - x = PART_INNER_HOLE - z = Height_Offset - OVER_ALL_HEIGTH - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - x = PART_INNER_HOLE - z = Height_Offset - EDGE_THICKNESS - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - x = INNER_HOLE + EDGE_THICKNESS - z = Height_Offset - EDGE_THICKNESS - verts.append([x,0.0,z]) - Lowest_Z_Vert = min(Lowest_Z_Vert,z) - Row += 1 - - - sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') - sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - - faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) - - return sVerts,faces,0 - Lowest_Z_Vert - #return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert @@ -2332,9 +2017,6 @@ def add_Nylon_Part(OUTSIDE_RADIUS,Z_LOCATION = 0): faces = [] Row = 0 - print "outside" , OUTSIDE_RADIUS - - INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5/4.75)) EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4/4.75)) RAD1 = (OUTSIDE_RADIUS * (0.5/4.75)) @@ -2380,7 +2062,6 @@ def add_Nylon_Part(OUTSIDE_RADIUS,Z_LOCATION = 0): faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) return sVerts,faces,0 - Lowest_Z_Vert - #return Move_Verts_Up_Z(sVerts,0 - Lowest_Z_Vert),faces,0 - Lowest_Z_Vert @@ -2415,16 +2096,15 @@ def Nut_Mesh(): faces.extend(Copy_Faces(Nylon_faces,Face_Start)) - #verts.extend(Move_Verts_Up_Z(Thread_Verts,Global_Thread_Height)) - #verts.extend(Thread_Verts) - #faces.extend(Copy_Faces(Thread_Faces,Face_Start)) - print "low z" , LowZ - #return Move_Verts_Up_Z(verts,0),faces return Move_Verts_Up_Z(verts,0 - LowZ),faces +################################################################################################## + + def Create_Nut(): + verts = [] faces = [] @@ -2432,44 +2112,162 @@ def Create_Nut(): if Error_Check() : return - me = Mesh.New('Nut') # create a new mesh verts, faces = Nut_Mesh() + Add_Mesh_To_Scene('Nut', verts, faces) - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh (also adds edges) - - is_editmode = Window.EditMode() # Store edit mode state - if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. - - - scn = Scene.GetCurrent() # link object to current scene - scn.objects.selected = [] - ob = scn.objects.active = scn.objects.new(me, 'Nut') - ob.loc = Window.GetCursorPos() - - me.remDoubles(0.010) - - if is_editmode: Window.EditMode(1) - - Blender.Redraw() - ################################################################################################## -def Get_Phillips_Bit_Height(Bit_Dia): - Flat_Width_half = (Bit_Dia*(0.5/1.82))/2.0 - Bit_Rad = Bit_Dia / 2.0 - x = Bit_Rad - Flat_Width_half - y = tan(radians(60))*x - return y + +def Create_Bolt(): + verts = [] + faces = [] + + + if Error_Check() : + return + + verts, faces = MakeBolt() + Add_Mesh_To_Scene('Bolt', verts, faces) + + + +def Remove_Doubles_From_Mesh(verts,faces): + Ret_verts = [] + Ret_faces = [] + + is_editmode = Window.EditMode() # Store edit mode state + if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. + + Temp_mesh = Mesh.New('MeshTemp') # create a new mesh + + Temp_mesh.verts.extend(verts) # add vertices to mesh + Temp_mesh.faces.extend(faces) # add faces to the mesh (also adds edges) + + scn = Scene.GetCurrent() # link object to current scene + Temp_Object = scn.objects.new(Temp_mesh, 'ObjectTemp') + + Temp_mesh.remDoubles(0.010) + Temp_mesh.transform(Mathutils.Matrix([Global_Scale,0,0,0], [0,Global_Scale,0,0], [0,0,Global_Scale,0], [0,0,0, Global_Scale])) + Ret_verts[:] = [v.co for v in Temp_mesh.verts] + Ret_faces[:] = [ [v.index for v in f] for f in Temp_mesh.faces] + + #delete temp mesh + scn.objects.unlink(Temp_Object) + scn.update(0) + + if is_editmode: Window.EditMode(1) + return Ret_verts,Ret_faces + + + +def Add_Mesh_To_Scene(name, verts, faces): + + scn = Scene.GetCurrent() + if scn.lib: return + ob_act = scn.objects.active + + is_editmode = Window.EditMode() + + cursor = Window.GetCursorPos() + quat = None + + if is_editmode or Blender.Get('add_view_align'): # Aligning seems odd for editmode, but blender does it, oh well + try: quat = Blender.Mathutils.Quaternion(Window.GetViewQuat()) + except: pass + + + # Exist editmode for non mesh types + if ob_act and ob_act.type != 'Mesh' and is_editmode: + EditMode(0) + + # We are in mesh editmode + if Window.EditMode(): + me = ob_act.getData(mesh=1) + + if me.multires: + error_txt = 'Error%t|Unable to complete action with multires enabled' + Blender.Draw.PupMenu(error_txt) + print error_txt + return + + #Don't want to remove doubles and scale the existing + # mesh so we need to get the verts and the faces from + # a mesh that has been scaled. + verts,faces = Remove_Doubles_From_Mesh(verts, faces) + + # Add to existing mesh + # must exit editmode to modify mesh + Window.EditMode(0) + + me.sel = False + + vert_offset = len(me.verts) + face_offset = len(me.faces) + + + # transform the verts + txmat = Blender.Mathutils.TranslationMatrix(Blender.Mathutils.Vector(cursor)) + if quat: + mat = quat.toMatrix() + mat.invert() + mat.resize4x4() + txmat = mat * txmat + + txmat = txmat * ob_act.matrixWorld.copy().invert() + + + me.verts.extend(verts) + # Transform the verts by the cursor and view rotation + me.transform(txmat, selected_only=True) + + if vert_offset: + me.faces.extend([[i+vert_offset for i in f] for f in faces]) + else: + # Mesh with no data, unlikely + me.faces.extend(faces) + else: + + # Object mode add new + me = Mesh.New(name) + me.verts.extend(verts) + me.faces.extend(faces) + + + me.sel = True + + # Object creation and location + scn.objects.selected = [] + ob_act = scn.objects.new(me, name) + + me.remDoubles(0.010) + me.transform(Mathutils.Matrix([Global_Scale,0,0,0], [0,Global_Scale,0,0], [0,0,Global_Scale,0], [0,0,0, Global_Scale])) + + scn.objects.active = ob_act + + if quat: + mat = quat.toMatrix() + mat.invert() + mat.resize4x4() + ob_act.setMatrix(mat) + + ob_act.loc = cursor + + me.calcNormals() + + if is_editmode or Blender.Get('add_editmode'): + Window.EditMode(1) + + Blender.Redraw(-1)#Redraw all + +################################################################################################## def Load_Preset(): global Preset_Menu - global Preset_Length global Shank_Dia global Shank_Length global Thread_Length @@ -2487,39 +2285,18 @@ def Load_Preset(): global Pan_Head_Dia global Philips_Bit_Dia global Phillips_Bit_Depth - global Cap_Head_Inside_Rad global Cap_Head_Height global Hex_Nut_Height global Hex_Nut_Flat_Distance - -# Crest_Percent.val = 13 -# Root_Percent.val = 24 -# Thread_Length.val = 8 -# -# -# if Preset_Menu.val == 4 : #M4 -# Major_Dia.val = 4.0 -# Pitch.val = 0.7 -# -# Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) -# Hex_Head_Flat_Distance.val = 1.75 * Major_Dia.val -# -# Shank_Dia.val = Major_Dia.val -# Shank_Length.val = 0.0 -# Hex_Head_Height.val = 2.8 -# -# Cap_Head_Dia.val = 7.0 -# Allen_Bit_Flat_Distance.val = 3.0 -# Phillips_Bit_Depth.val = 1.5 - - if Preset_Menu.val == 1 : #M3 Shank_Dia.val = 3.0 #Pitch.val = 0.5 #Coarse Pitch.val = 0.35 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 3.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 5.5 @@ -2542,6 +2319,8 @@ def Load_Preset(): Shank_Dia.val = 4.0 #Pitch.val = 0.7 #Coarse Pitch.val = 0.5 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 4.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 7.0 @@ -2564,6 +2343,8 @@ def Load_Preset(): Shank_Dia.val = 5.0 #Pitch.val = 0.8 #Coarse Pitch.val = 0.5 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 5.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 8.0 @@ -2586,6 +2367,8 @@ def Load_Preset(): Shank_Dia.val = 6.0 #Pitch.val = 1.0 #Coarse Pitch.val = 0.75 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 6.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 10.0 @@ -2608,6 +2391,8 @@ def Load_Preset(): Shank_Dia.val = 8.0 #Pitch.val = 1.25 #Coarse Pitch.val = 1.00 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 8.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 13.0 @@ -2629,6 +2414,8 @@ def Load_Preset(): Shank_Dia.val = 10.0 #Pitch.val = 1.5 #Coarse Pitch.val = 1.25 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 10.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 17.0 @@ -2650,6 +2437,8 @@ def Load_Preset(): if Preset_Menu.val == 7 : #M12 #Pitch.val = 1.75 #Coarse Pitch.val = 1.50 #Fine + Crest_Percent.val = 10 + Root_Percent.val = 10 Major_Dia.val = 12.0 Minor_Dia.val = Major_Dia.val - (1.082532 * Pitch.val) Hex_Head_Flat_Distance.val = 19.0 @@ -2668,46 +2457,23 @@ def Load_Preset(): Shank_Length.val = 33.0 Thread_Length.val = 32.0 - - -def get_selected_edges(edge_lst): - ret = [] - for i in range(0, len(edge_lst)): - if edge_lst[i].sel == 1: - ret.append(edge_lst[i]) - return ret +############################################################################################## def Test(): - - - print "Test" - scn = Scene.GetCurrent() - ob = scn.getActiveObject() # Gets the current active object (If Any) - - if ob == None or ob.getType() != 'Mesh': # Checks the active objects a mesh - Draw.PupMenu('ERROR%t|Select a mesh object.') + verts = [] + faces = [] + + if Error_Check() : return + + verts, faces = MakeBolt() + + Add_Mesh_To_Scene("TestBolt", verts,faces) + + Window.Redraw(-1) - is_editmode = Window.EditMode() # Store edit mode state - if is_editmode: Window.EditMode(0) # Python must get a mesh in object mode. - - me = ob.getData(False, True) - Sel_Edges = get_selected_edges(me.faces) - print Sel_Edges - print Sel_Edges[0].index - mystr = 'Face Number ' + str(Sel_Edges) - #mystr = 'Face Number ' + str(Sel_Edges[0].index) - Draw.PupMenu(mystr) - - - if is_editmode: Window.EditMode(1) - - - - -############################################################################################## def event(evt, val): # the function to handle input events @@ -2821,14 +2587,14 @@ def Create_Tab(X1,Y1,X2,Y2,Title,Buttons): # X1,Y1 = Top Left X2,Y2 = Bottom Rig if (Buttons != 0): key= Buttons.keys() for k in key: - Buttons[k][0]= Draw.Toggle(k,Buttons[k][1],Button_X,Button_Y, BIT_BUTTON_WIDTH,BIT_BUTTON_HEIGHT,Buttons[k][0].val) + Buttons[k][0]= Draw.Toggle(k,Buttons[k][1],Button_X,Button_Y, BIT_BUTTON_WIDTH,BIT_BUTTON_HEIGHT,Buttons[k][0].val,Buttons[k][2]) Button_X += BIT_BUTTON_WIDTH + BUTTON_GAP def Dispaly_Title_Bar(Y_POS,CONTROL_HEIGHT): CONTROL_WIDTH = 250 - Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS -CONTROL_HEIGHT,"Bolt Factory V1.50_249",Model_Type) + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS -CONTROL_HEIGHT,"Bolt Factory V2.00",Model_Type) @@ -2841,8 +2607,8 @@ def Dispaly_Preset_Tab(Y_POS,CONTROL_HEIGHT): name = "M3%x1|M4%x2|M5%x3|M6%x4|M8%x5|M10%x6|M12%x7" global Preset_Menu - Preset_Menu = Draw.Menu(name,No_Event,9,Y_POS-BUTTON_Y_OFFSET,50,18, Preset_Menu.val, "Just a test menu.") - Draw.Button("Apply",On_Preset_Click,150,Y_POS-BUTTON_Y_OFFSET,55,18) + Preset_Menu = Draw.Menu(name,No_Event,9,Y_POS-BUTTON_Y_OFFSET,50,18, Preset_Menu.val, "Predefined metric screw sizes.") + Draw.Button("Apply",On_Preset_Click,150,Y_POS-BUTTON_Y_OFFSET,55,18,"Apply the preset screw sizes.") def Dispaly_Bit_Tab(Y_POS,CONTROL_HEIGHT): @@ -2924,7 +2690,7 @@ def Dispaly_Thread_Tab(Y_POS,CONTROL_HEIGHT): Number_Y_Pos -= NUMBER_HEIGHT global Pitch - Pitch = Draw.Number('Pitch: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Pitch.val, 0.01,50.0, '') + Pitch = Draw.Number('Pitch: ',No_Event,Number_X,Number_Y_Pos,NUMBER_WIDTH,NUMBER_HEIGHT, Pitch.val, 0.1,7.0, '') Number_Y_Pos -= NUMBER_HEIGHT global Crest_Percent @@ -3031,11 +2797,8 @@ def gui(): # the function to draw the screen Draw.PushButton("Create",On_Create_Click,6,8,55,18,"Create Bolt") Draw.Button("Exit",On_Exit_Click,6+55+4,8,55,18) - - #Draw.Button("Test",On_Test_Click,150,10,55,20) - #Draw.Button("Nut2",On_Nut2_Click,150,32,55,20) - - #key.sort() +# Draw.Button("Test",On_Test_Click,150,10,55,20) +Load_Preset() Draw.Register(gui, event, button_event) # registering the 3 callbacks From 89049782dea9ce6ffc0a9de2cb95db4a448db05d Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Fri, 22 May 2009 17:01:32 +0000 Subject: [PATCH 297/444] Python API ---------- Fix incorrect exception message. --- source/blender/python/api2_2x/Text3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Text3d.c b/source/blender/python/api2_2x/Text3d.c index 202195cdcb4..6312f7fffc7 100644 --- a/source/blender/python/api2_2x/Text3d.c +++ b/source/blender/python/api2_2x/Text3d.c @@ -1116,7 +1116,7 @@ static PyObject *Text3d_setFont( BPy_Text3d * self, PyObject * args ) VFont *vf; //, *vfont; if( !PyArg_ParseTuple( args, "|O!",&Font_Type, &pyobj) ) return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected a string" ); + "expected a font object" ); if( !pyobj ) { // pyobj= M_Text3d_LoadFont (self, Py_BuildValue("(s)", "")); self->curve->vfont= get_builtin_font (); From cfa2b4f0a5530e0cdda09d466fff267ad9e7eccc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 23 May 2009 03:19:47 +0000 Subject: [PATCH 298/444] [#18802] BGE conversion script: more attributes; updated GameTypes.py Patch from Alex Fraser (z0r) - All attributes in the conversion map have been checked against the docs. More ambiguities have been resolved. - Added option to convert all text buffers in Blender. - Updated GameTypes.py: there were inconsistencies. The script works well (causes no errors) with 0_FPS_Template.blend and vehicle_demo.blend from the physics-2.43-physics-testfiles pack. Caveats: - Conversions were checked against other deprecated attributes. I may have missed some cases where a deprecated attribute has the same name as a non-deprecated attribute. I did catch a few though. - As with the last version, the conversion is purely text-based and doesn't compile the code. It's easy to create a script that would break on conversion. Still, it should get you 90% of the way to a converted script. --- release/scripts/textplugin_convert_ge.py | 286 +++++++++++++++++------ source/gameengine/PyDoc/GameTypes.py | 52 +++-- 2 files changed, 242 insertions(+), 96 deletions(-) diff --git a/release/scripts/textplugin_convert_ge.py b/release/scripts/textplugin_convert_ge.py index 4a472247dcc..043b40252d9 100644 --- a/release/scripts/textplugin_convert_ge.py +++ b/release/scripts/textplugin_convert_ge.py @@ -24,6 +24,53 @@ Tooltip: 'Attemps to update deprecated usage of game engine API.' # along with this program. If not, see . # +# +# This script updates game engine scripts that were designed for pre-2.49 +# versions of Blender to run with the new API. Deprecated function calls are +# listed in attributeRenameDict. This script searches for instances of the keys +# in a target script and re-writes them. +# +# Some deprecated functions are complicated to re-write. The most common +# conversions have been implemented, but some have not. Running this will reduce +# the number of deprecation warnings in your scripts, but may not eliminate them +# entirely. +# +# NOTE: The conversion is not guaranteed to be perfect. It is strongly +# recommended that you review all changes after running this script. +# +# TODO: The following attributes are either ambiguous or need special processing +# to handle parameters. +# +# getLinearVelocity (KX_SCA_AddObjectActuator) +# Conflicts with KX_GameObject. +# setLinearVelocity (KX_SCA_AddObjectActuator) +# Conflicts with KX_GameObject. +# getAngularVelocity (KX_SCA_AddObjectActuator) +# Conflicts with KX_GameObject. +# setAngularVelocity (KX_SCA_AddObjectActuator) +# Conflicts with KX_GameObject. +# setAction (BL_ShapeActionActuator, BL_ActionActuator) +# `reset' argument has no conversion target. +# set (KX_VisibilityActuator, KX_IpoActuator) +# Different numbers of arguments. +# Arguments map to multiple attributes. +# getIndex (SCA_JoystickSensor) +# Incompatible values: Old = 1-based index; new = 0-based. +# getMesh (KX_SCA_ReplaceMeshActuator) +# Return types differ. Need to call object.name. +# getObject (KX_SCA_AddObjectActuator, KX_CameraActuator, +# KX_TrackToActuator, KX_ParentActuator) +# Default return type differs between classes. +# setIndex (SCA_JoystickSensor) +# Incompatible values: Old = 1-based index; new = 0-based. +# setObject (KX_SCA_AddObjectActuator, KX_CameraActuator, +# KX_TrackToActuator, KX_ParentActuator) +# Incompatible types: Old = KX_GameObject or String; new = +# KX_GameObject. +# setOperation (KX_SCA_DynamicActuator, KX_StateActuator) +# Ambiguous: different target names. +# + import string import re @@ -36,7 +83,7 @@ def findBalancedParens(lines, row, col, openChar = '(', closeChar = ')'): """Finds a balanced pair of parentheses, searching from lines[row][col]. The opening parenthesis must be on the starting line. - Returns a 4-tuple containing the row and column of the opening paren, and + Returns two tuples containing the row and column of the opening paren, and the row and column of the matching paren. Throws a ParseError if the first character is not openChar, or if a matching @@ -163,6 +210,25 @@ def replaceSimpleSetter(lines, row, colStart, colEnd, newName): lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName + ' = ') +def replaceArgsWithListSetter(lines, row, colStart, colEnd, newName): + """Replace a call to a multi-agument setter function with a reference to a + list property, e.g. foo.setBar(baz, bazZ) -> foo.bar = [baz, bazZ] + + The function identifier being replaced must be on line `row' and + between `colStart' and `colEnd'. The opening parenthesis must follow + immediately (whitespace is allowed). The closing parenthesis may be on the + same or following lines. + + Throws a ConversionError if the parentheses can't be found. In this case + the content of `lines' will be untouched.""" + try: + replaceNextParens(lines, row, colEnd, newOpenChar = '[', newCloseChar = ']') + except ParseError: + raise ConversionError, ("Deprecated function reference.") + + lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName + ' = ') + + def replaceKeyedGetter(lines, row, colStart, colEnd, newName): """Replace a call to a keyed getter function with a reference to a property, e.g. foo.getBar(baz) -> foo.bar[baz] @@ -261,6 +327,10 @@ def replaceAddActiveActuator(lines, row, colStart, colEnd, closure): lines[row] = replaceSubstr(lines[row], gameLogicStart, closeCol + 1, newExpr) def getObject(line, attributeStart): + '''Get the object that an attribute belongs to. `attributeStart' is the + index of the first character of the attribute name in the string `line'. + Returns: the identifier preceding `attributeStart', or None if one can't be + found.''' match = re.search(r'([a-zA-Z_]\w*)\s*\.\s*$', line[0:attributeStart]) if not match: return None @@ -268,7 +338,7 @@ def getObject(line, attributeStart): def replaceGetActuator(lines, row, colStart, colEnd, closure): '''getActuator is ambiguous: it could belong to SCA_IController or - SCA_ActuatorSensor. Try to resolve. + SCA_ActuatorSensor. Try to resolve and then convert. Raises a ConversionError if the parentheses can't be found, or if the ambiguity can't be resolved.''' @@ -284,6 +354,54 @@ def replaceGetActuator(lines, row, colStart, colEnd, closure): raise ConversionError, "Ambiguous: addActiveActuator -> actuators[key] (SCA_IController) or actuator (SCA_ActuatorSensor)." +def replaceSetOrientation(lines, row, colStart, colEnd, closure): + '''setOrientation is ambiguous: it could belong to KX_SoundActuator or + KX_GameObject. Try to resolve and then convert. If the type can't be + determined, it is assumed to be a KX_GameObject. Currently, only the + conversion for KX_GameObject is implemented. + + Raises a ConversionError if the parentheses can't be found, or if the + object is found to be a KX_SoundActuator.''' + # Get the name of the object this attribute is attached to. + obName = getObject(lines[row], colStart) + if obName: + # Try to find out whether the object is an actuator. + assn = findLastAssignment(lines, row, obName) + if assn: + match = re.search(r'([a-zA-Z_]\w*)' # Controller identifier + r'\s*\.\s*' # Dot + r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier + assn) + if match: + # It's probably a KX_SoundActuator. + raise ConversionError, "Not implemented: Can't convert arguments to matrix." + + # It's probably a KX_GameObject. + replaceSimpleSetter(lines, row, colStart, colEnd, 'localOrientation') + +def replaceSetPosition(lines, row, colStart, colEnd, closure): + '''setPosition is ambiguous: it could belong to KX_SoundActuator or + KX_GameObject. Try to resolve and then convert. If the type can't be + determined, it is assumed to be a KX_GameObject. + + Raises a ConversionError if the parentheses can't be found.''' + # Get the name of the object this attribute is attached to. + obName = getObject(lines[row], colStart) + if obName: + # Try to find out whether the object is an actuator. + assn = findLastAssignment(lines, row, obName) + if assn: + match = re.search(r'([a-zA-Z_]\w*)' # Controller identifier + r'\s*\.\s*' # Dot + r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier + assn) + if match: + # It's probably a KX_SoundActuator. + replaceSimpleSetter(lines, row, colStart, colEnd, 'position') + + # It's probably a KX_GameObject. + replaceSimpleSetter(lines, row, colStart, colEnd, 'localPosition') + # # Deprecated attribute information. The format is: # deprecatedAttributeName: {(conversionFunction, closure): classList} @@ -298,24 +416,31 @@ attributeRenameDict = { 'getActuator': {(replaceGetActuator, None): ['SCA_IController', 'SCA_ActuatorSensor']}, 'getXPosition': {(replaceGetXYPosition, '0'): ['SCA_MouseSensor']}, 'getYPosition': {(replaceGetXYPosition, '1'): ['SCA_MouseSensor']}, + 'setOrientation': {(replaceSetOrientation, None): ['KX_GameObject', 'KX_SoundActuator']}, + 'setPosition': {(replaceSetPosition, None): ['KX_GameObject', 'KX_SoundActuator']}, - # Unimplemented! There are probably more of these below that would cause errors. - #'getLinearVelocity': {(replaceSimpleGetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, - #'setLinearVelocity': {(replaceSimpleSetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, - #'getAngularVelocity': {(replaceSimpleGetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, - #'setAngularVelocity': {(replaceSimpleSetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, + # Keyed getters/setters + 'getSensor': {(replaceKeyedGetter, 'sensors'): ['SCA_IController']}, - # Generic converters + # Multi-arg -> List setter + 'setAxis': {(replaceArgsWithListSetter, 'axis'): ['SCA_JoystickSensor']}, + 'setHat': {(replaceArgsWithListSetter, 'hat'): ['SCA_JoystickSensor']}, + 'setVelocity': {(replaceArgsWithListSetter, 'velocity'): ['KX_SoundActuator']}, + + # Straight rename + 'getButtonValue': {(replaceRename, 'getButtonActiveList'): ['SCA_JoystickSensor']}, + + # Simple getters/setters + 'getSensors': {(replaceSimpleGetter, 'sensors'): ['SCA_IController']}, + 'getActuators': {(replaceSimpleGetter, 'actuators'): ['SCA_IController']}, 'enableViewport': {(replaceSimpleSetter, 'useViewport'): ['KX_Camera']}, 'getAction': {(replaceSimpleGetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, - 'getActuators': {(replaceKeyedGetter, 'actuators'): ['SCA_IController']}, 'getAxis': {(replaceSimpleGetter, 'axis'): ['SCA_JoystickSensor']}, - 'getAxisValue': {(replaceSimpleGetter, 'axisSingle'): ['SCA_JoystickSensor']}, + 'getAxisValue': {(replaceSimpleGetter, 'axisValues'): ['SCA_JoystickSensor']}, 'getBlendin': {(replaceSimpleGetter, 'blendIn'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'getBodies': {(replaceSimpleGetter, 'bodies'): ['KX_NetworkMessageSensor']}, 'getButton': {(replaceSimpleGetter, 'button'): ['SCA_JoystickSensor']}, - 'getButtonValue': {(replaceRename, 'getButtonActiveList'): ['SCA_JoystickSensor']}, 'getCamera': {(replaceSimpleGetter, 'camera'): ['KX_SceneActuator']}, 'getConeOrigin': {(replaceSimpleGetter, 'coneOrigin'): ['KX_RadarSensor']}, 'getConeTarget': {(replaceSimpleGetter, 'coneTarget'): ['KX_RadarSensor']}, @@ -325,8 +450,8 @@ attributeRenameDict = { 'getDistribution': {(replaceSimpleGetter, 'distribution'): ['SCA_RandomActuator']}, 'getDuration': {(replaceSimpleGetter, 'duration'): ['SCA_DelaySensor']}, 'getEnd': {(replaceSimpleGetter, 'frameEnd'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, + 'KX_IpoActuator', + 'BL_ActionActuator']}, 'getExecutePriority': {(replaceSimpleGetter, 'executePriority'): ['SCA_ILogicBrick']}, 'getFile': {(replaceSimpleGetter, 'fileName'): ['KX_GameActuator']}, 'getFilename': {(replaceSimpleGetter, 'fileName'): ['KX_SoundActuator']}, @@ -334,21 +459,20 @@ attributeRenameDict = { 'getFrame': {(replaceSimpleGetter, 'frame'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, 'getFrameMessageCount': {(replaceSimpleGetter, 'frameMessageCount'): ['KX_NetworkMessageSensor']}, 'getFrameProperty': {(replaceSimpleGetter, 'framePropName'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'getFrequency': {(replaceSimpleGetter, 'frequency'): ['SCA_ISensor']}, 'getGain': {(replaceSimpleGetter, 'volume'): ['KX_SoundActuator', 'KX_CDActuator']}, 'getHat': {(replaceSimpleGetter, 'hat'): ['SCA_JoystickSensor']}, 'getHeight': {(replaceSimpleGetter, 'height'): ['KX_CameraActuator']}, 'getHitNormal': {(replaceSimpleGetter, 'hitNormal'): ['KX_MouseFocusSensor', 'KX_RaySensor']}, 'getHitObject': {(replaceSimpleGetter, 'hitObject'): ['KX_MouseFocusSensor', - 'KX_RaySensor', - 'KX_TouchSensor']}, + 'KX_RaySensor', + 'KX_TouchSensor']}, 'getHitObjectList': {(replaceSimpleGetter, 'hitObjectList'): ['KX_TouchSensor']}, 'getHitPosition': {(replaceSimpleGetter, 'hitPosition'): ['KX_MouseFocusSensor', - 'KX_RaySensor']}, + 'KX_RaySensor']}, 'getHold1': {(replaceSimpleGetter, 'hold1'): ['SCA_KeyboardSensor']}, 'getHold2': {(replaceSimpleGetter, 'hold2'): ['SCA_KeyboardSensor']}, - 'getIndex': {(replaceSimpleGetter, 'index'): ['SCA_JoystickSensor']}, 'getInvert': {(replaceSimpleGetter, 'invert'): ['SCA_ISensor']}, 'getIpoAdd': {(replaceSimpleGetter, 'useIpoAdd'): ['KX_IpoActuator']}, 'getIpoAsForce': {(replaceSimpleGetter, 'useIpoAsForce'): ['KX_IpoActuator']}, @@ -359,16 +483,11 @@ attributeRenameDict = { 'getLooping': {(replaceSimpleGetter, 'looping'): ['KX_SoundActuator']}, 'getMass': {(replaceSimpleGetter, 'mass'): ['KX_GameObject']}, 'getMax': {(replaceSimpleGetter, 'max'): ['KX_CameraActuator']}, - 'getMesh': {(replaceSimpleGetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, 'getMin': {(replaceSimpleGetter, 'min'): ['KX_CameraActuator']}, 'getName': {(replaceSimpleGetter, 'name'): ['KX_Scene']}, 'getNumAxes': {(replaceSimpleGetter, 'numAxis'): ['SCA_JoystickSensor']}, 'getNumButtons': {(replaceSimpleGetter, 'numButtons'): ['SCA_JoystickSensor']}, 'getNumHats': {(replaceSimpleGetter, 'numHats'): ['SCA_JoystickSensor']}, - 'getObject': {(replaceSimpleGetter, 'object'): ['KX_SCA_AddObjectActuator', - 'KX_CameraActuator', - 'KX_TrackToActuator', - 'KX_ParentActuator']}, 'getObjectList': {(replaceSimpleGetter, 'objects'): ['KX_Scene']}, 'getOperation': {(replaceSimpleGetter, 'mode'): ['KX_SCA_DynamicActuator']}, 'getOrientation': {(replaceSimpleGetter, 'worldOrientation'): ['KX_GameObject']}, @@ -380,12 +499,13 @@ attributeRenameDict = { 'getPosition': {(replaceSimpleGetter, 'worldPosition'): ['KX_GameObject']}, 'getPressedKeys': {(replaceSimpleGetter, 'events'): ['SCA_KeyboardSensor']}, 'getPriority': {(replaceSimpleGetter, 'priority'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'getProjectionMatrix': {(replaceSimpleGetter, 'projection_matrix'): ['KX_Camera']}, 'getProperty': {(replaceSimpleGetter, 'propName'): ['SCA_PropertySensor', - 'SCA_RandomActuator']}, + 'SCA_RandomActuator', + 'SCA_PropertyActuator']}, 'getRayDirection': {(replaceSimpleGetter, 'rayDirection'): ['KX_MouseFocusSensor', - 'KX_RaySensor']}, + 'KX_RaySensor']}, 'getRaySource': {(replaceSimpleGetter, 'raySource'): ['KX_MouseFocusSensor']}, 'getRayTarget': {(replaceSimpleGetter, 'rayTarget'): ['KX_MouseFocusSensor']}, 'getRepeat': {(replaceSimpleGetter, 'repeat'): ['SCA_DelaySensor']}, @@ -393,11 +513,9 @@ attributeRenameDict = { 'getScene': {(replaceSimpleGetter, 'scene'): ['KX_SceneActuator']}, 'getScript': {(replaceSimpleGetter, 'script'): ['SCA_PythonController']}, 'getSeed': {(replaceSimpleGetter, 'seed'): ['SCA_RandomActuator']}, - 'getSensor': {(replaceKeyedGetter, 'sensors'): ['SCA_IController']}, - 'getSensors': {(replaceKeyedGetter, 'sensors'): ['SCA_IController']}, 'getStart': {(replaceSimpleGetter, 'frameStart'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, + 'KX_IpoActuator', + 'BL_ActionActuator']}, 'getState': {(replaceSimpleGetter, 'state'): ['SCA_IController', 'KX_GameObject']}, 'getSubject': {(replaceSimpleGetter, 'subject'): ['KX_NetworkMessageSensor']}, 'getSubjects': {(replaceSimpleGetter, 'subjects'): ['KX_NetworkMessageSensor']}, @@ -415,14 +533,11 @@ attributeRenameDict = { 'isConnected': {(replaceSimpleGetter, 'connected'): ['SCA_JoystickSensor']}, 'isPositive': {(replaceSimpleGetter, 'positive'): ['SCA_ISensor']}, 'isTriggered': {(replaceSimpleGetter, 'triggered'): ['SCA_ISensor']}, - 'set': {(replaceSimpleSetter, 'visibility'): ['KX_VisibilityActuator']}, - 'setAction': {(replaceSimpleSetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, 'setActuator': {(replaceSimpleSetter, 'actuator'): ['SCA_ActuatorSensor']}, - 'setAxis': {(replaceSimpleSetter, 'axis'): ['SCA_JoystickSensor']}, 'setBlendin': {(replaceSimpleSetter, 'blendIn'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'setBlendtime': {(replaceSimpleSetter, 'blendTime'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'setBodyType': {(replaceSimpleSetter, 'usePropBody'): ['KX_NetworkMessageActuator']}, 'setButton': {(replaceSimpleSetter, 'button'): ['SCA_JoystickSensor']}, 'setCamera': {(replaceSimpleSetter, 'camera'): ['KX_SceneActuator']}, @@ -430,22 +545,20 @@ attributeRenameDict = { 'setDelay': {(replaceSimpleSetter, 'delay'): ['SCA_DelaySensor']}, 'setDuration': {(replaceSimpleSetter, 'duration'): ['SCA_DelaySensor']}, 'setEnd': {(replaceSimpleSetter, 'frameEnd'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, + 'KX_IpoActuator', + 'BL_ActionActuator']}, 'setExecutePriority': {(replaceSimpleSetter, 'executePriority'): ['SCA_ILogicBrick']}, 'setFile': {(replaceSimpleSetter, 'fileName'): ['KX_GameActuator']}, 'setFilename': {(replaceSimpleSetter, 'fileName'): ['KX_SoundActuator']}, 'setForceIpoActsLocal': {(replaceSimpleSetter, 'useIpoLocal'): ['KX_IpoActuator']}, 'setFrame': {(replaceSimpleSetter, 'frame'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, 'setFrameProperty': {(replaceSimpleSetter, 'framePropName'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'setFrequency': {(replaceSimpleSetter, 'frequency'): ['SCA_ISensor']}, 'setGain': {(replaceSimpleSetter, 'volume'): ['KX_SoundActuator', 'KX_CDActuator']}, - 'setHat': {(replaceSimpleSetter, 'hat'): ['SCA_JoystickSensor']}, 'setHeight': {(replaceSimpleSetter, 'height'): ['KX_CameraActuator']}, 'setHold1': {(replaceSimpleSetter, 'hold1'): ['SCA_KeyboardSensor']}, 'setHold2': {(replaceSimpleSetter, 'hold2'): ['SCA_KeyboardSensor']}, - 'setIndex': {(replaceSimpleSetter, 'index'): ['SCA_JoystickSensor']}, 'setInvert': {(replaceSimpleSetter, 'invert'): ['SCA_ISensor']}, 'setIpoAdd': {(replaceSimpleSetter, 'useIpoAdd'): ['KX_IpoActuator']}, 'setIpoAsForce': {(replaceSimpleSetter, 'useIpoAsForce'): ['KX_IpoActuator']}, @@ -456,31 +569,22 @@ attributeRenameDict = { 'setMax': {(replaceSimpleSetter, 'max'): ['KX_CameraActuator']}, 'setMesh': {(replaceSimpleSetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, 'setMin': {(replaceSimpleSetter, 'min'): ['KX_CameraActuator']}, - 'setObject': {(replaceSimpleSetter, 'object'): ['KX_SCA_AddObjectActuator', - 'KX_CameraActuator', - 'KX_TrackToActuator', - 'KX_ParentActuator']}, - 'setOperation': {(replaceSimpleSetter, 'mode'): ['KX_SCA_DynamicActuator'], - (replaceSimpleSetter, 'operation'): ['KX_StateActuator']}, - 'setOrientation': {(replaceSimpleSetter, 'localOrientation'): ['KX_GameObject'], - (replaceSimpleSetter, 'orientation'): ['KX_SoundActuator']}, 'setPitch': {(replaceSimpleSetter, 'pitch'): ['KX_SoundActuator']}, - 'setPosition': {(replaceSimpleSetter, 'localPosition'): ['KX_GameObject'], - (replaceSimpleSetter, 'position'): ['KX_SoundActuator']}, 'setPriority': {(replaceSimpleSetter, 'priority'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, + 'BL_ActionActuator']}, 'setProjectionMatrix': {(replaceSimpleSetter, 'projection_matrix'): ['KX_Camera']}, 'setProperty': {(replaceSimpleSetter, 'propName'): ['KX_IpoActuator', - 'SCA_PropertySensor', - 'SCA_RandomActuator']}, + 'SCA_PropertySensor', + 'SCA_RandomActuator', + 'SCA_PropertyActuator']}, 'setRepeat': {(replaceSimpleSetter, 'repeat'): ['SCA_DelaySensor']}, 'setRollOffFactor': {(replaceSimpleSetter, 'rollOffFactor'): ['KX_SoundActuator']}, 'setScene': {(replaceSimpleSetter, 'scene'): ['KX_SceneActuator']}, 'setScript': {(replaceSimpleSetter, 'script'): ['SCA_PythonController']}, 'setSeed': {(replaceSimpleSetter, 'seed'): ['SCA_RandomActuator']}, 'setStart': {(replaceSimpleSetter, 'frameStart'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, + 'KX_IpoActuator', + 'BL_ActionActuator']}, 'setState': {(replaceSimpleSetter, 'state'): ['KX_GameObject']}, 'setSubject': {(replaceSimpleSetter, 'subject'): ['KX_NetworkMessageActuator']}, 'setSubjectFilterText': {(replaceSimpleSetter, 'subject'): ['KX_NetworkMessageSensor']}, @@ -493,8 +597,28 @@ attributeRenameDict = { 'setUsePosPulseMode': {(replaceSimpleSetter, 'usePosPulseMode'): ['SCA_ISensor']}, 'setUseRestart': {(replaceSimpleSetter, 'useRestart'): ['KX_SceneActuator']}, 'setValue': {(replaceSimpleSetter, 'value'): ['SCA_PropertySensor', 'SCA_PropertyActuator']}, - 'setVelocity': {(replaceSimpleSetter, 'velocity'): ['KX_SoundActuator']}, 'setXY': {(replaceSimpleSetter, 'useXY'): ['KX_CameraActuator']} + + # Unimplemented! + #'getLinearVelocity': {(replaceSimpleGetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, + #'setLinearVelocity': {(replaceSimpleSetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, + #'getAngularVelocity': {(replaceSimpleGetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, + #'setAngularVelocity': {(replaceSimpleSetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, + #'setAction': {(replaceSimpleSetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, + #'set': {(replaceSimpleSetter, 'visibility'): ['KX_VisibilityActuator']}, + #'getIndex': {(replaceSimpleGetter, 'index'): ['SCA_JoystickSensor']}, + #'getMesh': {(replaceSimpleGetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, + #'getObject': {(replaceSimpleGetter, 'object'): ['KX_SCA_AddObjectActuator', + # 'KX_CameraActuator', + # 'KX_TrackToActuator', + # 'KX_ParentActuator']}, + #'setIndex': {(replaceSimpleSetter, 'index'): ['SCA_JoystickSensor']}, + #'setObject': {(replaceSimpleSetter, 'object'): ['KX_SCA_AddObjectActuator', + # 'KX_CameraActuator', + # 'KX_TrackToActuator', + # 'KX_ParentActuator']}, + #'setOperation': {(replaceSimpleSetter, 'mode'): ['KX_SCA_DynamicActuator'], + # (replaceSimpleSetter, 'operation'): ['KX_StateActuator']}, } def convert248to249(lines, log = True, logErrors = True): @@ -629,26 +753,41 @@ def runAsTextPlugin(): from Blender import Window, sys, Draw import BPyTextPlugin, bpy - # Gets the active text object, there can be many in one blend file. - txt = bpy.data.texts.active - - # Silently return if the script has been run with no active text - if not txt: - return + message = ("Convert Game Engine script from 4.48 API to 2.49 API%t|" + "Run on active script only%x1|" + "Run on ALL text buffers%x2") + convertAllBuffers = Draw.PupMenu(message) == 2 Window.WaitCursor(1) try: - lines = txt.asLines() - for i in range(0, len(lines)): - if not lines[i].endswith('\n'): - lines[i] = lines[i] + '\n' + nconverted = 0 + nerrors = 0 - nconverted, nerrors = convert248to249(lines) + if convertAllBuffers: + texts = bpy.data.texts + else: + if not bpy.data.texts.active: + Draw.PupMenu("No active buffer.") + return + texts = [bpy.data.texts.active] - Blender.SaveUndoState('Convert GE 249') - txt.clear() - for line in lines: - txt.write(line) + Blender.SaveUndoState('Convert BGE 2.49') + + for txt in texts: + lines = txt.asLines() + for i in range(0, len(lines)): + if not lines[i].endswith('\n'): + lines[i] = lines[i] + '\n' + + nc, ne = convert248to249(lines) + nconverted = nconverted + nc + nerrors = nerrors + ne + txt.clear() + for line in lines: + txt.write(line) + + finally: + Window.WaitCursor(0) message = "Converted %d attributes." % nconverted if nerrors == 1: @@ -657,9 +796,6 @@ def runAsTextPlugin(): message = message + " There were %d errors (see console)." % nerrors message = message + "|Please review all the changes." Draw.PupMenu(message) - - finally: - Window.WaitCursor(0) def main(): try: diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 3f9b627247f..a7ad29d5cfa 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -2561,6 +2561,7 @@ class KX_NetworkMessageActuator(SCA_IActuator): @ivar usePropBody: Send a property instead of a regular body message. @type usePropBody: boolean """ +#{Deprecated def setToPropName(name): """ Messages will only be sent to objects with the given property name. @@ -2592,6 +2593,7 @@ class KX_NetworkMessageActuator(SCA_IActuator): @param body: if the body type is True, this is the name of the property to send. if the body type is False, this is the text to send. """ +#} class KX_NetworkMessageSensor(SCA_ISensor): """ @@ -2609,8 +2611,7 @@ class KX_NetworkMessageSensor(SCA_ISensor): @ivar bodies: The list of message bodies received. (Read-only) @type bodies: list of strings """ - - +#{ Deprecated def setSubjectFilterText(subject): """ Change the message subject text that this sensor is listening to. @@ -2648,6 +2649,7 @@ class KX_NetworkMessageSensor(SCA_ISensor): @deprecated: Use the L{subjects} attribute instead. @rtype: list """ +#} class KX_ObjectActuator(SCA_IActuator): """ @@ -3431,8 +3433,7 @@ class KX_RadarSensor(KX_NearSensor): KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z """ - - +#{Deprecated #--The following methods are deprecated, please use properties instead. def getConeOrigin(): """ @@ -3450,6 +3451,7 @@ class KX_RadarSensor(KX_NearSensor): @deprecated: Use the L{coneTarget} property. @rtype: list [x, y, z] """ +#} def getConeHeight(): """ @@ -3521,7 +3523,7 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): @type object: KX_GameObject or None @ivar objectLastCreated: the last added object from this actuator (read-only). @type objectLastCreated: KX_GameObject or None - @ivar time: the lifetime of added objects, in frames. + @ivar time: the lifetime of added objects, in frames. Set to 0 to disable automatic deletion. @type time: integer @ivar linearVelocity: the initial linear velocity of added objects. @type linearVelocity: list [vx, vy, vz] @@ -3535,6 +3537,7 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): C{ERROR: GameObject I{OBName} has a AddObjectActuator I{ActuatorName} without object (in 'nonactive' layer)} """ +#{Deprecated def setObject(object): """ Sets the game object to add. @@ -3622,6 +3625,7 @@ class KX_SCA_AddObjectActuator(SCA_IActuator): @rtype: L{KX_GameObject} @return: A L{KX_GameObject} or None if no object has been created. """ +#} def instantAddObject(): """ Returns the last object created by this actuator. The object can then be accessed from L{objectLastCreated}. @@ -3920,32 +3924,31 @@ class KX_SoundActuator(SCA_IActuator): the actuator to be activated - they act instantly provided that the actuator has been activated once at least. - @ivar fileName: Sets the filename of the sound this actuator plays. + @ivar fileName: The filename of the sound this actuator plays. @type fileName: string - @ivar volume: Sets the volume (gain) of the sound. + @ivar volume: The volume (gain) of the sound. @type volume: float - @ivar pitch: Sets the pitch of the sound. + @ivar pitch: The pitch of the sound. @type pitch: float - @ivar rollOffFactor: Sets the roll off factor. Rolloff defines the rate of attenuation as the sound gets further away. + @ivar rollOffFactor: The roll off factor. Rolloff defines the rate of attenuation as the sound gets further away. @type rollOffFactor: float - @ivar looping: Sets the loop mode of the actuator. + @ivar looping: The loop mode of the actuator. @type looping: integer - @ivar position: Sets the position of the sound. + @ivar position: The position of the sound as a list: [x, y, z]. @type position: float array - @ivar velocity: Sets the speed of the sound; The speed of the sound alter the pitch. + @ivar velocity: The velocity of the emitter as a list: [x, y, z]. The relative velocity to the observer determines the pitch. List of 3 floats: [x, y, z]. @type velocity: float array - @ivar orientation: Sets the orientation of the sound. When setting the orientation you can - also use quaternion [float,float,float,float] or euler angles [float,float,float] + @ivar orientation: The orientation of the sound. When setting the orientation you can also use quaternion [float,float,float,float] or euler angles [float,float,float] @type orientation: 3x3 matrix [[float]] - @ivar mode: Sets the operation mode of the actuator. You can use one of the following constant: + @ivar mode: The operation mode of the actuator. You can use one of the following constants: - KX_SOUNDACT_PLAYSTOP (1) - KX_SOUNDACT_PLAYEND (2) - KX_SOUNDACT_LOOPSTOP (3) @@ -4057,7 +4060,7 @@ class KX_SoundActuator(SCA_IActuator): """ Sets the position this sound will come from. - @deprecated: Use the L{localPosition} attribute instead. + @deprecated: Use the L{position} attribute instead. @type x: float @param x: The x coordinate of the sound. @type y: float @@ -4605,6 +4608,7 @@ class SCA_ActuatorSensor(SCA_ISensor): @ivar actuator: the name of the actuator that the sensor is monitoring. @type actuator: string """ +#{Deprecated def getActuator(): """ Return the Actuator with which the sensor operates. @@ -4621,6 +4625,7 @@ class SCA_ActuatorSensor(SCA_ISensor): @param name: actuator name @type name: string """ +#} class SCA_AlwaysSensor(SCA_ISensor): """ @@ -4649,6 +4654,7 @@ class SCA_DelaySensor(SCA_ISensor): @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. @type repeat: integer """ +#{Deprecated def setDelay(delay): """ Set the initial delay before the positive trigger. @@ -4695,6 +4701,7 @@ class SCA_DelaySensor(SCA_ISensor): @deprecated: Use the L{repeat} attribute instead. @rtype: KX_TRUE or KX_FALSE """ +#} class SCA_JoystickSensor(SCA_ISensor): """ @@ -4748,6 +4755,7 @@ class SCA_JoystickSensor(SCA_ISensor): @type buttonIndex: integer @rtype: bool """ +#{Deprecated def getIndex(): """ Returns the joystick index to use (from 1 to 8). @@ -4786,7 +4794,7 @@ class SCA_JoystickSensor(SCA_ISensor): """ Returns the state of the joysticks axis. See differs to L{getAxis()} returning the current state of the joystick. - @deprecated: Use the L{axisSingle} attribute instead. + @deprecated: Use the L{axisValues} attribute instead. @rtype: list @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. @@ -4876,6 +4884,7 @@ class SCA_JoystickSensor(SCA_ISensor): @deprecated: Use the L{connected} attribute instead. @rtype: bool """ +#} class SCA_KeyboardSensor(SCA_ISensor): """ @@ -4917,7 +4926,7 @@ class SCA_KeyboardSensor(SCA_ISensor): @param keycode: The code that represents the key you want to get the state of """ - #--The following methods are DEPRECATED-- +#{Deprecated def getKey(): """ Returns the key code this sensor is looking for. @@ -4981,6 +4990,7 @@ class SCA_KeyboardSensor(SCA_ISensor): @deprecated: Use the L{events} attribute instead. @rtype: list of key status. [[keycode, status]] """ +#} class SCA_NANDController(SCA_IController): """ @@ -5023,7 +5033,7 @@ class SCA_PropertyActuator(SCA_IActuator): If there is no property of this name, the call is ignored. - @deprecated: Use the L{property} attribute instead. + @deprecated: Use the L{propName} attribute instead. @type prop: string @param prop: The name of the property to set. """ @@ -5031,7 +5041,7 @@ class SCA_PropertyActuator(SCA_IActuator): """ Returns the name of the property on which to operate. - @deprecated: Use the L{property} attribute instead. + @deprecated: Use the L{propName} attribute instead. @rtype: string """ def setValue(value): @@ -5132,7 +5142,7 @@ class SCA_PythonController(SCA_IController): Properties: @ivar script: the Python script this controller executes - @type script: string, read-only + @type script: string @group Deprecated: getScript, setScript """ From 3820e4f3db2ca23f7eeed7c3121cc41b0e12db25 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 23 May 2009 04:56:37 +0000 Subject: [PATCH 299/444] BGE PyController module reloading didnt check that the base of the function was a module (could be a class). --- source/gameengine/GameLogic/SCA_PythonController.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 8140dbd53db..52f6bece132 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -336,7 +336,7 @@ bool SCA_PythonController::Import() PyObject *base= mod; for(unsigned int i=1; i < py_function_path.size(); i++) { - if(m_debug) { + if(m_debug && PyModule_Check(base)) { /* base could be a class */ Py_DECREF(base); /* getting a new one so dont hold a ref to the old one */ base= PyImport_ReloadModule(base); if (base==NULL) { diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index bb5e0875402..2c74c88dc14 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1452,7 +1452,7 @@ void KX_Scene::LogicEndFrame() { m_logicmgr->EndFrame(); int numobj = m_euthanasyobjects->GetCount(); - int i; + KX_GameObject* obj; while ((numobj = m_euthanasyobjects->GetCount()) > 0) From 443df708e22e772965c098a93842083dc20cfbac Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sat, 23 May 2009 07:37:02 +0000 Subject: [PATCH 300/444] == Sequencer == This fixes: [#18373] WAV with IPO CURVE: Clicking in playback by adding linear interpolation between frames. (Old IPOs were only calculated once per frame which will lead to clicking on steep curves) --- source/blender/src/seqaudio.c | 92 ++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 17 deletions(-) diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index 078750ca118..92264605380 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -101,6 +101,9 @@ static Scene * audio_scene = 0; /* we can't use G.scene, since called while we have G.scene changed!) */ +#define AFRA2TIME(a) ((((double) audio_scene->r.frs_sec_base) * (a)) / audio_scene->r.frs_sec) +#define ATIME2FRA(a) ((((double) audio_scene->r.frs_sec) * (a)) / audio_scene->r.frs_sec_base) + ///// // /* local protos ------------------- */ @@ -235,23 +238,27 @@ void audiostream_fill(uint8_t *mixdown, int len) } -static void audio_levels(uint8_t *buf, int len, float db, float facf, float pan) +static void audio_levels(uint8_t *buf, int len, float db, + float facf_start, float facf_end, float pan) { int i; + double m = (facf_end - facf_start) / len; float facl, facr, fac; signed short *sample; if (pan>=0) { facr = 1.0; facl = 1.0-pan; } else { facr = pan+1.0; facl = 1.0; } - fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0)) / facf; - facl /= fac; - facr /= fac; - + fac = pow(10.0, ((-(db+audio_scene->audio.main))/20.0)); + for (i=0; istart) + + ((double) + seq->anim_startofs)) + * ((float)audio_scene + ->audio.mixrate) + * 4 )); +} + +static int curpos2fra(Sequence * seq, int curpos) +{ + return ((int) floor( + ATIME2FRA( + ((double) curpos) / 4 + /audio_scene->audio.mixrate))) + - seq->anim_startofs + seq->start; +} + +static void do_audio_seq_ipo(Sequence * seq, int len, float * facf_start, + float * facf_end) +{ + int cfra_start = curpos2fra(seq, seq->curpos); + int cfra_end = cfra_start + 1; + int ipo_curpos_start = fra2curpos(seq, curpos2fra(seq, seq->curpos)); + int ipo_curpos_end = fra2curpos(seq, cfra_end); + double ipo_facf_start; + double ipo_facf_end; + double m; + + do_seq_ipo(seq, cfra_start); + ipo_facf_start = seq->facf0; + + do_seq_ipo(seq, cfra_end); + ipo_facf_end = seq->facf0; + + m = (ipo_facf_end- ipo_facf_start)/(ipo_curpos_end - ipo_curpos_start); + + *facf_start = ipo_facf_start + (seq->curpos - ipo_curpos_start) * m; + *facf_end = ipo_facf_start + (seq->curpos + len-ipo_curpos_start) * m; +} + +#endif + #ifndef DISABLE_SDL static void audio_fill_ram_sound(Sequence *seq, void * mixdown, uint8_t * sstream, int len, @@ -305,7 +359,8 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown, { uint8_t* cvtbuf; bSound* sound; - float facf; + float facf_start; + float facf_end; sound = seq->sound; audio_makestream(sound); @@ -313,14 +368,15 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown, (seq->startdisp <= cfra) && ((seq->enddisp) > cfra)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, cfra); - facf = seq->facf0; + do_audio_seq_ipo(seq, len, &facf_start, &facf_end); } else { - facf = 1.0; + facf_start = 1.0; + facf_end = 1.0; } cvtbuf = malloc(len); memcpy(cvtbuf, ((uint8_t*)sound->stream)+(seq->curpos & (~3)), len); - audio_levels(cvtbuf, len, seq->level, facf, seq->pan); + audio_levels(cvtbuf, len, seq->level, facf_start, facf_end, + seq->pan); if (!mixdown) { SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME); } else { @@ -338,16 +394,17 @@ static void audio_fill_hd_sound(Sequence *seq, int len, int cfra) { uint8_t* cvtbuf; - float facf; + float facf_start; + float facf_end; if ((seq->curpos >= 0) && (seq->startdisp <= cfra) && ((seq->enddisp) > cfra)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq, cfra); - facf = seq->facf0; + do_audio_seq_ipo(seq, len, &facf_start, &facf_end); } else { - facf = 1.0; + facf_start = 1.0; + facf_end = 1.0; } cvtbuf = malloc(len); @@ -356,7 +413,8 @@ static void audio_fill_hd_sound(Sequence *seq, audio_scene->audio.mixrate, 2, len / 4); - audio_levels(cvtbuf, len, seq->level, facf, seq->pan); + audio_levels(cvtbuf, len, seq->level, facf_start, facf_end, + seq->pan); if (!mixdown) { SDL_MixAudio(sstream, cvtbuf, len, SDL_MIX_MAXVOLUME); From 4e3248fb91a5abd8d6bed07f304579b554c85194 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 23 May 2009 14:21:11 +0000 Subject: [PATCH 301/444] FIX memleak in mmap(). --- intern/guardedalloc/intern/mmap_win.c | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c index 5c59640200f..979e77ebbed 100644 --- a/intern/guardedalloc/intern/mmap_win.c +++ b/intern/guardedalloc/intern/mmap_win.c @@ -162,6 +162,7 @@ intptr_t munmap(void *ptr, intptr_t size) CloseHandle( mm->maphandle ); CloseHandle( mm->fhandle); mmap_remlink(mmapbase, mm); + free(mm); return 0; } From 6d8d7cd768f292a7fbbcecaf5f1cbc3090973f12 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 23 May 2009 14:40:36 +0000 Subject: [PATCH 302/444] BGE: Random sensor will produce true random sequence of events when seed is set to 0 in the GUI (the actual seed value is stored in the sensor seed attribute). Positive values will use fixed pseudo random sequence. --- source/gameengine/Converter/KX_ConvertSensors.cpp | 5 +++++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 5 +++++ source/gameengine/Ketsji/KX_KetsjiEngine.h | 1 + 3 files changed, 11 insertions(+) diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 07b0abae6df..37631a0523d 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -682,6 +682,11 @@ void BL_ConvertSensors(struct Object* blenderobject, if (eventmgr) { int randomSeed = blenderrndsensor->seed; + if (randomSeed == 0) + { + randomSeed = (int)(kxengine->GetRealTime()*100000.0); + randomSeed ^= (intptr_t)blenderrndsensor; + } gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed); } } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 983059d0c70..347634b4599 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1770,6 +1770,11 @@ double KX_KetsjiEngine::GetClockTime(void) const return m_clockTime; } +double KX_KetsjiEngine::GetRealTime(void) const +{ + return m_kxsystem->GetTimeInSeconds(); +} + void KX_KetsjiEngine::SetAnimFrameRate(double framerate) { m_anim_framerate = framerate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 5c14c63dd04..6fa379e551a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -271,6 +271,7 @@ public: */ double GetClockTime(void) const; + double GetRealTime(void) const; /** * Returns the difference between the local time of the scene (when it * was running and not suspended) and the "curtime" From 5441323dca30c169d1ecb726d26e8cb4c5f4994d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 23 May 2009 14:46:43 +0000 Subject: [PATCH 303/444] BGE: fix memleaks. SCA_RandomActuator: The random generator was shared between replicas and not deleted. Added ref counting between replicas to allow deletion at the end. KX_Camera: The scenegraph node was not deleted for temporary cameras (ImageMirror and shadow), causing 500 bytes leak per frame and per shadow light. KX_GameActuator: Global dictionary buffer was not deleted after saving. KX_MotionState: The motion state for compound child was not deleted KX_ReplaceMeshActuator: The mesh was unnecessarily converted for each actuator and not deleted, causing large memleak. After these fix, YoFrankie runs without memleak. --- .../Converter/BL_BlenderDataConversion.cpp | 12 +++++------- .../Converter/KX_BlenderSceneConverter.cpp | 6 +++--- .../Converter/KX_BlenderSceneConverter.h | 2 +- .../GameLogic/SCA_RandomNumberGenerator.cpp | 1 + .../GameLogic/SCA_RandomNumberGenerator.h | 13 +++++++++++++ .../gameengine/GameLogic/SCA_RandomSensor.cpp | 10 +++++++--- source/gameengine/GameLogic/SCA_RandomSensor.h | 1 + source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 8 ++++---- source/gameengine/Ketsji/KX_BlenderMaterial.h | 4 ++-- source/gameengine/Ketsji/KX_Camera.cpp | 17 ++++++++++++++++- source/gameengine/Ketsji/KX_Camera.h | 8 +++++++- .../Ketsji/KX_ConvertPhysicsObjects.cpp | 2 ++ source/gameengine/Ketsji/KX_GameActuator.cpp | 2 ++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 2 +- source/gameengine/Ketsji/KX_PolygonMaterial.cpp | 2 +- .../Rasterizer/RAS_IPolygonMaterial.cpp | 14 +++++++------- .../Rasterizer/RAS_IPolygonMaterial.h | 6 +++--- source/gameengine/Rasterizer/RAS_MeshObject.cpp | 10 +++++----- source/gameengine/Rasterizer/RAS_MeshObject.h | 4 ++-- source/gameengine/VideoTexture/ImageRender.cpp | 4 ++-- 20 files changed, 85 insertions(+), 43 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index f3024197a8a..06a4da4fce0 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -729,6 +729,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bool skinMesh = false; int lightlayer = blenderobj->lay; + if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL) + return meshobj; // Get DerivedMesh data DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj); @@ -1043,7 +1045,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* // pre calculate texture generation for(list::iterator mit = meshobj->GetFirstMaterial(); mit != meshobj->GetLastMaterial(); ++ mit) { - mit->m_bucket->GetPolyMaterial()->OnConstruction(); + mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer); } if (layers) @@ -1057,6 +1059,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* delete kx_blmat; if (kx_polymat) delete kx_polymat; + converter->RegisterGameMesh(meshobj, mesh); return meshobj; } @@ -1712,14 +1715,9 @@ static KX_GameObject *gameobject_from_blenderobject( case OB_MESH: { Mesh* mesh = static_cast(ob->data); - RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay); float center[3], extents[3]; float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents); - - if (!meshobj) { - meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter); - converter->RegisterGameMesh(meshobj, mesh); - } + RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter); // needed for python scripting kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index c9ac7a23625..646e569a27e 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -550,12 +550,12 @@ void KX_BlenderSceneConverter::RegisterGameMesh( RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh( - struct Mesh *for_blendermesh, - unsigned int onlayer) + struct Mesh *for_blendermesh/*, + unsigned int onlayer*/) { RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)]; - if (meshp && onlayer==(*meshp)->GetLightLayer()) { + if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) { return *meshp; } else { return NULL; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index 2317e952a0a..f7c1a506457 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -115,7 +115,7 @@ public: struct Object *FindBlenderObject(KX_GameObject *for_gameobject); void RegisterGameMesh(RAS_MeshObject *gamemesh, struct Mesh *for_blendermesh); - RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh, unsigned int onlayer); + RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/); // void RegisterSumoShape(DT_ShapeHandle shape, RAS_MeshObject *for_gamemesh); // DT_ShapeHandle FindSumoShape(RAS_MeshObject *for_gamemesh); diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp index 06b5cca6ce9..0267cc8ebbf 100644 --- a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp @@ -59,6 +59,7 @@ SCA_RandomNumberGenerator::SCA_RandomNumberGenerator(long seed) { // int mti = N + 1; /*unused*/ m_seed = seed; + m_refcount = 1; SetStartVector(); } diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h index b9311d31af6..842a0331752 100644 --- a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h +++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h @@ -36,6 +36,9 @@ class SCA_RandomNumberGenerator { + /* reference counted for memleak */ + int m_refcount; + /** base seed */ long m_seed; @@ -56,6 +59,16 @@ class SCA_RandomNumberGenerator { float DrawFloat(); long GetSeed(); void SetSeed(long newseed); + SCA_RandomNumberGenerator* AddRef() + { + ++m_refcount; + return this; + } + void Release() + { + if (--m_refcount == 0) + delete this; + } }; #endif /* __KX_RANDOMNUMBERGENERATOR */ diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 3c04173d10e..d5cbeef01ae 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -50,7 +50,6 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, PyTypeObject* T) : SCA_ISensor(gameobj,eventmgr, T) { - // m_basegenerator is never deleted => memory leak m_basegenerator = new SCA_RandomNumberGenerator(startseed); Init(); } @@ -59,7 +58,7 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, SCA_RandomSensor::~SCA_RandomSensor() { - /* Nothing to be done here. */ + m_basegenerator->Release(); } void SCA_RandomSensor::Init() @@ -74,13 +73,18 @@ void SCA_RandomSensor::Init() CValue* SCA_RandomSensor::GetReplica() { CValue* replica = new SCA_RandomSensor(*this); - // replication copies m_basegenerator pointer => share same generator // this will copy properties and so on... replica->ProcessReplica(); return replica; } +void SCA_RandomSensor::ProcessReplica() +{ + SCA_ISensor::ProcessReplica(); + // increment reference count so that we can release the generator at this end + m_basegenerator->AddRef(); +} bool SCA_RandomSensor::IsPositiveTrigger() diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 27b41841f0b..b2bf2440966 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -52,6 +52,7 @@ public: PyTypeObject* T=&Type); virtual ~SCA_RandomSensor(); virtual CValue* GetReplica(); + virtual void ProcessReplica(); virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 3b8917efe90..f1543d752f1 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -158,14 +158,14 @@ void KX_BlenderMaterial::ReleaseMaterial() mBlenderShader->ReloadMaterial(); } -void KX_BlenderMaterial::OnConstruction() +void KX_BlenderMaterial::OnConstruction(int layer) { if (mConstructed) // when material are reused between objects return; if(mMaterial->glslmat) - SetBlenderGLSLShader(); + SetBlenderGLSLShader(layer); // for each unique material... int i; @@ -902,10 +902,10 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") } -void KX_BlenderMaterial::SetBlenderGLSLShader(void) +void KX_BlenderMaterial::SetBlenderGLSLShader(int layer) { if(!mBlenderShader) - mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, m_lightlayer); + mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer); if(!mBlenderShader->Ok()) { delete mBlenderShader; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 52019ed2248..b29f2df98db 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -97,7 +97,7 @@ public: // -------------------------------- // pre calculate to avoid pops/lag at startup - virtual void OnConstruction( ); + virtual void OnConstruction(int layer); static void EndFrame(); @@ -112,7 +112,7 @@ private: bool mModified; bool mConstructed; // if false, don't clean on exit - void SetBlenderGLSLShader(); + void SetBlenderGLSLShader(int layer); void ActivatGLMaterials( RAS_IRasterizer* rasty )const; void ActivateTexGen( RAS_IRasterizer *ras ) const; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 4bef4936813..144ff4ac883 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -42,6 +42,7 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, SG_Callbacks callbacks, const RAS_CameraData& camdata, bool frustum_culling, + bool delete_node, PyTypeObject *T) : KX_GameObject(sgReplicationInfo,callbacks,T), @@ -50,7 +51,8 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, m_normalized(false), m_frustum_culling(frustum_culling), m_set_projection_matrix(false), - m_set_frustum_center(false) + m_set_frustum_center(false), + m_delete_node(delete_node) { // setting a name would be nice... m_name = "cam"; @@ -64,6 +66,12 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, KX_Camera::~KX_Camera() { + if (m_delete_node && m_pSGNode) + { + // for shadow camera, avoids memleak + delete m_pSGNode; + m_pSGNode = NULL; + } } @@ -77,6 +85,13 @@ CValue* KX_Camera::GetReplica() return replica; } +void KX_Camera::ProcessReplica() +{ + KX_GameObject::ProcessReplica(); + // replicated camera are always registered in the scene + m_delete_node = false; +} + MT_Transform KX_Camera::GetWorldToCamera() const { MT_Transform camtrans; diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 2ec60be0404..aef21cd91e4 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -112,6 +112,11 @@ protected: MT_Scalar m_frustum_radius; bool m_set_frustum_center; + /** + * whether the camera should delete the node itself (only for shadow camera) + */ + bool m_delete_node; + /** * Extracts the camera clip frames from the projection and world-to-camera matrices. */ @@ -138,7 +143,7 @@ public: enum { INSIDE, INTERSECT, OUTSIDE } ; - KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, PyTypeObject *T = &Type); + KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false, PyTypeObject *T = &Type); virtual ~KX_Camera(); /** @@ -149,6 +154,7 @@ public: virtual CValue* GetReplica( ); + virtual void ProcessReplica(); MT_Transform GetWorldToCamera() const; MT_Transform GetCameraToWorld() const; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 406339586cc..76642649afc 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -980,6 +980,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, compoundShape->calculateLocalInertia(mass,localInertia); rigidbody->setMassProps(mass,localInertia); } + // delete motionstate as it's not used + delete motionstate; return; } diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 7c18b03906e..28bf12f5e87 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -149,6 +149,8 @@ bool KX_GameActuator::Update() } else { printf("Warning: could not create marshal buffer\n"); } + if (marshal_buffer) + delete [] marshal_buffer; } break; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 347634b4599..b30b79e7f23 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1142,7 +1142,7 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) { /* make temporary camera */ RAS_CameraData camdata = RAS_CameraData(); - KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false); + KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, true, true); cam->SetName("__shadow__cam__"); MT_Transform camtrans; diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 98aad3943fe..506c167a905 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -220,7 +220,7 @@ PyAttributeDef KX_PolygonMaterial::Attributes[] = { KX_PYATTRIBUTE_INT_RW("tilexrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tilexrep), KX_PYATTRIBUTE_INT_RW("tileyrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tileyrep), KX_PYATTRIBUTE_INT_RW("drawingmode", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_drawingmode), - KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer), + //KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer), KX_PYATTRIBUTE_BOOL_RW("transparent", KX_PolygonMaterial, m_alpha), KX_PYATTRIBUTE_BOOL_RW("zsort", KX_PolygonMaterial, m_zsort), diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index f2fd96d63e9..6af00d63c2d 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -59,7 +59,7 @@ void RAS_IPolyMaterial::Initialize( m_transp = transp; m_alpha = alpha; m_zsort = zsort; - m_lightlayer = lightlayer; + //m_lightlayer = lightlayer; m_polymatid = m_newpolymatid++; m_flag = 0; m_multimode = 0; @@ -80,7 +80,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial() m_transp(0), m_alpha(false), m_zsort(false), - m_lightlayer(0), + //m_lightlayer(0), m_polymatid(0), m_flag(0), m_multimode(0) @@ -112,7 +112,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, m_transp(transp), m_alpha(alpha), m_zsort(zsort), - m_lightlayer(lightlayer), + //m_lightlayer(lightlayer), m_polymatid(m_newpolymatid++), m_flag(0), m_multimode(0) @@ -172,10 +172,10 @@ bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const return m_polymatid < rhs.m_polymatid; } -int RAS_IPolyMaterial::GetLightLayer() const -{ - return m_lightlayer; -} +//int RAS_IPolyMaterial::GetLightLayer() const +//{ +// return m_lightlayer; +//} bool RAS_IPolyMaterial::IsAlpha() const { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index decd93c3d13..e19db35ccb5 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -73,7 +73,7 @@ protected: int m_transp; bool m_alpha; bool m_zsort; - int m_lightlayer; + //int m_lightlayer; int m_materialindex; unsigned int m_polymatid; @@ -147,7 +147,7 @@ public: virtual bool Equals(const RAS_IPolyMaterial& lhs) const; bool Less(const RAS_IPolyMaterial& rhs) const; - int GetLightLayer() const; + //int GetLightLayer() const; bool IsAlpha() const; bool IsZSort() const; unsigned int hash() const; @@ -167,7 +167,7 @@ public: /* * PreCalculate texture gen */ - virtual void OnConstruction(){} + virtual void OnConstruction(int layer){} }; inline bool operator ==( const RAS_IPolyMaterial & rhs,const RAS_IPolyMaterial & lhs) diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index edd7615efd4..1cb394aaff3 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -91,7 +91,7 @@ struct RAS_MeshObject::fronttoback STR_String RAS_MeshObject::s_emptyname = ""; RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer) - : m_lightlayer(lightlayer), + : //m_lightlayer(lightlayer), m_bModified(true), m_bMeshModified(true), m_mesh(mesh), @@ -112,10 +112,10 @@ bool RAS_MeshObject::MeshModified() return m_bMeshModified; } -unsigned int RAS_MeshObject::GetLightLayer() -{ - return m_lightlayer; -} +//unsigned int RAS_MeshObject::GetLightLayer() +//{ +// return m_lightlayer; +//} diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index fbc3c549a7a..0a16c7fa0f6 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -54,7 +54,7 @@ class RAS_MeshObject { private: unsigned int m_debugcolor; - int m_lightlayer; + //int m_lightlayer; bool m_bModified; bool m_bMeshModified; @@ -94,7 +94,7 @@ public: list::iterator GetFirstMaterial(); list::iterator GetLastMaterial(); - unsigned int GetLightLayer(); + //unsigned int GetLightLayer(); /* name */ void SetName(const char *name); diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index db4461325d8..7ceb9e58c7a 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -561,8 +561,8 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj float yaxis[3] = {0.f, 1.f, 0.f}; float mirrorMat[3][3]; float left, right, top, bottom, back; - - m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata); + // make sure this camera will delete its node + m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata, true, true); m_camera->SetName("__mirror__cam__"); // don't add the camera to the scene object list, it doesn't need to be accessible m_owncamera = true; From 2de8f6e328e90ac5287187cee16e159411075956 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sat, 23 May 2009 19:36:11 +0000 Subject: [PATCH 304/444] == Sequencer == Fix for the fix: SDL_PauseAudio() doesn't really wait for callback to finish which can lead to random segfaults if we set audio_scene to 0 afterwards. So we don't do that. --- source/blender/src/seqaudio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index 92264605380..fd70cbe1f08 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -715,7 +715,6 @@ void audiostream_stop(void) #ifndef DISABLE_SDL SDL_PauseAudio(1); audio_playing=0; - audio_scene=0; #endif } From a96ce9453f2a8d39e238d20c1c4dec9fe5becfb5 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 23 May 2009 20:02:12 +0000 Subject: [PATCH 305/444] Minor fixes in Bullet/constraint solving Should make generic 6DOF constraint more useable, and rigid body stacking more stable (warmstarting was accidently switched off) If time allows, a few more minor last-minute 2.49 fixes might follow. Check out http://bulletphysics.com/constraintsTutorial.blend --- .../btConeTwistConstraint.cpp | 60 ++++++++++----- .../ConstraintSolver/btConeTwistConstraint.h | 29 ++++++- .../btGeneric6DofConstraint.cpp | 66 ++++++++-------- .../btGeneric6DofConstraint.h | 1 + .../btSequentialImpulseConstraintSolver.cpp | 2 +- .../ConstraintSolver/btSliderConstraint.cpp | 76 +++++++++++-------- .../ConstraintSolver/btSliderConstraint.h | 11 +-- extern/bullet2/src/LinearMath/btScalar.h | 4 + source/blender/src/buttons_object.c | 5 +- 9 files changed, 162 insertions(+), 92 deletions(-) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp index 29c8496c36f..50a79451f5d 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp @@ -22,12 +22,13 @@ Written by: Marcus Hennix #include "LinearMath/btMinMax.h" #include -//----------------------------------------------------------------------------- + +//#define CONETWIST_USE_OBSOLETE_SOLVER true #define CONETWIST_USE_OBSOLETE_SOLVER false #define CONETWIST_DEF_FIX_THRESH btScalar(.05f) -//----------------------------------------------------------------------------- + btConeTwistConstraint::btConeTwistConstraint() :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE), @@ -63,13 +64,13 @@ void btConeTwistConstraint::init() m_bMotorEnabled = false; m_maxMotorImpulse = btScalar(-1); - setLimit(btScalar(1e30), btScalar(1e30), btScalar(1e30)); + setLimit(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); m_damping = btScalar(0.01); m_fixThresh = CONETWIST_DEF_FIX_THRESH; } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) { @@ -99,9 +100,9 @@ void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) info->nub--; } } -} // btConeTwistConstraint::getInfo1() +} -//----------------------------------------------------------------------------- + void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) { @@ -230,7 +231,7 @@ void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) } } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::buildJacobian() { @@ -239,6 +240,7 @@ void btConeTwistConstraint::buildJacobian() m_appliedImpulse = btScalar(0.); m_accTwistLimitImpulse = btScalar(0.); m_accSwingLimitImpulse = btScalar(0.); + m_accMotorImpulse = btVector3(0.,0.,0.); if (!m_angularOnly) { @@ -277,7 +279,7 @@ void btConeTwistConstraint::buildJacobian() } } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) { @@ -406,10 +408,10 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver } } - else // no motor: do a little damping + else if (m_damping > SIMD_EPSILON) // no motor: do a little damping { - const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); - const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); + btVector3 angVelA; bodyA.getAngularVelocity(angVelA); + btVector3 angVelB; bodyB.getAngularVelocity(angVelB); btVector3 relVel = angVelB - angVelA; if (relVel.length2() > SIMD_EPSILON) { @@ -490,7 +492,7 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::updateRHS(btScalar timeStep) { @@ -498,7 +500,7 @@ void btConeTwistConstraint::updateRHS(btScalar timeStep) } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::calcAngleInfo() { @@ -584,12 +586,12 @@ void btConeTwistConstraint::calcAngleInfo() m_twistAxis.normalize(); } } -} // btConeTwistConstraint::calcAngleInfo() +} static btVector3 vTwist(1,0,0); // twist axis in constraint's space -//----------------------------------------------------------------------------- + void btConeTwistConstraint::calcAngleInfo2() { @@ -597,13 +599,34 @@ void btConeTwistConstraint::calcAngleInfo2() m_twistLimitSign = btScalar(0.); m_solveTwistLimit = false; m_solveSwingLimit = false; + // compute rotation of A wrt B (in constraint space) + if (m_bMotorEnabled && (!m_useSolveConstraintObsolete)) + { // it is assumed that setMotorTarget() was alredy called + // and motor target m_qTarget is within constraint limits + // TODO : split rotation to pure swing and pure twist + // compute desired transforms in world + btTransform trPose(m_qTarget); + btTransform trA = getRigidBodyA().getCenterOfMassTransform() * m_rbAFrame; + btTransform trB = getRigidBodyB().getCenterOfMassTransform() * m_rbBFrame; + btTransform trDeltaAB = trB * trPose * trA.inverse(); + btQuaternion qDeltaAB = trDeltaAB.getRotation(); + btVector3 swingAxis = btVector3(qDeltaAB.x(), qDeltaAB.y(), qDeltaAB.z()); + m_swingAxis = swingAxis; + m_swingAxis.normalize(); + m_swingCorrection = qDeltaAB.getAngle(); + if(!btFuzzyZero(m_swingCorrection)) + { + m_solveSwingLimit = true; + } + return; + } + { // compute rotation of A wrt B (in constraint space) btQuaternion qA = getRigidBodyA().getCenterOfMassTransform().getRotation() * m_rbAFrame.getRotation(); btQuaternion qB = getRigidBodyB().getCenterOfMassTransform().getRotation() * m_rbBFrame.getRotation(); btQuaternion qAB = qB.inverse() * qA; - // split rotation into cone and twist // (all this is done from B's perspective. Maybe I should be averaging axes...) btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize(); @@ -756,7 +779,7 @@ void btConeTwistConstraint::calcAngleInfo2() m_twistAngle = btScalar(0.f); } } -} // btConeTwistConstraint::calcAngleInfo2() +} @@ -982,8 +1005,5 @@ void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion & } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h index 84ea9e04095..8a893d4fb8c 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h @@ -17,6 +17,22 @@ Written by: Marcus Hennix +/* +Overview: + +btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc). +It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint". +It divides the 3 rotational DOFs into swing (movement within a cone) and twist. +Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape. +(Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.) + +In the contraint's frame of reference: +twist is along the x-axis, +and swing 1 and 2 are along the z and y axes respectively. +*/ + + + #ifndef CONETWISTCONSTRAINT_H #define CONETWISTCONSTRAINT_H @@ -141,7 +157,18 @@ public: }; } - void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + // setLimit(), a few notes: + // _softness: + // 0->1, recommend ~0.8->1. + // describes % of limits where movement is free. + // beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached. + // _biasFactor: + // 0->1?, recommend 0.3 +/-0.3 or so. + // strength with which constraint resists zeroth order (angular, not angular velocity) limit violation. + // __relaxationFactor: + // 0->1, recommend to stay near 1. + // the lower the value, the less the constraint will fight velocities which violate the angular limits. + void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) { m_swingSpan1 = _swingSpan1; m_swingSpan2 = _swingSpan2; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index 6cbfe61f700..9644f2b6d57 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -26,7 +26,7 @@ http://gimpact.sf.net #define D6_USE_OBSOLETE_METHOD false -//----------------------------------------------------------------------------- + btGeneric6DofConstraint::btGeneric6DofConstraint() :btTypedConstraint(D6_CONSTRAINT_TYPE), @@ -35,7 +35,7 @@ m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) { } -//----------------------------------------------------------------------------- + btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) @@ -46,12 +46,12 @@ m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) { } -//----------------------------------------------------------------------------- + #define GENERIC_D6_DISABLE_WARMSTARTING 1 -//----------------------------------------------------------------------------- + btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) @@ -61,7 +61,7 @@ btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) return mat[i][j]; } -//----------------------------------------------------------------------------- + ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz); @@ -129,7 +129,7 @@ int btRotationalLimitMotor::testLimitValue(btScalar test_value) } -//----------------------------------------------------------------------------- + btScalar btRotationalLimitMotor::solveAngularLimits( btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, @@ -191,8 +191,8 @@ btScalar btRotationalLimitMotor::solveAngularLimits( // sort with accumulated impulses - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); btScalar oldaccumImpulse = m_accumulatedImpulse; btScalar sum = oldaccumImpulse + clippedMotorImpulse; @@ -249,9 +249,9 @@ int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_valu m_currentLimit[limitIndex] = 0;//Free from violation m_currentLimitError[limitIndex] = btScalar(0.f); return 0; -} // btTranslationalLimitMotor::testLimitValue() +} + -//----------------------------------------------------------------------------- btScalar btTranslationalLimitMotor::solveLinearAxis( btScalar timeStep, @@ -283,8 +283,8 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( //positional error (zeroth order error) btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); btScalar minLimit = m_lowerLimit[limit_index]; btScalar maxLimit = m_upperLimit[limit_index]; @@ -372,7 +372,7 @@ void btGeneric6DofConstraint::calculateAngleInfo() } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::calculateTransforms() { @@ -382,7 +382,7 @@ void btGeneric6DofConstraint::calculateTransforms() calculateAngleInfo(); } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::buildLinearJacobian( btJacobianEntry & jacLinear,const btVector3 & normalWorld, @@ -400,7 +400,7 @@ void btGeneric6DofConstraint::buildLinearJacobian( m_rbB.getInvMass()); } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::buildAngularJacobian( btJacobianEntry & jacAngular,const btVector3 & jointAxisW) @@ -413,7 +413,7 @@ void btGeneric6DofConstraint::buildAngularJacobian( } -//----------------------------------------------------------------------------- + bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) { @@ -423,7 +423,7 @@ bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) return m_angularLimits[axis_index].needApplyTorques(); } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::buildJacobian() { @@ -483,7 +483,7 @@ void btGeneric6DofConstraint::buildJacobian() } } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) { @@ -519,7 +519,7 @@ void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) } } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) { @@ -528,7 +528,7 @@ void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) setAngularLimits(info, row); } -//----------------------------------------------------------------------------- + int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) { @@ -559,7 +559,7 @@ int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) return row; } -//----------------------------------------------------------------------------- + int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset) { @@ -582,7 +582,7 @@ int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_o return row; } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) { @@ -643,7 +643,7 @@ void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolv } } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::updateRHS(btScalar timeStep) { @@ -651,21 +651,21 @@ void btGeneric6DofConstraint::updateRHS(btScalar timeStep) } -//----------------------------------------------------------------------------- + btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; } -//----------------------------------------------------------------------------- + btScalar btGeneric6DofConstraint::getAngle(int axis_index) const { return m_calculatedAxisAngleDiff[axis_index]; } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::calcAnchorPos(void) { @@ -684,9 +684,9 @@ void btGeneric6DofConstraint::calcAnchorPos(void) const btVector3& pB = m_calculatedTransformB.getOrigin(); m_AnchorPos = pA * weight + pB * (btScalar(1.0) - weight); return; -} // btGeneric6DofConstraint::calcAnchorPos() +} + -//----------------------------------------------------------------------------- void btGeneric6DofConstraint::calculateLinearInfo() { @@ -696,9 +696,9 @@ void btGeneric6DofConstraint::calculateLinearInfo() { m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); } -} // btGeneric6DofConstraint::calculateLinearInfo() +} + -//----------------------------------------------------------------------------- int btGeneric6DofConstraint::get_limit_motor_info2( btRotationalLimitMotor * limot, @@ -824,6 +824,6 @@ int btGeneric6DofConstraint::get_limit_motor_info2( else return 0; } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- + + + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h index 0ae161d5bdf..5af866390ee 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -477,4 +477,5 @@ public: }; + #endif //GENERIC_6DOF_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index 685a812d427..373cdfa26c7 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -490,7 +490,7 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m ///warm starting (or zero if disabled) - if (0)//infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) { solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; if (rb0) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp index 50d06960379..133aed7271b 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp @@ -18,14 +18,14 @@ Added by Roman Ponomarev (rponom@gmail.com) April 04, 2008 */ -//----------------------------------------------------------------------------- + #include "btSliderConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" #include -//----------------------------------------------------------------------------- + void btSliderConstraint::initParams() { @@ -62,9 +62,9 @@ void btSliderConstraint::initParams() m_maxAngMotorForce = btScalar(0.); m_accumulatedAngMotorImpulse = btScalar(0.0); -} // btSliderConstraint::initParams() +} + -//----------------------------------------------------------------------------- btSliderConstraint::btSliderConstraint() :btTypedConstraint(SLIDER_CONSTRAINT_TYPE), @@ -73,9 +73,9 @@ btSliderConstraint::btSliderConstraint() // m_useSolveConstraintObsolete(true) { initParams(); -} // btSliderConstraint::btSliderConstraint() +} + -//----------------------------------------------------------------------------- btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB) @@ -86,9 +86,25 @@ btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const // m_useSolveConstraintObsolete(true) { initParams(); -} // btSliderConstraint::btSliderConstraint() +} + + +static btRigidBody s_fixed(0, 0, 0); +btSliderConstraint::btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) + : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, s_fixed, rbB) + , + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameB), + m_useSolveConstraintObsolete(false) +// m_useSolveConstraintObsolete(true) +{ + ///not providing rigidbody B means implicitly using worldspace for body B +// m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin()); + + initParams(); +} + -//----------------------------------------------------------------------------- void btSliderConstraint::buildJacobian() { @@ -104,9 +120,9 @@ void btSliderConstraint::buildJacobian() { buildJacobianInt(m_rbB, m_rbA, m_frameInB, m_frameInA); } -} // btSliderConstraint::buildJacobian() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB) { @@ -159,9 +175,9 @@ void btSliderConstraint::buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, co // clear accumulator for motors m_accumulatedLinMotorImpulse = btScalar(0.0); m_accumulatedAngMotorImpulse = btScalar(0.0); -} // btSliderConstraint::buildJacobianInt() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::getInfo1(btConstraintInfo1* info) { @@ -189,9 +205,9 @@ void btSliderConstraint::getInfo1(btConstraintInfo1* info) info->nub--; } } -} // btSliderConstraint::getInfo1() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::getInfo2(btConstraintInfo2* info) { @@ -499,9 +515,9 @@ void btSliderConstraint::getInfo2(btConstraintInfo2* info) info->m_constraintError[srow] *= getSoftnessLimAng(); } // if(limit) } // if angular limit or powered -} // btSliderConstraint::getInfo2() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) { @@ -517,9 +533,9 @@ void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBod solveConstraintInt(m_rbB,bodyB, m_rbA,bodyA); } } -} // btSliderConstraint::solveConstraint() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btSolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB) { @@ -703,11 +719,11 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btSolverBody& body bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-angImpulse); } } -} // btSliderConstraint::solveConstraint() +} + + -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- void btSliderConstraint::calculateTransforms(void){ if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete)) @@ -740,9 +756,9 @@ void btSliderConstraint::calculateTransforms(void){ normalWorld = m_calculatedTransformA.getBasis().getColumn(i); m_depth[i] = m_delta.dot(normalWorld); } -} // btSliderConstraint::calculateTransforms() +} -//----------------------------------------------------------------------------- + void btSliderConstraint::testLinLimits(void) { @@ -769,9 +785,9 @@ void btSliderConstraint::testLinLimits(void) { m_depth[0] = btScalar(0.); } -} // btSliderConstraint::testLinLimits() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::testAngLimits(void) { @@ -795,9 +811,9 @@ void btSliderConstraint::testAngLimits(void) m_solveAngLim = true; } } -} // btSliderConstraint::testAngLimits() +} -//----------------------------------------------------------------------------- + btVector3 btSliderConstraint::getAncorInA(void) { @@ -805,13 +821,13 @@ btVector3 btSliderConstraint::getAncorInA(void) ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * btScalar(0.5) * m_sliderAxis; ancorInA = m_rbA.getCenterOfMassTransform().inverse() * ancorInA; return ancorInA; -} // btSliderConstraint::getAncorInA() +} + -//----------------------------------------------------------------------------- btVector3 btSliderConstraint::getAncorInB(void) { btVector3 ancorInB; ancorInB = m_frameInB.getOrigin(); return ancorInB; -} // btSliderConstraint::getAncorInB(); +} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h index 70fbce5d9b2..01cef59ed31 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h @@ -25,23 +25,23 @@ TODO: #ifndef SLIDER_CONSTRAINT_H #define SLIDER_CONSTRAINT_H -//----------------------------------------------------------------------------- + #include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" -//----------------------------------------------------------------------------- + class btRigidBody; -//----------------------------------------------------------------------------- + #define SLIDER_CONSTRAINT_DEF_SOFTNESS (btScalar(1.0)) #define SLIDER_CONSTRAINT_DEF_DAMPING (btScalar(1.0)) #define SLIDER_CONSTRAINT_DEF_RESTITUTION (btScalar(0.7)) -//----------------------------------------------------------------------------- + class btSliderConstraint : public btTypedConstraint { @@ -126,6 +126,7 @@ protected: public: // constructors btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); btSliderConstraint(); // overrides virtual void buildJacobian(); @@ -223,7 +224,7 @@ public: btVector3 getAncorInB(void); }; -//----------------------------------------------------------------------------- + #endif //SLIDER_CONSTRAINT_H diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h index 822296164c1..08b2dee8af3 100644 --- a/extern/bullet2/src/LinearMath/btScalar.h +++ b/extern/bullet2/src/LinearMath/btScalar.h @@ -168,8 +168,12 @@ inline int btGetVersion() ///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision. #if defined(BT_USE_DOUBLE_PRECISION) typedef double btScalar; +//this number could be bigger in double precision +#define BT_LARGE_FLOAT 1e30 #else typedef float btScalar; +//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX +#define BT_LARGE_FLOAT 1e18f #endif diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index a41f954c4d8..edc8e2a56a1 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1510,10 +1510,11 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); - uiDefButI(block, MENU, B_CONSTRAINT_TEST, "Joint Types%t|Ball%x1|Hinge%x2|Cone Twist%x4|Generic (experimental)%x12",//|Extra Force%x6", + uiDefButI(block, MENU, B_CONSTRAINT_TEST, "Joint Types%t|Ball%x1|Hinge%x2|Generic 6DOF%x12",//|Extra Force%x6", + //uiDefButI(block, MENU, B_CONSTRAINT_TEST, "Joint Types%t|Ball%x1|Hinge%x2|Cone Twist%x4|Generic 6DOF%x12",//|Extra Force%x6", *xco, *yco-25, 150, 18, &data->type, 0, 0, 0, 0, "Choose the joint type"); - uiDefButBitS(block, TOG, CONSTRAINT_DISABLE_LINKED_COLLISION, B_CONSTRAINT_TEST, "No Col.", *xco+155, *yco-25, 111, 18, &data->flag, 0, 24, 0, 0, "Disable Collision Between Linked Bodies"); + uiDefButBitS(block, TOG, CONSTRAINT_DISABLE_LINKED_COLLISION, B_CONSTRAINT_TEST, "No Collision", *xco+155, *yco-25, 111, 18, &data->flag, 0, 24, 0, 0, "Disable Collision Between Linked Bodies"); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "toObject:", *xco, *yco-50, 130, 18, &data->tar, "Child Object"); From eb8c5f3272b87fffaf017badf55f761de9a04fd1 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 23 May 2009 22:35:47 +0000 Subject: [PATCH 306/444] Set default constraint solver mode more compatible to Blender 2.48 settings, this fixes rigid body stacking in this blend file: http://blenderartists.org/forum/showpost.php?p=1382653&postcount=102 (todo: expose this setting in World setting GUI) Expose contact processing threshold in Advanced GUI, next to rigid body margin, called CPT. Default to 1, makes rigid body stacking a bit more stable, smaller values makes sliding easier (at the cost of easier jittering). Disabled for 'dynamic' objects that don't rotate, because characters etc. always need smooth sliding. --- .../ConstraintSolver/btContactSolverInfo.h | 2 +- source/blender/blenkernel/intern/object.c | 2 ++ source/blender/blenloader/intern/readfile.c | 5 +++-- source/blender/makesdna/DNA_object_types.h | 2 +- source/blender/src/buttons_logic.c | 15 +++++++++++++-- .../Converter/BL_BlenderDataConversion.cpp | 13 +++++++++++++ .../gameengine/Ketsji/KX_ConvertPhysicsObject.h | 2 ++ .../Ketsji/KX_ConvertPhysicsObjects.cpp | 2 ++ .../Physics/Bullet/CcdPhysicsController.cpp | 2 ++ .../Physics/Bullet/CcdPhysicsController.h | 10 +++++++++- 10 files changed, 48 insertions(+), 7 deletions(-) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h index e99430c00de..a11fc94ea11 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -77,7 +77,7 @@ struct btContactSolverInfo : public btContactSolverInfoData m_splitImpulsePenetrationThreshold = -0.02f; m_linearSlop = btScalar(0.0); m_warmstartingFactor=btScalar(0.85); - m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER + m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_USE_2_FRICTION_DIRECTIONS |SOLVER_SIMD | SOLVER_RANDMIZE_ORDER; m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution } }; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index bffbcf73672..9739668c7c7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -984,6 +984,8 @@ Object *add_only_object(int type, char *name) ob->anisotropicFriction[2] = 1.0f; ob->gameflag= OB_PROP|OB_COLLISION; ob->margin = 0.0; + /* ob->pad3 == Contact Processing Threshold */ + ob->pad3 = 1.; /* NT fluid sim defaults */ ob->fluidsimFlag = 0; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bda0348f2ca..0b0a97b7ec0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8083,7 +8083,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* Adjustments needed after Bullets update */ for(ob = main->object.first; ob; ob= ob->id.next) { ob->damping *= 0.635f; - ob->rdamping = 0.1 + (0.59f * ob->rdamping); + ob->rdamping = 0.1 + (0.8f * ob->rdamping); } } @@ -8105,11 +8105,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) wrld->occlusionRes = 128; } } - + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) { Object *ob; World *wrld; for(ob = main->object.first; ob; ob= ob->id.next) { + ob->pad3 = 1.; //pad3 is used for m_contactProcessingThreshold if(ob->parent) { /* check if top parent has compound shape set and if yes, set this object to compound shaper as well (was the behaviour before, now it's optional) */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 9121f38be16..11fa44fe488 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -159,7 +159,7 @@ typedef struct Object { float margin; float max_vel; /* clamp the maximum velocity 0.0 is disabled */ float min_vel; /* clamp the maximum velocity 0.0 is disabled */ - float pad3; /* clamp the maximum velocity 0.0 is disabled */ + float pad3; /* pad3 is now used for m_contactProcessingThreshold, can we still rename it? */ char dt, dtx; char totcol; /* copy of mesh or curve or meta */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index b7039673dfc..b0ce3c8a95b 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3198,11 +3198,17 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) uiDefButF(block, NUM, 0, "Margin", xco, yco, 180, 19, &ob->margin, 0.001, 1.0, 1, 0, "Collision margin"); + - yco -= 20; if (ob->gameflag & OB_RIGID_BODY) { + uiDefButF(block, NUM, 0, "CPT", + xco+180, yco, 180, 19, &ob->pad3, 0.00, 1., 1, 0, + "Contact Processing Threshold"); + + yco -= 20; + uiDefButBitI(block, TOG, OB_LOCK_RIGID_BODY_X_AXIS, 0, "Lock X Axis", xco, yco, 180, 19, &ob->gameflag2, 0, 0, 0, 0, "Disable simulation of linear motion along the X axis"); @@ -3226,8 +3232,9 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) uiDefButBitI(block, TOG, OB_LOCK_RIGID_BODY_Z_ROT_AXIS, 0, "Lock Z Rot Axis", xco+=180, yco, 180, 19, &ob->gameflag2, 0, 0, 0, 0, "Disable simulation of angular motion along the Z axis"); - yco -= 20; } + + yco -= 20; xco = 0; uiBlockEndAlign(block); @@ -3279,6 +3286,10 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) uiDefButF(block, NUM, 0, "Margin", xco, yco, 180, 19, &ob->margin, 0.0, 1.0, 1, 0, "Collision margin"); + uiDefButF(block, NUM, 0, "CPT", + xco+180, yco, 180, 19, &ob->pad3, 0.00, 1., 1, 0, + "Contact Processing Threshold"); + } yco -= 20; xco = 0; diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 06a4da4fce0..a9c839595c2 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1412,11 +1412,22 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_isCompoundChild = isCompoundChild; objprop.m_hasCompoundChildren = hasCompoundChildren; objprop.m_margin = blenderobject->margin; + // ACTOR is now a separate feature objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0; objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0; objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0; + + ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic' + if (objprop.m_angular_rigidbody || !objprop.m_dyna ) + { + objprop.m_contactProcessingThreshold = blenderobject->pad3; + } else + { + objprop.m_contactProcessingThreshold = 0.f; + } + objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0; if (objprop.m_softbody) @@ -1461,6 +1472,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */ objprop.m_margin = blenderobject->bsoft->margin; + objprop.m_contactProcessingThreshold = 0.f; } else { objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT; @@ -1501,6 +1513,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_numclusteriterations= 16; objprop.m_soft_welding = 0.f; objprop.m_margin = 0.f; + objprop.m_contactProcessingThreshold = 0.f; } } diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index e48fddb30bd..74042366bae 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -139,6 +139,8 @@ struct KX_ObjectProperties ///////////////////////// double m_margin; + float m_contactProcessingThreshold; + KX_BoundBoxClass m_boundclass; union { KX_BoxBounds box; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 76642649afc..cdba59dd9ca 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -1103,6 +1103,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody; + + ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so ci.m_bSoft = objprop->m_softbody; ci.m_bSensor = isbulletsensor; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6b00011b693..710d0656f6d 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -519,6 +519,8 @@ void CcdPhysicsController::CreateRigidbody() { body->setAngularFactor(0.f); } + body->setContactProcessingThreshold(m_cci.m_contactProcessingThreshold); + } if (m_object && m_cci.m_do_anisotropic) { diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index fc8de0e2ded..d73759bac76 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -231,7 +231,8 @@ struct CcdConstructionInfo m_physicsEnv(0), m_inertiaFactor(1.f), m_do_anisotropic(false), - m_anisotropicFriction(1.f,1.f,1.f) + m_anisotropicFriction(1.f,1.f,1.f), + m_contactProcessingThreshold(1e10) { } @@ -317,6 +318,13 @@ struct CcdConstructionInfo btScalar m_fh_distance; ///< The range above the surface where Fh is active. bool m_fh_normal; ///< Should the object slide off slopes? float m_radius;//for fh backwards compatibility + + ///m_contactProcessingThreshold allows to process contact points with positive distance + ///normally only contacts with negative distance (penetration) are solved + ///however, rigid body stacking is more stable when positive contacts are still passed into the constraint solver + ///this might sometimes lead to collisions with 'internal edges' such as a sliding character controller + ///so disable/set m_contactProcessingThreshold to zero for sliding characters etc. + float m_contactProcessingThreshold;///< Process contacts with positive distance in range [0..INF] }; From 4922dd03393489e85f04bd5785496c44af78d0d6 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sun, 24 May 2009 00:42:40 +0000 Subject: [PATCH 307/444] fix generic 6dof constraint support -> convert 3 values into euler angles and convert those into a full constraint frame (same values as Rigid Body constraint Generic 6DOF values), and add 'setLimit' support for generic 6DOF constraint. todo: enableMotor --- .../Ketsji/KX_ConstraintWrapper.cpp | 30 +++++++++++++++++++ .../gameengine/Ketsji/KX_ConstraintWrapper.h | 2 ++ .../Ketsji/KX_PyConstraintBinding.cpp | 27 ++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index c63f9e57ed2..7af2b15a14c 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -54,6 +54,31 @@ PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds return PyInt_FromLong(m_constraintId); } +PyObject* KX_ConstraintWrapper::PySetLimit(PyObject* args, PyObject* kwds) +{ + int len = PyTuple_Size(args); + int success = 1; + + if (len == 3) + { + int dof; + float minLimit,maxLimit; + success = PyArg_ParseTuple(args,"iff",&dof,&minLimit,&maxLimit); + if (success) + { + m_physenv->setConstraintParam(m_constraintId,dof,minLimit,maxLimit); + Py_RETURN_NONE; + } + } + return NULL; +} + +PyObject* KX_ConstraintWrapper::PyEnableMotor(PyObject* args, PyObject* kwds) +{ + ///will add it soon + return PyInt_FromLong(0); +} + //python specific stuff PyTypeObject KX_ConstraintWrapper::Type = { #if (PY_VERSION_HEX >= 0x02060000) @@ -100,8 +125,13 @@ int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value) }; + + + PyMethodDef KX_ConstraintWrapper::Methods[] = { {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS}, + {"setLimit",(PyCFunction) KX_ConstraintWrapper::sPySetLimit, METH_VARARGS}, + {"enableMotor",(PyCFunction) KX_ConstraintWrapper::sPyEnableMotor, METH_VARARGS}, {NULL,NULL} //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 3270d57188d..0772d257b56 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -45,6 +45,8 @@ public: KX_PYMETHOD(KX_ConstraintWrapper,TestMethod); KX_PYMETHOD(KX_ConstraintWrapper,GetConstraintId); + KX_PYMETHOD(KX_ConstraintWrapper,SetLimit); + KX_PYMETHOD(KX_ConstraintWrapper,EnableMotor); private: int m_constraintId; diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 0f21b24489d..1d52057317e 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -33,6 +33,7 @@ #include "KX_PhysicsObjectWrapper.h" #include "PHY_IPhysicsController.h" #include "PHY_IVehicle.h" +#include "MT_Matrix3x3.h" #include "PyObjectPlus.h" @@ -435,7 +436,31 @@ static PyObject* gPyCreateConstraint(PyObject* self, PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2; if (physctrl) //TODO:check for existance of this pointer! { - int constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0); + PHY_ConstraintType ct = (PHY_ConstraintType) constrainttype; + int constraintid =0; + + if (ct == PHY_GENERIC_6DOF_CONSTRAINT) + { + //convert from euler angle into axis + float radsPerDeg = 6.283185307179586232f / 360.f; + + //we need to pass a full constraint frame, not just axis + //localConstraintFrameBasis + MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*axisX,radsPerDeg*axisY,radsPerDeg*axisZ)); + MT_Vector3 axis0 = localCFrame.getColumn(0); + MT_Vector3 axis1 = localCFrame.getColumn(1); + MT_Vector3 axis2 = localCFrame.getColumn(2); + + constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype, + pivotX,pivotY,pivotZ, + (float)axis0.x(),(float)axis0.y(),(float)axis0.z(), + (float)axis1.x(),(float)axis1.y(),(float)axis1.z(), + (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),0);//dat->flag); //flag? + + } else + { + constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0); + } KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment()); From 52b0a2b3dbf5c5e0b930dcaff8647ec1d06e2d3c Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sun, 24 May 2009 01:55:24 +0000 Subject: [PATCH 308/444] PhysicsConstraints.createConstraint: allow to dynamically create rigid body constraints while disable collision detection between connected bodies, pass as 10th argument the flag 128 PhysiPython KX_ConstraintWrapper, setParam export setParam(paramIndex,paramValue0,paramValue1) for Physics constraints paramIndex 0,1,2 are linear limits, 3,4,5 are angular limits, 6,7,8 are linear motors, 9,10,11 are angular motors For example: disableConnectedBodies=128 cons = PhysicsConstraints.createConstraint(oid,rid,generic6dof,pivotInAx,pivotInAy,pivotInAz,angleX,angleY,angleZ,disableConnectedBodies) #params 0,1,2 are linear limits, low,high value. if low > high then disable limit cons.setParam(0,0,0) I will provide an example .blend for Blender 2.49 --- .../Ketsji/KX_ConstraintWrapper.cpp | 11 ++--- .../gameengine/Ketsji/KX_ConstraintWrapper.h | 3 +- .../Ketsji/KX_PyConstraintBinding.cpp | 9 +++- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 47 +++++++++++++++++-- 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index 7af2b15a14c..b0576424a47 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -54,7 +54,7 @@ PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds return PyInt_FromLong(m_constraintId); } -PyObject* KX_ConstraintWrapper::PySetLimit(PyObject* args, PyObject* kwds) +PyObject* KX_ConstraintWrapper::PySetParam(PyObject* args, PyObject* kwds) { int len = PyTuple_Size(args); int success = 1; @@ -73,11 +73,7 @@ PyObject* KX_ConstraintWrapper::PySetLimit(PyObject* args, PyObject* kwds) return NULL; } -PyObject* KX_ConstraintWrapper::PyEnableMotor(PyObject* args, PyObject* kwds) -{ - ///will add it soon - return PyInt_FromLong(0); -} + //python specific stuff PyTypeObject KX_ConstraintWrapper::Type = { @@ -130,8 +126,7 @@ int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value) PyMethodDef KX_ConstraintWrapper::Methods[] = { {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS}, - {"setLimit",(PyCFunction) KX_ConstraintWrapper::sPySetLimit, METH_VARARGS}, - {"enableMotor",(PyCFunction) KX_ConstraintWrapper::sPyEnableMotor, METH_VARARGS}, + {"setParam",(PyCFunction) KX_ConstraintWrapper::sPySetParam, METH_VARARGS}, {NULL,NULL} //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 0772d257b56..b8ac464ceab 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -45,8 +45,7 @@ public: KX_PYMETHOD(KX_ConstraintWrapper,TestMethod); KX_PYMETHOD(KX_ConstraintWrapper,GetConstraintId); - KX_PYMETHOD(KX_ConstraintWrapper,SetLimit); - KX_PYMETHOD(KX_ConstraintWrapper,EnableMotor); + KX_PYMETHOD(KX_ConstraintWrapper,SetParam); private: int m_constraintId; diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 1d52057317e..a098d99864f 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -405,6 +405,8 @@ static PyObject* gPyCreateConstraint(PyObject* self, int physicsid=0,physicsid2 = 0,constrainttype=0,extrainfo=0; int len = PyTuple_Size(args); int success = 1; + int flag = 0; + float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1; if (len == 3) { @@ -421,6 +423,11 @@ static PyObject* gPyCreateConstraint(PyObject* self, success = PyArg_ParseTuple(args,"iiiffffff",&physicsid,&physicsid2,&constrainttype, &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ); } + else if (len == 10) + { + success = PyArg_ParseTuple(args,"iiiffffffi",&physicsid,&physicsid2,&constrainttype, + &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag); + } else if (len==4) { success = PyArg_ParseTuple(args,"iiii",&physicsid,&physicsid2,&constrainttype,&extrainfo); @@ -455,7 +462,7 @@ static PyObject* gPyCreateConstraint(PyObject* self, pivotX,pivotY,pivotZ, (float)axis0.x(),(float)axis0.y(),(float)axis0.z(), (float)axis1.x(),(float)axis1.y(),(float)axis1.z(), - (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),0);//dat->flag); //flag? + (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag); } else { diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index ed517e637dc..561c370854f 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -426,6 +426,13 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr btRigidBody* body = ctrl->GetRigidBody(); if (body) { + for (int i=body->getNumConstraintRefs()-1;i>=0;i--) + { + btTypedConstraint* con = body->getConstraintRef(i); + m_dynamicsWorld->removeConstraint(con); + body->removeConstraintRef(con); + //delete con; //might be kept by python KX_ConstraintWrapper + } m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody()); } else { @@ -1791,9 +1798,43 @@ void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float { case PHY_GENERIC_6DOF_CONSTRAINT: { - //param = 1..12, min0,max0,min1,max1...min6,max6 - btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - genCons->setLimit(param,value0,value1); + + switch (param) + { + case 0: case 1: case 2: case 3: case 4: case 5: + { + //param = 0..5 are constraint limits, with low/high limit value + btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; + genCons->setLimit(param,value0,value1); + break; + } + case 6: case 7: case 8: + { + //param = 6,7,8 are translational motors, with value0=target velocity, value1 = max motor force + btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; + int transMotorIndex = param-6; + btTranslationalLimitMotor* transMotor = genCons->getTranslationalLimitMotor(); + transMotor->m_targetVelocity[transMotorIndex]= value0; + transMotor->m_maxMotorForce[transMotorIndex]=value1; + transMotor->m_enableMotor[transMotorIndex] = (value1>0.f); + break; + } + case 9: case 10: case 11: + { + //param = 9,10,11 are rotational motors, with value0=target velocity, value1 = max motor force + btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; + int angMotorIndex = param-9; + btRotationalLimitMotor* rotMotor = genCons->getRotationalLimitMotor(angMotorIndex); + rotMotor->m_enableMotor = (value1 > 0.f); + rotMotor->m_targetVelocity = value0; + rotMotor->m_maxMotorForce = value1; + break; + } + + default: + { + } + } break; }; default: From 45f2463c833577852b2c9d3c85e435fc25b945bd Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sun, 24 May 2009 04:45:10 +0000 Subject: [PATCH 309/444] Patch #18815: BGE: More updates to deprecation documentation and 2.49 conversion script by Alex Frases(z0r) - Fixed some deprecation warnings in documentation. - Added more conversions to script. - Added more attributes to script todo list. - Print out name of text buffer when encountering an error in batch mode. - Refactor: Simplified attribute map. - Added notImplemented function to print warnings for missing conversions. References documentation. --- release/scripts/textplugin_convert_ge.py | 534 +++++++++++++---------- source/gameengine/PyDoc/GameTypes.py | 100 +++-- 2 files changed, 353 insertions(+), 281 deletions(-) diff --git a/release/scripts/textplugin_convert_ge.py b/release/scripts/textplugin_convert_ge.py index 043b40252d9..f3b44cdb14b 100644 --- a/release/scripts/textplugin_convert_ge.py +++ b/release/scripts/textplugin_convert_ge.py @@ -39,16 +39,23 @@ Tooltip: 'Attemps to update deprecated usage of game engine API.' # recommended that you review all changes after running this script. # # TODO: The following attributes are either ambiguous or need special processing -# to handle parameters. +# to handle parameters. Deprecated attributes that map to multiple target +# attributes will require a refactor of the main conversion loop in the +# convert248to249 function: currently, it doesn't allow any conversion to +# advance the row index by more than one. # -# getLinearVelocity (KX_SCA_AddObjectActuator) +# getLinearVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator) # Conflicts with KX_GameObject. -# setLinearVelocity (KX_SCA_AddObjectActuator) +# Maps to multiple attributes. +# setLinearVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator) # Conflicts with KX_GameObject. -# getAngularVelocity (KX_SCA_AddObjectActuator) +# Maps to multiple attributes. +# getAngularVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator) # Conflicts with KX_GameObject. -# setAngularVelocity (KX_SCA_AddObjectActuator) +# Maps to multiple attributes. +# setAngularVelocity (KX_SCA_AddObjectActuator, KX_ObjectActuator) # Conflicts with KX_GameObject. +# Maps to multiple attributes. # setAction (BL_ShapeActionActuator, BL_ActionActuator) # `reset' argument has no conversion target. # set (KX_VisibilityActuator, KX_IpoActuator) @@ -69,6 +76,26 @@ Tooltip: 'Attemps to update deprecated usage of game engine API.' # KX_GameObject. # setOperation (KX_SCA_DynamicActuator, KX_StateActuator) # Ambiguous: different target names. +# getDRot (KX_ObjectActuator) +# Maps to multiple attributes. +# setDRot (KX_ObjectActuator) +# Arguments map to multiple attributes. +# getDLoc (KX_ObjectActuator) +# Maps to multiple attributes. +# setDLoc (KX_ObjectActuator) +# Arguments map to multiple attributes. +# getTorque (KX_ObjectActuator) +# Maps to multiple attributes. +# setTorque (KX_ObjectActuator) +# Arguments map to multiple attributes. +# getForce (KX_ObjectActuator) +# Maps to multiple attributes. +# setForce (KX_ObjectActuator) +# Arguments map to multiple attributes. +# position (KX_GameObject) +# Conflicts with KX_SoundActuator. +# orientation (KX_GameObject) +# Conflicts with KX_SoundActuator. # import string @@ -268,7 +295,9 @@ def replaceGetXYPosition(lines, row, colStart, colEnd, axis): lines[row] = replaceSubstr(lines[row], colStart, colEnd, 'position') def replaceRename(lines, row, colStart, colEnd, newName): - """Replace an identifier with another, e.g. foo.getBar() -> foo.getBaz() + """Replace an identifier with another, e.g. + foo.getBar() -> foo.getBaz() + foo.bar -> foo.baz The identifier being replaced must be on line `row' and between `colStart' and `colEnd'.""" @@ -402,233 +431,268 @@ def replaceSetPosition(lines, row, colStart, colEnd, closure): # It's probably a KX_GameObject. replaceSimpleSetter(lines, row, colStart, colEnd, 'localPosition') +def replaceSplitProperty(lines, row, colStart, colEnd, (newGetter, newSetter)): + '''Some property attributes behave differently when being written to or read + from. Try to determine the operation, and replace accordingly. E.G. + o.position = foo -> o.localPosition = foo # set + foo = o.position -> foo = o.worldPosition # get + + This implementation can not handle cases where the object is returned from + a function, e.g. + foo = bar.getObject().position # Error! + + Raises a ConversionError if the operation can't be determined, or if the + object is returned from a function.''' + assnRegex = re.compile(r'(=\s*)?' # Getter + r'[a-zA-Z_]\w*' # Object identifier + r'\.([a-zA-Z_][a-zA-Z0-9_.]*)+' # Trailing attributes + r'(\s*=)?') # Setter + match = assnRegex.search(lines[row]) + + if not match: + raise ConversionError, "Can't determine operation (getting or setting)." + + setting = False + getting = False + if match.group(1): + getting = True + if match.group(3): + setting = True + if (getting and setting) or ((not getting) and (not setting)): + raise ConversionError, "Can't determine operation (getting or setting)." + + if getting: + replaceRename(lines, row, colStart, colEnd, newGetter) + else: + replaceRename(lines, row, colStart, colEnd, newSetter) + +def notImplemented(lines, row, colStart, colEnd, classNames): + message = "Conversion not implemented. See documentation for " +\ + string.join(classNames, ', ') + raise ConversionError, message + # # Deprecated attribute information. The format is: -# deprecatedAttributeName: {(conversionFunction, closure): classList} +# deprecatedAttributeName: (conversionFunction, closure) # Usually the closure will be the name of the superceding attribute. # -# If an attribute maps to more than one function/attribute pair, the conversion -# is ambiguous and can't be performed. +# Since each deprecated attribute can appear in this dictionary only once, it is +# the conversion function's responsibility to resolve ambiguity. # attributeRenameDict = { # Special cases - 'addActiveActuator': {(replaceAddActiveActuator, None): []}, - 'getActuator': {(replaceGetActuator, None): ['SCA_IController', 'SCA_ActuatorSensor']}, - 'getXPosition': {(replaceGetXYPosition, '0'): ['SCA_MouseSensor']}, - 'getYPosition': {(replaceGetXYPosition, '1'): ['SCA_MouseSensor']}, - 'setOrientation': {(replaceSetOrientation, None): ['KX_GameObject', 'KX_SoundActuator']}, - 'setPosition': {(replaceSetPosition, None): ['KX_GameObject', 'KX_SoundActuator']}, + 'addActiveActuator': (replaceAddActiveActuator, None), # + 'getActuator': (replaceGetActuator, None), # SCA_IController, SCA_ActuatorSensor + 'getXPosition': (replaceGetXYPosition, '0'), # SCA_MouseSensor + 'getYPosition': (replaceGetXYPosition, '1'), # SCA_MouseSensor + 'setOrientation': (replaceSetOrientation, None), # KX_GameObject, KX_SoundActuator + 'setPosition': (replaceSetPosition, None), # KX_GameObject, KX_SoundActuator # Keyed getters/setters - 'getSensor': {(replaceKeyedGetter, 'sensors'): ['SCA_IController']}, + 'getSensor': (replaceKeyedGetter, 'sensors'), # SCA_IController # Multi-arg -> List setter - 'setAxis': {(replaceArgsWithListSetter, 'axis'): ['SCA_JoystickSensor']}, - 'setHat': {(replaceArgsWithListSetter, 'hat'): ['SCA_JoystickSensor']}, - 'setVelocity': {(replaceArgsWithListSetter, 'velocity'): ['KX_SoundActuator']}, + 'setAxis': (replaceArgsWithListSetter, 'axis'), # SCA_JoystickSensor + 'setForceLimitX': (replaceArgsWithListSetter, 'forceLimitX'), # KX_ObjectActuator + 'setForceLimitY': (replaceArgsWithListSetter, 'forceLimitY'), # KX_ObjectActuator + 'setForceLimitZ': (replaceArgsWithListSetter, 'forceLimitZ'), # KX_ObjectActuator + 'setHat': (replaceArgsWithListSetter, 'hat'), # SCA_JoystickSensor + 'setPID': (replaceArgsWithListSetter, 'pid'), # KX_ObjectActuator + 'setVelocity': (replaceArgsWithListSetter, 'velocity'), # KX_SoundActuator # Straight rename - 'getButtonValue': {(replaceRename, 'getButtonActiveList'): ['SCA_JoystickSensor']}, + 'getButtonValue': (replaceRename, 'getButtonActiveList'), # SCA_JoystickSensor + + # Split properties + 'scaling': (replaceSplitProperty, ('worldScaling', 'localScaling')), # KX_GameObject # Simple getters/setters - 'getSensors': {(replaceSimpleGetter, 'sensors'): ['SCA_IController']}, - 'getActuators': {(replaceSimpleGetter, 'actuators'): ['SCA_IController']}, - 'enableViewport': {(replaceSimpleSetter, 'useViewport'): ['KX_Camera']}, - 'getAction': {(replaceSimpleGetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, - 'getAxis': {(replaceSimpleGetter, 'axis'): ['SCA_JoystickSensor']}, - 'getAxisValue': {(replaceSimpleGetter, 'axisValues'): ['SCA_JoystickSensor']}, - 'getBlendin': {(replaceSimpleGetter, 'blendIn'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'getBodies': {(replaceSimpleGetter, 'bodies'): ['KX_NetworkMessageSensor']}, - 'getButton': {(replaceSimpleGetter, 'button'): ['SCA_JoystickSensor']}, - 'getCamera': {(replaceSimpleGetter, 'camera'): ['KX_SceneActuator']}, - 'getConeOrigin': {(replaceSimpleGetter, 'coneOrigin'): ['KX_RadarSensor']}, - 'getConeTarget': {(replaceSimpleGetter, 'coneTarget'): ['KX_RadarSensor']}, - 'getContinue': {(replaceSimpleGetter, 'useContinue'): ['BL_ActionActuator']}, - 'getCurrentlyPressedKeys': {(replaceSimpleGetter, 'events'): ['SCA_KeyboardSensor']}, - 'getDelay': {(replaceSimpleGetter, 'delay'): ['SCA_DelaySensor']}, - 'getDistribution': {(replaceSimpleGetter, 'distribution'): ['SCA_RandomActuator']}, - 'getDuration': {(replaceSimpleGetter, 'duration'): ['SCA_DelaySensor']}, - 'getEnd': {(replaceSimpleGetter, 'frameEnd'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, - 'getExecutePriority': {(replaceSimpleGetter, 'executePriority'): ['SCA_ILogicBrick']}, - 'getFile': {(replaceSimpleGetter, 'fileName'): ['KX_GameActuator']}, - 'getFilename': {(replaceSimpleGetter, 'fileName'): ['KX_SoundActuator']}, - 'getForceIpoActsLocal': {(replaceSimpleGetter, 'useIpoLocal'): ['KX_IpoActuator']}, - 'getFrame': {(replaceSimpleGetter, 'frame'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, - 'getFrameMessageCount': {(replaceSimpleGetter, 'frameMessageCount'): ['KX_NetworkMessageSensor']}, - 'getFrameProperty': {(replaceSimpleGetter, 'framePropName'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'getFrequency': {(replaceSimpleGetter, 'frequency'): ['SCA_ISensor']}, - 'getGain': {(replaceSimpleGetter, 'volume'): ['KX_SoundActuator', 'KX_CDActuator']}, - 'getHat': {(replaceSimpleGetter, 'hat'): ['SCA_JoystickSensor']}, - 'getHeight': {(replaceSimpleGetter, 'height'): ['KX_CameraActuator']}, - 'getHitNormal': {(replaceSimpleGetter, 'hitNormal'): ['KX_MouseFocusSensor', 'KX_RaySensor']}, - 'getHitObject': {(replaceSimpleGetter, 'hitObject'): ['KX_MouseFocusSensor', - 'KX_RaySensor', - 'KX_TouchSensor']}, - 'getHitObjectList': {(replaceSimpleGetter, 'hitObjectList'): ['KX_TouchSensor']}, - 'getHitPosition': {(replaceSimpleGetter, 'hitPosition'): ['KX_MouseFocusSensor', - 'KX_RaySensor']}, - 'getHold1': {(replaceSimpleGetter, 'hold1'): ['SCA_KeyboardSensor']}, - 'getHold2': {(replaceSimpleGetter, 'hold2'): ['SCA_KeyboardSensor']}, - 'getInvert': {(replaceSimpleGetter, 'invert'): ['SCA_ISensor']}, - 'getIpoAdd': {(replaceSimpleGetter, 'useIpoAdd'): ['KX_IpoActuator']}, - 'getIpoAsForce': {(replaceSimpleGetter, 'useIpoAsForce'): ['KX_IpoActuator']}, - 'getKey': {(replaceSimpleGetter, 'key'): ['SCA_KeyboardSensor']}, - 'getLastCreatedObject': {(replaceSimpleGetter, 'objectLastCreated'): ['KX_SCA_AddObjectActuator']}, - 'getLevel': {(replaceSimpleGetter, 'level'): ['SCA_ISensor']}, - 'getLightList': {(replaceSimpleGetter, 'lights'): ['KX_Scene']}, - 'getLooping': {(replaceSimpleGetter, 'looping'): ['KX_SoundActuator']}, - 'getMass': {(replaceSimpleGetter, 'mass'): ['KX_GameObject']}, - 'getMax': {(replaceSimpleGetter, 'max'): ['KX_CameraActuator']}, - 'getMin': {(replaceSimpleGetter, 'min'): ['KX_CameraActuator']}, - 'getName': {(replaceSimpleGetter, 'name'): ['KX_Scene']}, - 'getNumAxes': {(replaceSimpleGetter, 'numAxis'): ['SCA_JoystickSensor']}, - 'getNumButtons': {(replaceSimpleGetter, 'numButtons'): ['SCA_JoystickSensor']}, - 'getNumHats': {(replaceSimpleGetter, 'numHats'): ['SCA_JoystickSensor']}, - 'getObjectList': {(replaceSimpleGetter, 'objects'): ['KX_Scene']}, - 'getOperation': {(replaceSimpleGetter, 'mode'): ['KX_SCA_DynamicActuator']}, - 'getOrientation': {(replaceSimpleGetter, 'worldOrientation'): ['KX_GameObject']}, - 'getOwner': {(replaceSimpleGetter, 'owner'): ['SCA_ILogicBrick']}, - 'getPara1': {(replaceSimpleGetter, 'para1'): ['SCA_RandomActuator']}, - 'getPara2': {(replaceSimpleGetter, 'para2'): ['SCA_RandomActuator']}, - 'getParent': {(replaceSimpleGetter, 'parent'): ['KX_GameObject']}, - 'getPitch': {(replaceSimpleGetter, 'pitch'): ['KX_SoundActuator']}, - 'getPosition': {(replaceSimpleGetter, 'worldPosition'): ['KX_GameObject']}, - 'getPressedKeys': {(replaceSimpleGetter, 'events'): ['SCA_KeyboardSensor']}, - 'getPriority': {(replaceSimpleGetter, 'priority'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'getProjectionMatrix': {(replaceSimpleGetter, 'projection_matrix'): ['KX_Camera']}, - 'getProperty': {(replaceSimpleGetter, 'propName'): ['SCA_PropertySensor', - 'SCA_RandomActuator', - 'SCA_PropertyActuator']}, - 'getRayDirection': {(replaceSimpleGetter, 'rayDirection'): ['KX_MouseFocusSensor', - 'KX_RaySensor']}, - 'getRaySource': {(replaceSimpleGetter, 'raySource'): ['KX_MouseFocusSensor']}, - 'getRayTarget': {(replaceSimpleGetter, 'rayTarget'): ['KX_MouseFocusSensor']}, - 'getRepeat': {(replaceSimpleGetter, 'repeat'): ['SCA_DelaySensor']}, - 'getRollOffFactor': {(replaceSimpleGetter, 'rollOffFactor'): ['KX_SoundActuator']}, - 'getScene': {(replaceSimpleGetter, 'scene'): ['KX_SceneActuator']}, - 'getScript': {(replaceSimpleGetter, 'script'): ['SCA_PythonController']}, - 'getSeed': {(replaceSimpleGetter, 'seed'): ['SCA_RandomActuator']}, - 'getStart': {(replaceSimpleGetter, 'frameStart'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, - 'getState': {(replaceSimpleGetter, 'state'): ['SCA_IController', 'KX_GameObject']}, - 'getSubject': {(replaceSimpleGetter, 'subject'): ['KX_NetworkMessageSensor']}, - 'getSubjects': {(replaceSimpleGetter, 'subjects'): ['KX_NetworkMessageSensor']}, - 'getThreshold': {(replaceSimpleGetter, 'threshold'): ['SCA_JoystickSensor']}, - 'getTime': {(replaceSimpleGetter, 'time'): ['KX_SCA_AddObjectActuator', 'KX_TrackToActuator']}, - 'getTouchMaterial': {(replaceSimpleGetter, 'useMaterial'): ['KX_TouchSensor']}, - 'getType': {(replaceSimpleGetter, 'mode'): ['SCA_PropertySensor']}, - 'getUse3D': {(replaceSimpleGetter, 'use3D'): ['KX_TrackToActuator']}, - 'getUseNegPulseMode': {(replaceSimpleGetter, 'useNegPulseMode'): ['SCA_ISensor']}, - 'getUsePosPulseMode': {(replaceSimpleGetter, 'usePosPulseMode'): ['SCA_ISensor']}, - 'getUseRestart': {(replaceSimpleGetter, 'useRestart'): ['KX_SceneActuator']}, - 'getValue': {(replaceSimpleGetter, 'value'): ['SCA_PropertySensor', 'SCA_PropertyActuator']}, - 'getVisible': {(replaceSimpleGetter, 'visible'): ['KX_GameObject']}, - 'getXY': {(replaceSimpleGetter, 'useXY'): ['KX_CameraActuator']}, - 'isConnected': {(replaceSimpleGetter, 'connected'): ['SCA_JoystickSensor']}, - 'isPositive': {(replaceSimpleGetter, 'positive'): ['SCA_ISensor']}, - 'isTriggered': {(replaceSimpleGetter, 'triggered'): ['SCA_ISensor']}, - 'setActuator': {(replaceSimpleSetter, 'actuator'): ['SCA_ActuatorSensor']}, - 'setBlendin': {(replaceSimpleSetter, 'blendIn'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'setBlendtime': {(replaceSimpleSetter, 'blendTime'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'setBodyType': {(replaceSimpleSetter, 'usePropBody'): ['KX_NetworkMessageActuator']}, - 'setButton': {(replaceSimpleSetter, 'button'): ['SCA_JoystickSensor']}, - 'setCamera': {(replaceSimpleSetter, 'camera'): ['KX_SceneActuator']}, - 'setContinue': {(replaceSimpleSetter, 'useContinue'): ['BL_ActionActuator']}, - 'setDelay': {(replaceSimpleSetter, 'delay'): ['SCA_DelaySensor']}, - 'setDuration': {(replaceSimpleSetter, 'duration'): ['SCA_DelaySensor']}, - 'setEnd': {(replaceSimpleSetter, 'frameEnd'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, - 'setExecutePriority': {(replaceSimpleSetter, 'executePriority'): ['SCA_ILogicBrick']}, - 'setFile': {(replaceSimpleSetter, 'fileName'): ['KX_GameActuator']}, - 'setFilename': {(replaceSimpleSetter, 'fileName'): ['KX_SoundActuator']}, - 'setForceIpoActsLocal': {(replaceSimpleSetter, 'useIpoLocal'): ['KX_IpoActuator']}, - 'setFrame': {(replaceSimpleSetter, 'frame'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, - 'setFrameProperty': {(replaceSimpleSetter, 'framePropName'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'setFrequency': {(replaceSimpleSetter, 'frequency'): ['SCA_ISensor']}, - 'setGain': {(replaceSimpleSetter, 'volume'): ['KX_SoundActuator', 'KX_CDActuator']}, - 'setHeight': {(replaceSimpleSetter, 'height'): ['KX_CameraActuator']}, - 'setHold1': {(replaceSimpleSetter, 'hold1'): ['SCA_KeyboardSensor']}, - 'setHold2': {(replaceSimpleSetter, 'hold2'): ['SCA_KeyboardSensor']}, - 'setInvert': {(replaceSimpleSetter, 'invert'): ['SCA_ISensor']}, - 'setIpoAdd': {(replaceSimpleSetter, 'useIpoAdd'): ['KX_IpoActuator']}, - 'setIpoAsForce': {(replaceSimpleSetter, 'useIpoAsForce'): ['KX_IpoActuator']}, - 'setKey': {(replaceSimpleSetter, 'key'): ['SCA_KeyboardSensor']}, - 'setLevel': {(replaceSimpleSetter, 'level'): ['SCA_ISensor']}, - 'setLooping': {(replaceSimpleSetter, 'looping'): ['KX_SoundActuator']}, - 'setMask': {(replaceSimpleSetter, 'mask'): ['KX_StateActuator']}, - 'setMax': {(replaceSimpleSetter, 'max'): ['KX_CameraActuator']}, - 'setMesh': {(replaceSimpleSetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, - 'setMin': {(replaceSimpleSetter, 'min'): ['KX_CameraActuator']}, - 'setPitch': {(replaceSimpleSetter, 'pitch'): ['KX_SoundActuator']}, - 'setPriority': {(replaceSimpleSetter, 'priority'): ['BL_ShapeActionActuator', - 'BL_ActionActuator']}, - 'setProjectionMatrix': {(replaceSimpleSetter, 'projection_matrix'): ['KX_Camera']}, - 'setProperty': {(replaceSimpleSetter, 'propName'): ['KX_IpoActuator', - 'SCA_PropertySensor', - 'SCA_RandomActuator', - 'SCA_PropertyActuator']}, - 'setRepeat': {(replaceSimpleSetter, 'repeat'): ['SCA_DelaySensor']}, - 'setRollOffFactor': {(replaceSimpleSetter, 'rollOffFactor'): ['KX_SoundActuator']}, - 'setScene': {(replaceSimpleSetter, 'scene'): ['KX_SceneActuator']}, - 'setScript': {(replaceSimpleSetter, 'script'): ['SCA_PythonController']}, - 'setSeed': {(replaceSimpleSetter, 'seed'): ['SCA_RandomActuator']}, - 'setStart': {(replaceSimpleSetter, 'frameStart'): ['BL_ShapeActionActuator', - 'KX_IpoActuator', - 'BL_ActionActuator']}, - 'setState': {(replaceSimpleSetter, 'state'): ['KX_GameObject']}, - 'setSubject': {(replaceSimpleSetter, 'subject'): ['KX_NetworkMessageActuator']}, - 'setSubjectFilterText': {(replaceSimpleSetter, 'subject'): ['KX_NetworkMessageSensor']}, - 'setThreshold': {(replaceSimpleSetter, 'threshold'): ['SCA_JoystickSensor']}, - 'setTime': {(replaceSimpleSetter, 'time'): ['KX_SCA_AddObjectActuator', 'KX_TrackToActuator']}, - 'setToPropName': {(replaceSimpleSetter, 'propName'): ['KX_NetworkMessageActuator']}, - 'setType': {(replaceSimpleSetter, 'mode'): ['SCA_PropertySensor']}, - 'setUse3D': {(replaceSimpleSetter, 'use3D'): ['KX_TrackToActuator']}, - 'setUseNegPulseMode': {(replaceSimpleSetter, 'useNegPulseMode'): ['SCA_ISensor']}, - 'setUsePosPulseMode': {(replaceSimpleSetter, 'usePosPulseMode'): ['SCA_ISensor']}, - 'setUseRestart': {(replaceSimpleSetter, 'useRestart'): ['KX_SceneActuator']}, - 'setValue': {(replaceSimpleSetter, 'value'): ['SCA_PropertySensor', 'SCA_PropertyActuator']}, - 'setXY': {(replaceSimpleSetter, 'useXY'): ['KX_CameraActuator']} + 'getSensors': (replaceSimpleGetter, 'sensors'), # SCA_IController + 'getActuators': (replaceSimpleGetter, 'actuators'), # SCA_IController + 'enableViewport': (replaceSimpleSetter, 'useViewport'), # KX_Camera + 'getAction': (replaceSimpleGetter, 'action'), # BL_ShapeActionActuator, BL_ActionActuator + 'getAxis': (replaceSimpleGetter, 'axis'), # SCA_JoystickSensor + 'getAxisValue': (replaceSimpleGetter, 'axisValues'), # SCA_JoystickSensor + 'getBlendin': (replaceSimpleGetter, 'blendIn'), # BL_ShapeActionActuator, BL_ActionActuator + 'getBodies': (replaceSimpleGetter, 'bodies'), # KX_NetworkMessageSensor + 'getButton': (replaceSimpleGetter, 'button'), # SCA_JoystickSensor + 'getCamera': (replaceSimpleGetter, 'camera'), # KX_SceneActuator + 'getConeOrigin': (replaceSimpleGetter, 'coneOrigin'), # KX_RadarSensor + 'getConeTarget': (replaceSimpleGetter, 'coneTarget'), # KX_RadarSensor + 'getContinue': (replaceSimpleGetter, 'useContinue'), # BL_ActionActuator + 'getCurrentlyPressedKeys': (replaceSimpleGetter, 'events'), # SCA_KeyboardSensor + 'getDamping': (replaceSimpleGetter, 'damping'), # KX_ObjectActuator + 'getDelay': (replaceSimpleGetter, 'delay'), # SCA_DelaySensor + 'getDistribution': (replaceSimpleGetter, 'distribution'), # SCA_RandomActuator + 'getDuration': (replaceSimpleGetter, 'duration'), # SCA_DelaySensor + 'getEnd': (replaceSimpleGetter, 'frameEnd'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator + 'getExecutePriority': (replaceSimpleGetter, 'executePriority'), # SCA_ILogicBrick + 'getFile': (replaceSimpleGetter, 'fileName'), # KX_GameActuator + 'getFilename': (replaceSimpleGetter, 'fileName'), # KX_SoundActuator + 'getForceIpoActsLocal': (replaceSimpleGetter, 'useIpoLocal'), # KX_IpoActuator + 'getForceLimitX': (replaceSimpleGetter, 'forceLimitX'), # KX_ObjectActuator + 'getForceLimitY': (replaceSimpleGetter, 'forceLimitY'), # KX_ObjectActuator + 'getForceLimitZ': (replaceSimpleGetter, 'forceLimitZ'), # KX_ObjectActuator + 'getFrame': (replaceSimpleGetter, 'frame'), # BL_ShapeActionActuator, BL_ActionActuator + 'getFrameMessageCount': (replaceSimpleGetter, 'frameMessageCount'), # KX_NetworkMessageSensor + 'getFrameProperty': (replaceSimpleGetter, 'framePropName'), # BL_ShapeActionActuator, BL_ActionActuator + 'getFrequency': (replaceSimpleGetter, 'frequency'), # SCA_ISensor + 'getGain': (replaceSimpleGetter, 'volume'), # KX_SoundActuator, KX_CDActuator + 'getHat': (replaceSimpleGetter, 'hat'), # SCA_JoystickSensor + 'getHeight': (replaceSimpleGetter, 'height'), # KX_CameraActuator + 'getHitNormal': (replaceSimpleGetter, 'hitNormal'), # KX_MouseFocusSensor, KX_RaySensor + 'getHitObject': (replaceSimpleGetter, 'hitObject'), # KX_MouseFocusSensor, KX_RaySensor, KX_TouchSensor + 'getHitObjectList': (replaceSimpleGetter, 'hitObjectList'), # KX_TouchSensor + 'getHitPosition': (replaceSimpleGetter, 'hitPosition'), # KX_MouseFocusSensor, KX_RaySensor + 'getHold1': (replaceSimpleGetter, 'hold1'), # SCA_KeyboardSensor + 'getHold2': (replaceSimpleGetter, 'hold2'), # SCA_KeyboardSensor + 'getInvert': (replaceSimpleGetter, 'invert'), # SCA_ISensor + 'getIpoAdd': (replaceSimpleGetter, 'useIpoAdd'), # KX_IpoActuator + 'getIpoAsForce': (replaceSimpleGetter, 'useIpoAsForce'), # KX_IpoActuator + 'getKey': (replaceSimpleGetter, 'key'), # SCA_KeyboardSensor + 'getLastCreatedObject': (replaceSimpleGetter, 'objectLastCreated'), # KX_SCA_AddObjectActuator + 'getLevel': (replaceSimpleGetter, 'level'), # SCA_ISensor + 'getLightList': (replaceSimpleGetter, 'lights'), # KX_Scene + 'getLooping': (replaceSimpleGetter, 'looping'), # KX_SoundActuator + 'getMass': (replaceSimpleGetter, 'mass'), # KX_GameObject + 'getMax': (replaceSimpleGetter, 'max'), # KX_CameraActuator + 'getMin': (replaceSimpleGetter, 'min'), # KX_CameraActuator + 'getName': (replaceSimpleGetter, 'name'), # KX_Scene + 'getNumAxes': (replaceSimpleGetter, 'numAxis'), # SCA_JoystickSensor + 'getNumButtons': (replaceSimpleGetter, 'numButtons'), # SCA_JoystickSensor + 'getNumHats': (replaceSimpleGetter, 'numHats'), # SCA_JoystickSensor + 'getObjectList': (replaceSimpleGetter, 'objects'), # KX_Scene + 'getOperation': (replaceSimpleGetter, 'mode'), # KX_SCA_DynamicActuator + 'getOrientation': (replaceSimpleGetter, 'worldOrientation'), # KX_GameObject + 'getOwner': (replaceSimpleGetter, 'owner'), # SCA_ILogicBrick + 'getPara1': (replaceSimpleGetter, 'para1'), # SCA_RandomActuator + 'getPara2': (replaceSimpleGetter, 'para2'), # SCA_RandomActuator + 'getParent': (replaceSimpleGetter, 'parent'), # KX_GameObject + 'getPID': (replaceSimpleGetter, 'pid'), # KX_ObjectActuator + 'getPitch': (replaceSimpleGetter, 'pitch'), # KX_SoundActuator + 'getPosition': (replaceSimpleGetter, 'worldPosition'), # KX_GameObject + 'getPressedKeys': (replaceSimpleGetter, 'events'), # SCA_KeyboardSensor + 'getPriority': (replaceSimpleGetter, 'priority'), # BL_ShapeActionActuator, BL_ActionActuator + 'getProjectionMatrix': (replaceSimpleGetter, 'projection_matrix'), # KX_Camera + 'getProperty': (replaceSimpleGetter, 'propName'), # SCA_PropertySensor, SCA_RandomActuator, SCA_PropertyActuator + 'getRayDirection': (replaceSimpleGetter, 'rayDirection'), # KX_MouseFocusSensor, KX_RaySensor + 'getRaySource': (replaceSimpleGetter, 'raySource'), # KX_MouseFocusSensor + 'getRayTarget': (replaceSimpleGetter, 'rayTarget'), # KX_MouseFocusSensor + 'getRepeat': (replaceSimpleGetter, 'repeat'), # SCA_DelaySensor + 'getRollOffFactor': (replaceSimpleGetter, 'rollOffFactor'), # KX_SoundActuator + 'getScene': (replaceSimpleGetter, 'scene'), # KX_SceneActuator + 'getScript': (replaceSimpleGetter, 'script'), # SCA_PythonController + 'getSeed': (replaceSimpleGetter, 'seed'), # SCA_RandomActuator + 'getStart': (replaceSimpleGetter, 'frameStart'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator + 'getState': (replaceSimpleGetter, 'state'), # SCA_IController, KX_GameObject + 'getSubject': (replaceSimpleGetter, 'subject'), # KX_NetworkMessageSensor + 'getSubjects': (replaceSimpleGetter, 'subjects'), # KX_NetworkMessageSensor + 'getThreshold': (replaceSimpleGetter, 'threshold'), # SCA_JoystickSensor + 'getTime': (replaceSimpleGetter, 'time'), # KX_SCA_AddObjectActuator, KX_TrackToActuator + 'getTouchMaterial': (replaceSimpleGetter, 'useMaterial'), # KX_TouchSensor + 'getType': (replaceSimpleGetter, 'mode'), # SCA_PropertySensor + 'getUse3D': (replaceSimpleGetter, 'use3D'), # KX_TrackToActuator + 'getUseNegPulseMode': (replaceSimpleGetter, 'useNegPulseMode'), # SCA_ISensor + 'getUsePosPulseMode': (replaceSimpleGetter, 'usePosPulseMode'), # SCA_ISensor + 'getUseRestart': (replaceSimpleGetter, 'useRestart'), # KX_SceneActuator + 'getValue': (replaceSimpleGetter, 'value'), # SCA_PropertySensor, SCA_PropertyActuator + 'getVisible': (replaceSimpleGetter, 'visible'), # KX_GameObject + 'getXY': (replaceSimpleGetter, 'useXY'), # KX_CameraActuator + 'isConnected': (replaceSimpleGetter, 'connected'), # SCA_JoystickSensor + 'isPositive': (replaceSimpleGetter, 'positive'), # SCA_ISensor + 'isTriggered': (replaceSimpleGetter, 'triggered'), # SCA_ISensor + 'setActuator': (replaceSimpleSetter, 'actuator'), # SCA_ActuatorSensor + 'setBlendin': (replaceSimpleSetter, 'blendIn'), # BL_ShapeActionActuator, BL_ActionActuator + 'setBlendtime': (replaceSimpleSetter, 'blendTime'), # BL_ShapeActionActuator, BL_ActionActuator + 'setBodyType': (replaceSimpleSetter, 'usePropBody'), # KX_NetworkMessageActuator + 'setBody': (replaceSimpleSetter, 'body'), # KX_NetworkMessageActuator + 'setButton': (replaceSimpleSetter, 'button'), # SCA_JoystickSensor + 'setCamera': (replaceSimpleSetter, 'camera'), # KX_SceneActuator + 'setContinue': (replaceSimpleSetter, 'useContinue'), # BL_ActionActuator + 'setDamping': (replaceSimpleSetter, 'damping'), # KX_ObjectActuator + 'setDelay': (replaceSimpleSetter, 'delay'), # SCA_DelaySensor + 'setDuration': (replaceSimpleSetter, 'duration'), # SCA_DelaySensor + 'setEnd': (replaceSimpleSetter, 'frameEnd'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator + 'setExecutePriority': (replaceSimpleSetter, 'executePriority'), # SCA_ILogicBrick + 'setFile': (replaceSimpleSetter, 'fileName'), # KX_GameActuator + 'setFilename': (replaceSimpleSetter, 'fileName'), # KX_SoundActuator + 'setForceIpoActsLocal': (replaceSimpleSetter, 'useIpoLocal'), # KX_IpoActuator + 'setFrame': (replaceSimpleSetter, 'frame'), # BL_ShapeActionActuator, BL_ActionActuator + 'setFrameProperty': (replaceSimpleSetter, 'framePropName'), # BL_ShapeActionActuator, BL_ActionActuator + 'setFrequency': (replaceSimpleSetter, 'frequency'), # SCA_ISensor + 'setGain': (replaceSimpleSetter, 'volume'), # KX_SoundActuator, KX_CDActuator + 'setHeight': (replaceSimpleSetter, 'height'), # KX_CameraActuator + 'setHold1': (replaceSimpleSetter, 'hold1'), # SCA_KeyboardSensor + 'setHold2': (replaceSimpleSetter, 'hold2'), # SCA_KeyboardSensor + 'setInvert': (replaceSimpleSetter, 'invert'), # SCA_ISensor + 'setIpoAdd': (replaceSimpleSetter, 'useIpoAdd'), # KX_IpoActuator + 'setIpoAsForce': (replaceSimpleSetter, 'useIpoAsForce'), # KX_IpoActuator + 'setKey': (replaceSimpleSetter, 'key'), # SCA_KeyboardSensor + 'setLevel': (replaceSimpleSetter, 'level'), # SCA_ISensor + 'setLooping': (replaceSimpleSetter, 'looping'), # KX_SoundActuator + 'setMask': (replaceSimpleSetter, 'mask'), # KX_StateActuator + 'setMax': (replaceSimpleSetter, 'max'), # KX_CameraActuator + 'setMesh': (replaceSimpleSetter, 'mesh'), # KX_SCA_ReplaceMeshActuator + 'setMin': (replaceSimpleSetter, 'min'), # KX_CameraActuator + 'setPitch': (replaceSimpleSetter, 'pitch'), # KX_SoundActuator + 'setPriority': (replaceSimpleSetter, 'priority'), # BL_ShapeActionActuator, BL_ActionActuator + 'setProjectionMatrix': (replaceSimpleSetter, 'projection_matrix'), # KX_Camera + 'setProperty': (replaceSimpleSetter, 'propName'), # KX_IpoActuator, SCA_PropertySensor, SCA_RandomActuator, SCA_PropertyActuator + 'setRepeat': (replaceSimpleSetter, 'repeat'), # SCA_DelaySensor + 'setRollOffFactor': (replaceSimpleSetter, 'rollOffFactor'), # KX_SoundActuator + 'setScene': (replaceSimpleSetter, 'scene'), # KX_SceneActuator + 'setScript': (replaceSimpleSetter, 'script'), # SCA_PythonController + 'setSeed': (replaceSimpleSetter, 'seed'), # SCA_RandomActuator + 'setStart': (replaceSimpleSetter, 'frameStart'), # BL_ShapeActionActuator, KX_IpoActuator, BL_ActionActuator + 'setState': (replaceSimpleSetter, 'state'), # KX_GameObject + 'setSubject': (replaceSimpleSetter, 'subject'), # KX_NetworkMessageActuator + 'setSubjectFilterText': (replaceSimpleSetter, 'subject'), # KX_NetworkMessageSensor + 'setThreshold': (replaceSimpleSetter, 'threshold'), # SCA_JoystickSensor + 'setTime': (replaceSimpleSetter, 'time'), # KX_SCA_AddObjectActuator, KX_TrackToActuator + 'setToPropName': (replaceSimpleSetter, 'propName'), # KX_NetworkMessageActuator + 'setType': (replaceSimpleSetter, 'mode'), # SCA_PropertySensor + 'setUse3D': (replaceSimpleSetter, 'use3D'), # KX_TrackToActuator + 'setUseNegPulseMode': (replaceSimpleSetter, 'useNegPulseMode'), # SCA_ISensor + 'setUsePosPulseMode': (replaceSimpleSetter, 'usePosPulseMode'), # SCA_ISensor + 'setUseRestart': (replaceSimpleSetter, 'useRestart'), # KX_SceneActuator + 'setValue': (replaceSimpleSetter, 'value'), # SCA_PropertySensor, SCA_PropertyActuator + 'setXY': (replaceSimpleSetter, 'useXY'), # KX_CameraActuator # Unimplemented! - #'getLinearVelocity': {(replaceSimpleGetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, - #'setLinearVelocity': {(replaceSimpleSetter, 'linearVelocity'): ['KX_SCA_AddObjectActuator']}, - #'getAngularVelocity': {(replaceSimpleGetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, - #'setAngularVelocity': {(replaceSimpleSetter, 'angularVelocity'): ['KX_SCA_AddObjectActuator']}, - #'setAction': {(replaceSimpleSetter, 'action'): ['BL_ShapeActionActuator', 'BL_ActionActuator']}, - #'set': {(replaceSimpleSetter, 'visibility'): ['KX_VisibilityActuator']}, - #'getIndex': {(replaceSimpleGetter, 'index'): ['SCA_JoystickSensor']}, - #'getMesh': {(replaceSimpleGetter, 'mesh'): ['KX_SCA_ReplaceMeshActuator']}, - #'getObject': {(replaceSimpleGetter, 'object'): ['KX_SCA_AddObjectActuator', - # 'KX_CameraActuator', - # 'KX_TrackToActuator', - # 'KX_ParentActuator']}, - #'setIndex': {(replaceSimpleSetter, 'index'): ['SCA_JoystickSensor']}, - #'setObject': {(replaceSimpleSetter, 'object'): ['KX_SCA_AddObjectActuator', - # 'KX_CameraActuator', - # 'KX_TrackToActuator', - # 'KX_ParentActuator']}, - #'setOperation': {(replaceSimpleSetter, 'mode'): ['KX_SCA_DynamicActuator'], - # (replaceSimpleSetter, 'operation'): ['KX_StateActuator']}, + 'getLinearVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']), + 'setLinearVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']), + 'getAngularVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']), + 'setAngularVelocity': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_GameObject']), + 'setAction': (notImplemented, ['BL_ShapeActionActuator', 'BL_ActionActuator']), + 'set': (notImplemented, ['KX_VisibilityActuator', 'KX_IpoActuator']), + 'getIndex': (notImplemented, ['SCA_JoystickSensor']), + 'getMesh': (notImplemented, ['KX_SCA_ReplaceMeshActuator']), + 'getObject': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_CameraActuator', 'KX_TrackToActuator', 'KX_ParentActuator']), + 'setIndex': (notImplemented, ['SCA_JoystickSensor']), + 'setObject': (notImplemented, ['KX_SCA_AddObjectActuator', 'KX_CameraActuator', 'KX_TrackToActuator', 'KX_ParentActuator']), + 'setOperation': (notImplemented, ['KX_SCA_DynamicActuator', 'KX_StateActuator']), + 'position': (notImplemented, ['KX_GameObject', 'KX_SoundActuator']), + 'orientation': (notImplemented, ['KX_GameObject', 'KX_SoundActuator']), + 'getDRot': (notImplemented, ['KX_ObjectActuator']), + 'setDRot': (notImplemented, ['KX_ObjectActuator']), + 'getDLoc': (notImplemented, ['KX_ObjectActuator']), + 'setDLoc': (notImplemented, ['KX_ObjectActuator']), + 'getTorque': (notImplemented, ['KX_ObjectActuator']), + 'getTorque': (notImplemented, ['KX_ObjectActuator']), + 'getForce': (notImplemented, ['KX_ObjectActuator']), + 'setForce': (notImplemented, ['KX_ObjectActuator']), } -def convert248to249(lines, log = True, logErrors = True): +def convert248to249(lines, log = True, logErrors = True, fileName = None): # Regular expression for finding attributes. For the string 'a.b', this # returns three groups: ['a.b', 'a.', 'b']. The last is the attribute name. attrRegex = re.compile(r'\.\s*' # Dot r'([a-zA-Z_]\w*)') # Identifier + fileIdStr = "" + if fileName: + fileIdStr = fileName + ": " row = 0 - sourceRow = 0 col = 0 nconverted = 0 nerrors = 0 @@ -650,51 +714,34 @@ def convert248to249(lines, log = True, logErrors = True): attrName = match.group(1) if attributeRenameDict.has_key(attrName): # name is deprecated. - conversionDict = attributeRenameDict[attrName] - - if len(conversionDict.keys()) > 1: - # Ambiguous! Can't convert. - print "ERROR: source line %d, ambiguous conversion:" % sourceRow + func, closure = attributeRenameDict[attrName] + try: + # Convert! + func(lines, row, match.start(1), match.end(1), closure) + except ConversionError as e: + # Insert a comment saying the conversion failed. + print "ERROR: %sline %d, %s: %s\n" % ( + fileIdStr, row + 1, attrName, e) if logErrors: - lines.insert(row, "##248## ERROR: ambiguous conversion.\n") + lines.insert(row, + "##248## ERROR: %s: %s\n" % + (attrName, e)) row = row + 1 - for conversion in conversionDict.keys(): - _, newAttrName = conversion - classes = conversionDict[conversion] - print "\t%s -> %s (classes %s)" % (attrName, newAttrName, classes) - if logErrors: - lines.insert(row, "##248##%s -> %s (classes %s)\n" % - (attrName, newAttrName, classes)) - row = row + 1 nerrors = nerrors + 1 - else: - # Conversion is well-defined. Execute. - func, newAttrName = conversionDict.keys()[0] - try: - func(lines, row, match.start(1), match.end(1), newAttrName) - except ConversionError as e: - # Insert a comment saying the conversion failed. - print "ERROR: source line %d, %s: %s\n" % ( - sourceRow, attrName, e) - if logErrors: - lines.insert(row, - "##248## ERROR: %s: %s\n" % - (attrName, e)) - row = row + 1 - nerrors = nerrors + 1 - else: - changed = True - nconverted = nconverted + 1 + changed = True + nconverted = nconverted + 1 # Search the rest of this line. col = match.start(1) + if changed and log: + # Insert a comment to showing difference in lines. if originalLine[-1] != '\n': originalLine = originalLine + '\n' lines.insert(row, "##248##%s" % originalLine) row = row + 1 + row = row + 1 - sourceRow = sourceRow + 1 col = 0 return nconverted, nerrors @@ -774,12 +821,15 @@ def runAsTextPlugin(): Blender.SaveUndoState('Convert BGE 2.49') for txt in texts: + bufName = txt.name + if txt.lib: + bufName = txt.lib + '/' + bufName lines = txt.asLines() for i in range(0, len(lines)): if not lines[i].endswith('\n'): lines[i] = lines[i] + '\n' - nc, ne = convert248to249(lines) + nc, ne = convert248to249(lines, fileName = bufName) nconverted = nconverted + nc nerrors = nerrors + ne txt.clear() diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index a7ad29d5cfa..8a590a48c9e 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -2508,7 +2508,7 @@ class KX_TouchSensor(SCA_ISensor): """ Returns the property or material to collide with. Use getTouchMaterial() to find out whether this sensor - looks for properties or materials. (B{deprecated}) + looks for properties or materials. @deprecated: use the L{property} property @rtype: string @@ -2588,7 +2588,7 @@ class KX_NetworkMessageActuator(SCA_IActuator): """ Sets the message body. - deprecated: Use the L{body} attribute instead. + @deprecated: Use the L{body} attribute instead. @type body: string @param body: if the body type is True, this is the name of the property to send. if the body type is False, this is the text to send. @@ -2707,15 +2707,17 @@ class KX_ObjectActuator(SCA_IActuator): """ def getForce(): """ - Returns the force applied by the actuator. (B{deprecated}) - + Returns the force applied by the actuator. + + @deprecated: Use L{force} and L{useLocalForce} instead. @rtype: list [fx, fy, fz, local] @return: A four item list, containing the vector force, and a flag specifying whether the force is local. """ def setForce(fx, fy, fz, local): """ - Sets the force applied by the actuator. (B{deprecated}) + Sets the force applied by the actuator. + @deprecated: Use L{force} and L{useLocalForce} instead. @type fx: float @param fx: the x component of the force. @type fy: float @@ -2728,16 +2730,18 @@ class KX_ObjectActuator(SCA_IActuator): """ def getTorque(): """ - Returns the torque applied by the actuator. (B{deprecated}) + Returns the torque applied by the actuator. + @deprecated: Use L{torque} and L{useLocalTorque} instead. @rtype: list [S{Tau}x, S{Tau}y, S{Tau}z, local] @return: A four item list, containing the vector torque, and a flag specifying whether the torque is applied in local coordinates (True) or world coordinates (False) """ def setTorque(tx, ty, tz, local): """ - Sets the torque applied by the actuator. (B{deprecated}) + Sets the torque applied by the actuator. + @deprecated: Use L{torque} and L{useLocalTorque} instead. @type tx: float @param tx: the x component of the torque. @type ty: float @@ -2750,8 +2754,9 @@ class KX_ObjectActuator(SCA_IActuator): """ def getDLoc(): """ - Returns the displacement vector applied by the actuator. (B{deprecated}) + Returns the displacement vector applied by the actuator. + @deprecated: Use L{dLoc} and L{useLocalDLoc} instead. @rtype: list [dx, dy, dz, local] @return: A four item list, containing the vector displacement, and whether the displacement is applied in local coordinates (True) or world @@ -2759,12 +2764,13 @@ class KX_ObjectActuator(SCA_IActuator): """ def setDLoc(dx, dy, dz, local): """ - Sets the displacement vector applied by the actuator. (B{deprecated}) + Sets the displacement vector applied by the actuator. Since the displacement is applied every frame, you must adjust the displacement based on the frame rate, or you game experience will depend on the player's computer speed. + @deprecated: Use L{dLoc} and L{useLocalDLoc} instead. @type dx: float @param dx: the x component of the displacement vector. @type dy: float @@ -2777,20 +2783,22 @@ class KX_ObjectActuator(SCA_IActuator): """ def getDRot(): """ - Returns the angular displacement vector applied by the actuator. (B{deprecated}) + Returns the angular displacement vector applied by the actuator. + @deprecated: Use L{dRot} and L{useLocalDRot} instead. @rtype: list [dx, dy, dz, local] @return: A four item list, containing the angular displacement vector, and whether the displacement is applied in local coordinates (True) or world coordinates (False) """ def setDRot(dx, dy, dz, local): """ - Sets the angular displacement vector applied by the actuator. (B{deprecated}) + Sets the angular displacement vector applied by the actuator. Since the displacement is applied every frame, you must adjust the displacement based on the frame rate, or you game experience will depend on the player's computer speed. + @deprecated: Use L{dRot} and L{useLocalDRot} instead. @type dx: float @param dx: the x component of the angular displacement vector. @type dy: float @@ -2804,16 +2812,18 @@ class KX_ObjectActuator(SCA_IActuator): def getLinearVelocity(): """ Returns the linear velocity applied by the actuator. - For the servo control actuator, this is the target speed. (B{deprecated}) - + For the servo control actuator, this is the target speed. + + @deprecated: Use L{linV} and L{useLocalLinV} instead. @rtype: list [vx, vy, vz, local] @return: A four item list, containing the vector velocity, and whether the velocity is applied in local coordinates (True) or world coordinates (False) """ def setLinearVelocity(vx, vy, vz, local): """ Sets the linear velocity applied by the actuator. - For the servo control actuator, sets the target speed. (B{deprecated}) - + For the servo control actuator, sets the target speed. + + @deprecated: Use L{linV} and L{useLocalLinV} instead. @type vx: float @param vx: the x component of the velocity vector. @type vy: float @@ -2826,8 +2836,9 @@ class KX_ObjectActuator(SCA_IActuator): """ def getAngularVelocity(): """ - Returns the angular velocity applied by the actuator. (B{deprecated}) - + Returns the angular velocity applied by the actuator. + + @deprecated: Use L{angV} and L{useLocalAngV} instead. @rtype: list [S{omega}x, S{omega}y, S{omega}z, local] @return: A four item list, containing the vector velocity, and whether the velocity is applied in local coordinates (True) or world @@ -2835,8 +2846,9 @@ class KX_ObjectActuator(SCA_IActuator): """ def setAngularVelocity(wx, wy, wz, local): """ - Sets the angular velocity applied by the actuator. (B{deprecated}) - + Sets the angular velocity applied by the actuator. + + @deprecated: Use L{angV} and L{useLocalAngV} instead. @type wx: float @param wx: the x component of the velocity vector. @type wy: float @@ -2849,30 +2861,34 @@ class KX_ObjectActuator(SCA_IActuator): """ def getDamping(): """ - Returns the damping parameter of the servo controller. (B{deprecated}) - + Returns the damping parameter of the servo controller. + + @deprecated: Use L{damping} instead. @rtype: integer @return: the time constant of the servo controller in frame unit. """ def setDamping(damp): """ - Sets the damping parameter of the servo controller. (B{deprecated}) - + Sets the damping parameter of the servo controller. + + @deprecated: Use L{damping} instead. @type damp: integer @param damp: the damping parameter in frame unit. """ def getForceLimitX(): """ - Returns the min/max force limit along the X axis used by the servo controller. (B{deprecated}) - + Returns the min/max force limit along the X axis used by the servo controller. + + @deprecated: Use L{forceLimitX} instead. @rtype: list [min, max, enabled] @return: A three item list, containing the min and max limits of the force as float and whether the limits are active(true) or inactive(true) """ def setForceLimitX(min, max, enable): """ - Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller. (B{deprecated}) - + Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller. + + @deprecated: Use L{forceLimitX} instead. @type min: float @param min: the minimum value of the force along the X axis. @type max: float @@ -2883,16 +2899,18 @@ class KX_ObjectActuator(SCA_IActuator): """ def getForceLimitY(): """ - Returns the min/max force limit along the Y axis used by the servo controller. (B{deprecated}) - + Returns the min/max force limit along the Y axis used by the servo controller. + + @deprecated: Use L{forceLimitY} instead. @rtype: list [min, max, enabled] @return: A three item list, containing the min and max limits of the force as float and whether the limits are active(true) or inactive(true) """ def setForceLimitY(min, max, enable): """ - Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller. (B{deprecated}) - + Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller. + + @deprecated: Use L{forceLimitY} instead. @type min: float @param min: the minimum value of the force along the Y axis. @type max: float @@ -2903,16 +2921,18 @@ class KX_ObjectActuator(SCA_IActuator): """ def getForceLimitZ(): """ - Returns the min/max force limit along the Z axis used by the servo controller. (B{deprecated}) - + Returns the min/max force limit along the Z axis used by the servo controller. + + @deprecated: Use L{forceLimitZ} instead. @rtype: list [min, max, enabled] @return: A three item list, containing the min and max limits of the force as float and whether the limits are active(true) or inactive(true) """ def setForceLimitZ(min, max, enable): """ - Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller. (B{deprecated}) - + Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller. + + @deprecated: Use L{forceLimitZ} instead. @type min: float @param min: the minimum value of the force along the Z axis. @type max: float @@ -2923,8 +2943,9 @@ class KX_ObjectActuator(SCA_IActuator): """ def getPID(): """ - Returns the PID coefficient of the servo controller. (B{deprecated}) - + Returns the PID coefficient of the servo controller. + + @deprecated: Use L{pid} instead. @rtype: list [P, I, D] @return: A three item list, containing the PID coefficient as floats: P : proportional coefficient @@ -2933,8 +2954,9 @@ class KX_ObjectActuator(SCA_IActuator): """ def setPID(P, I, D): """ - Sets the PID coefficients of the servo controller. (B{deprecated}) - + Sets the PID coefficients of the servo controller. + + @deprecated: Use L{pid} instead. @type P: flat @param P: proportional coefficient @type I: float From 83bb096f24cb2252f90a77923bd1818930a2fed2 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sun, 24 May 2009 06:31:47 +0000 Subject: [PATCH 310/444] + renamed pad3 to m_contactProcessingThreshold (thanks Campbell Barton/ideasman for confirming it is ok to rename it) + fixed Python method, PyArg_ParseTuple already checks for errors, no returning of NULL, thanks Campbell too) + added linear/angular spring for each of the 6DOFs of a generic 6dof constraint. This makes the generic 6dof constraint very versatile. --- .../btGeneric6DofConstraint.cpp | 120 +++++++++++++++++- .../btGeneric6DofConstraint.h | 16 +++ source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/makesdna/DNA_object_types.h | 2 +- source/blender/src/buttons_logic.c | 4 +- .../Converter/BL_BlenderDataConversion.cpp | 2 +- .../Ketsji/KX_ConstraintWrapper.cpp | 17 +-- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 28 +++- 9 files changed, 172 insertions(+), 21 deletions(-) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index 9644f2b6d57..2edf28c6bac 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -22,9 +22,11 @@ http://gimpact.sf.net #include "btGeneric6DofConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" +#include "LinearMath/btTransformUtil.h" #include + #define D6_USE_OBSOLETE_METHOD false @@ -738,7 +740,9 @@ int btGeneric6DofConstraint::get_limit_motor_info2( } // if we're limited low and high simultaneously, the joint motor is // ineffective - if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = 0; + if (limit && (limot->m_loLimit == limot->m_hiLimit)) + powered = 0; + info->m_constraintError[srow] = btScalar(0.f); if (powered) { @@ -827,3 +831,117 @@ int btGeneric6DofConstraint::get_limit_motor_info2( +btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) + : btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA) +{ + for(int i = 0; i < 6; i++) + { + m_springEnabled[i] = false; + m_equilibriumPoint[i] = btScalar(0.f); + m_springStiffness[i] = btScalar(0.f); + } +} + + +void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff) +{ + btAssert((index >= 0) && (index < 6)); + m_springEnabled[index] = onOff; + if(index < 3) + { + m_linearLimits.m_enableMotor[index] = onOff; + } + else + { + m_angularLimits[index - 3].m_enableMotor = onOff; + } +} + + + +void btGeneric6DofSpringConstraint::setStiffness(int index, btScalar stiffness) +{ + btAssert((index >= 0) && (index < 6)); + m_springStiffness[index] = stiffness; +} + + +void btGeneric6DofSpringConstraint::setEquilibriumPoint() +{ + calculateTransforms(); + for(int i = 0; i < 3; i++) + { + m_equilibriumPoint[i] = m_calculatedLinearDiff[i]; + } + for(int i = 0; i < 3; i++) + { + m_equilibriumPoint[i + 3] = m_calculatedAxisAngleDiff[i]; + } +} + + + +void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index) +{ + btAssert((index >= 0) && (index < 6)); + calculateTransforms(); + if(index < 3) + { + m_equilibriumPoint[index] = m_calculatedLinearDiff[index]; + } + else + { + m_equilibriumPoint[index + 3] = m_calculatedAxisAngleDiff[index]; + } +} + + + +void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* info) +{ + // it is assumed that calculateTransforms() have been called before this call + int i; + btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity(); + for(i = 0; i < 3; i++) + { + if(m_springEnabled[i]) + { + // get current position of constraint + btScalar currPos = m_calculatedLinearDiff[i]; + // calculate difference + btScalar delta = currPos - m_equilibriumPoint[i]; + // spring force is (delta * m_stiffness) according to Hooke's Law + btScalar force = delta * m_springStiffness[i]; + m_linearLimits.m_targetVelocity[i] = force * info->fps; + m_linearLimits.m_maxMotorForce[i] = btFabs(force) / info->fps; + } + } + for(i = 0; i < 3; i++) + { + if(m_springEnabled[i + 3]) + { + // get current position of constraint + btScalar currPos = m_calculatedAxisAngleDiff[i]; + // calculate difference + btScalar delta = currPos - m_equilibriumPoint[i+3]; + // spring force is (-delta * m_stiffness) according to Hooke's Law + btScalar force = -delta * m_springStiffness[i+3]; + m_angularLimits[i].m_targetVelocity = force * info->fps; + m_angularLimits[i].m_maxMotorForce = btFabs(force) / info->fps; + } + } +} + + +void btGeneric6DofSpringConstraint::getInfo2(btConstraintInfo2* info) +{ + // this will be called by constraint solver at the constraint setup stage + // set current motor parameters + internalUpdateSprings(info); + // do the rest of job for constraint setup + btGeneric6DofConstraint::getInfo2(info); +} + + + + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h index 5af866390ee..33e4749ffd0 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -478,4 +478,20 @@ public: }; +class btGeneric6DofSpringConstraint : public btGeneric6DofConstraint +{ +protected: + bool m_springEnabled[6]; + btScalar m_equilibriumPoint[6]; + btScalar m_springStiffness[6]; + void internalUpdateSprings(btConstraintInfo2* info); +public: + btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + void enableSpring(int index, bool onOff); + void setStiffness(int index, btScalar stiffness); + void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF + void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF + virtual void getInfo2 (btConstraintInfo2* info); +}; + #endif //GENERIC_6DOF_CONSTRAINT_H diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9739668c7c7..ec068c35c11 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -985,7 +985,7 @@ Object *add_only_object(int type, char *name) ob->gameflag= OB_PROP|OB_COLLISION; ob->margin = 0.0; /* ob->pad3 == Contact Processing Threshold */ - ob->pad3 = 1.; + ob->m_contactProcessingThreshold = 1.; /* NT fluid sim defaults */ ob->fluidsimFlag = 0; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0b0a97b7ec0..d8566e06ed7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8110,7 +8110,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Object *ob; World *wrld; for(ob = main->object.first; ob; ob= ob->id.next) { - ob->pad3 = 1.; //pad3 is used for m_contactProcessingThreshold + ob->m_contactProcessingThreshold = 1.; //pad3 is used for m_contactProcessingThreshold if(ob->parent) { /* check if top parent has compound shape set and if yes, set this object to compound shaper as well (was the behaviour before, now it's optional) */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 11fa44fe488..741822b5a98 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -159,7 +159,7 @@ typedef struct Object { float margin; float max_vel; /* clamp the maximum velocity 0.0 is disabled */ float min_vel; /* clamp the maximum velocity 0.0 is disabled */ - float pad3; /* pad3 is now used for m_contactProcessingThreshold, can we still rename it? */ + float m_contactProcessingThreshold; char dt, dtx; char totcol; /* copy of mesh or curve or meta */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index b0ce3c8a95b..c283cd18ca2 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3204,7 +3204,7 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) if (ob->gameflag & OB_RIGID_BODY) { uiDefButF(block, NUM, 0, "CPT", - xco+180, yco, 180, 19, &ob->pad3, 0.00, 1., 1, 0, + xco+180, yco, 180, 19, &ob->m_contactProcessingThreshold, 0.00, 1., 1, 0, "Contact Processing Threshold"); yco -= 20; @@ -3287,7 +3287,7 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) xco, yco, 180, 19, &ob->margin, 0.0, 1.0, 1, 0, "Collision margin"); uiDefButF(block, NUM, 0, "CPT", - xco+180, yco, 180, 19, &ob->pad3, 0.00, 1., 1, 0, + xco+180, yco, 180, 19, &ob->m_contactProcessingThreshold, 0.00, 1., 1, 0, "Contact Processing Threshold"); } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index a9c839595c2..d9e93d41f34 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1422,7 +1422,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic' if (objprop.m_angular_rigidbody || !objprop.m_dyna ) { - objprop.m_contactProcessingThreshold = blenderobject->pad3; + objprop.m_contactProcessingThreshold = blenderobject->m_contactProcessingThreshold; } else { objprop.m_contactProcessingThreshold = 0.f; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index b0576424a47..b40100db2f7 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -59,22 +59,17 @@ PyObject* KX_ConstraintWrapper::PySetParam(PyObject* args, PyObject* kwds) int len = PyTuple_Size(args); int success = 1; - if (len == 3) + int dof; + float minLimit,maxLimit; + success = PyArg_ParseTuple(args,"iff:setParam",&dof,&minLimit,&maxLimit); + if (success) { - int dof; - float minLimit,maxLimit; - success = PyArg_ParseTuple(args,"iff",&dof,&minLimit,&maxLimit); - if (success) - { - m_physenv->setConstraintParam(m_constraintId,dof,minLimit,maxLimit); - Py_RETURN_NONE; - } + m_physenv->setConstraintParam(m_constraintId,dof,minLimit,maxLimit); } - return NULL; + Py_RETURN_NONE; } - //python specific stuff PyTypeObject KX_ConstraintWrapper::Type = { #if (PY_VERSION_HEX >= 0x02060000) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 561c370854f..58720c8cc30 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -922,7 +922,7 @@ int CcdPhysicsEnvironment::createUniversalD6Constraint( bool useReferenceFrameA = true; - genericConstraint = new btGeneric6DofConstraint( + genericConstraint = new btGeneric6DofSpringConstraint( *rb0,*rb1, frameInA,frameInB,useReferenceFrameA); genericConstraint->setLinearLowerLimit(linearMinLimits); @@ -1831,6 +1831,28 @@ void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float break; } + case 12: case 13: case 14: case 15: case 16: case 17: + { + //param 13-17 are for motorized springs on each of the degrees of freedom + btGeneric6DofSpringConstraint* genCons = (btGeneric6DofSpringConstraint*)typedConstraint; + int springIndex = param-12; + if (value0!=0.f) + { + bool springEnabled = true; + genCons->setStiffness(springIndex,value0); + genCons->enableSpring(springIndex,springEnabled); + if (value1>0.5f) + { + genCons->setEquilibriumPoint(springIndex); + } + } else + { + bool springEnabled = false; + genCons->enableSpring(springIndex,springEnabled); + } + break; + } + default: { } @@ -2351,7 +2373,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl frameInB = inv * globalFrameA; bool useReferenceFrameA = true; - genericConstraint = new btGeneric6DofConstraint( + genericConstraint = new btGeneric6DofSpringConstraint( *rb0,*rb1, frameInA,frameInB,useReferenceFrameA); @@ -2375,7 +2397,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl frameInB = rb0->getCenterOfMassTransform() * frameInA; bool useReferenceFrameA = true; - genericConstraint = new btGeneric6DofConstraint( + genericConstraint = new btGeneric6DofSpringConstraint( *rb0,s_fixedObject2, frameInA,frameInB,useReferenceFrameA); } From e41eeaa0451c8affeda8b9ff44a60d804d8622cc Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 24 May 2009 12:53:49 +0000 Subject: [PATCH 311/444] BGE: renamed sensor type enum to avoid conflict with mingw (NEAR was causing the problem). --- source/gameengine/GameLogic/SCA_ISensor.h | 10 +++++----- source/gameengine/Ketsji/KX_NearSensor.h | 2 +- source/gameengine/Ketsji/KX_RadarSensor.h | 2 +- source/gameengine/Ketsji/KX_TouchEventManager.cpp | 2 +- source/gameengine/Ketsji/KX_TouchSensor.h | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index ad8865299d6..9bbd6ed41e4 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -93,10 +93,10 @@ protected: public: enum sensortype { - NONE = 0, - TOUCH, - NEAR, - RADAR, + ST_NONE = 0, + ST_TOUCH, + ST_NEAR, + ST_RADAR, // to be updated as needed }; @@ -147,7 +147,7 @@ public: virtual double GetNumber(); - virtual sensortype GetSensorType() { return NONE; } + virtual sensortype GetSensorType() { return ST_NONE; } /** Stop sensing for a while. */ void Suspend(); diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index d98b464a443..63099e181a0 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -78,7 +78,7 @@ public: const PHY_CollData * coll_data); virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2); virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2) { return false; }; - virtual sensortype GetSensorType() { return NEAR; } + virtual sensortype GetSensorType() { return ST_NEAR; } /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 6779a9edffe..2e5a0e68bed 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -92,7 +92,7 @@ public: virtual PyObject* py_getattro(PyObject *attr); virtual PyObject* py_getattro_dict(); virtual int py_setattro(PyObject *attr, PyObject* value); - virtual sensortype GetSensorType() { return RADAR; } + virtual sensortype GetSensorType() { return ST_RADAR; } //Deprecated -----> KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin); diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 46927541099..9603410c3ac 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -105,7 +105,7 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data, it != info->m_sensors.end(); ++it) { - if ((*it)->GetSensorType() == SCA_ISensor::TOUCH) + if ((*it)->GetSensorType() == SCA_ISensor::ST_TOUCH) { KX_TouchSensor* touchsensor = static_cast(*it); if (touchsensor->BroadPhaseSensorFilterCollision(object1, object2)) diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index b62ec6eaf4d..476c63e89db 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -104,7 +104,7 @@ public: // return value = true if collision should be checked on pair of object virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2) { return true; } virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2); - virtual sensortype GetSensorType() { return TOUCH; } + virtual sensortype GetSensorType() { return ST_TOUCH; } virtual bool IsPositiveTrigger() { From ea94f8ab8a2cbe7ccfb4914ef6441c3be7ac0e60 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 24 May 2009 13:41:37 +0000 Subject: [PATCH 312/444] == Sequencer == This adds custom proxy file storage to the sequencer. Reasoning: sometimes low resolution versions are already available as a seperate file built by the capture application. So there is no real reason to make blender build it's own seperate proxy. This also somewhat fixes (aehm works around :) ) [#13632] Creating Proxy Takes Over Process, Should be Background Since now you can just fire up ffmpeg to build your proxies in the background. (You could have done before and build a directory of jpeg files, but then you would have to rename all the files since otherwise things are off by one...) --- source/blender/blenloader/intern/readfile.c | 1 + source/blender/include/butspace.h | 3 +- source/blender/makesdna/DNA_sequence_types.h | 3 ++ source/blender/src/buttons_scene.c | 56 ++++++++++++++++---- source/blender/src/sequence.c | 42 +++++++++++++++ 5 files changed, 94 insertions(+), 11 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d8566e06ed7..d9df1ee4419 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3689,6 +3689,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) if (seq->flag & SEQ_USE_PROXY) { seq->strip->proxy = newdataadr( fd, seq->strip->proxy); + seq->strip->proxy->anim = 0; } else { seq->strip->proxy = 0; } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 8a9c1933c97..8aaf4a7c65b 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -318,7 +318,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la /* *********************** */ #define B_RENDERBUTS 1690 -#define B_SEQUENCERBUTS 1699 +#define B_SEQUENCERBUTS 1700 #define B_FS_PIC 1601 #define B_FS_BACKBUF 1602 @@ -377,6 +377,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_SEQ_BUT_RELOAD_FILE 1696 #define B_SEQ_BUT_REBUILD_PROXY 1697 #define B_SEQ_SEL_PROXY_DIR 1698 +#define B_SEQ_SEL_PROXY_FILE 1699 /* *********************** */ #define B_ARMATUREBUTS 1800 #define B_POSE 1701 diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 7bad8ec3b44..801b283a6c2 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -78,6 +78,8 @@ typedef struct StripColorBalance { typedef struct StripProxy { char dir[160]; + char file[80]; + struct anim *anim; } StripProxy; typedef struct Strip { @@ -258,6 +260,7 @@ typedef struct SpeedControlVars { #define SEQ_USE_COLOR_BALANCE 262144 #define SEQ_USE_PROXY_CUSTOM_DIR 524288 #define SEQ_ACTIVE 1048576 +#define SEQ_USE_PROXY_CUSTOM_FILE 2097152 #define SEQ_COLOR_BALANCE_INVERSE_GAIN 1 #define SEQ_COLOR_BALANCE_INVERSE_GAMMA 2 diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 3036bb78da8..f99ac47b2c5 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1174,7 +1174,7 @@ static void seq_panel_proxy() uiDefButBitI(block, TOG, SEQ_USE_PROXY, B_SEQ_BUT_RELOAD, "Use Proxy", - 10,140,120,19, &last_seq->flag, + 10,140,80,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Use a preview proxy for this strip"); @@ -1187,10 +1187,16 @@ static void seq_panel_proxy() uiDefButBitI(block, TOG, SEQ_USE_PROXY_CUSTOM_DIR, B_SEQ_BUT_RELOAD, "Custom Dir", - 130,140,120,19, &last_seq->flag, + 90,140,80,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Use a custom directory to store data"); + uiDefButBitI(block, TOG, SEQ_USE_PROXY_CUSTOM_FILE, + B_SEQ_BUT_RELOAD, "Custom File", + 170,140,80,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Use a custom file to load data from"); + if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) { uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR, ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0, @@ -1202,30 +1208,41 @@ static void seq_panel_proxy() 30,120,220,20, last_seq->strip->proxy->dir, 0.0, 160.0, 100, 0, ""); } + if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_FILE, + ICON_FILESEL, 10, 100, 20, 20, 0, 0, 0, + 0, 0, + "Select the custom proxy file " + "(used for all preview resolutions!)"); + + uiDefBut(block, TEX, + B_SEQ_BUT_RELOAD, "File: ", + 30,100,220,20, last_seq->strip->proxy->file, + 0.0, 160.0, 100, 0, ""); + } } if (last_seq->flag & SEQ_USE_PROXY) { if (G.scene->r.size == 100) { uiDefBut(block, LABEL, 0, "Full render size selected, ", - 10,100,240,19, 0, 0, 0, 0, 0, ""); + 10,60,240,19, 0, 0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "so no proxy enabled!", - 10,80,240,19, 0, 0, 0, 0, 0, ""); + 10,40,240,19, 0, 0, 0, 0, 0, ""); } else if (last_seq->type != SEQ_MOVIE && last_seq->type != SEQ_IMAGE && !(last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) { uiDefBut(block, LABEL, 0, "Cannot proxy this strip without ", - 10,100,240,19, 0, 0, 0, 0, 0, ""); + 10,60,240,19, 0, 0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "custom directory selection!", - 10,80,240,19, 0, 0, 0, 0, 0, ""); - - } else { + 10,40,240,19, 0, 0, 0, 0, 0, ""); + } else if (!(last_seq->flag & SEQ_USE_PROXY_CUSTOM_FILE)) { uiDefBut(block, BUT, B_SEQ_BUT_REBUILD_PROXY, "Rebuild proxy", - 10,100,240,19, 0, 0, 0, 0, 0, + 10,60,240,19, 0, 0, 0, 0, 0, "Rebuild proxy for the " "currently selected strip."); } @@ -1294,7 +1311,19 @@ static void sel_proxy_dir(char *name) allqueue(REDRAWBUTSSCENE, 0); - BIF_undo_push("Change proxy directory"); + BIF_undo_push("Change custom proxy directory"); +} + +static void sel_proxy_file(char *name) +{ + Sequence *last_seq = get_last_seq(); + + BLI_split_dirfile_basic(name, last_seq->strip->proxy->dir, + last_seq->strip->proxy->file); + + allqueue(REDRAWBUTSSCENE, 0); + + BIF_undo_push("Change custom proxy file"); } void do_sequencer_panels(unsigned short event) @@ -1324,6 +1353,13 @@ void do_sequencer_panels(unsigned short event) last_seq->strip->proxy->dir, sel_proxy_dir); break; + case B_SEQ_SEL_PROXY_FILE: + sa= closest_bigger_area(); + areawinset(sa->win); + activate_fileselect(FILE_SPECIAL, "SELECT PROXY FILE", + last_seq->strip->proxy->dir, + sel_proxy_file); + break; case B_SEQ_BUT_RELOAD: case B_SEQ_BUT_RELOAD_ALL: update_seq_ipo_rect(last_seq); diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index edc68d016a1..d94f30a2bdb 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -106,6 +106,14 @@ void free_tstripdata(int len, TStripElem *se) } +static void free_proxy_seq(Sequence *seq) +{ + if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) { + IMB_free_anim(seq->strip->proxy->anim); + seq->strip->proxy->anim = 0; + } +} + void free_strip(Strip *strip) { strip->us--; @@ -120,6 +128,10 @@ void free_strip(Strip *strip) } if (strip->proxy) { + if (strip->proxy->anim) { + IMB_free_anim(strip->proxy->anim); + } + MEM_freeN(strip->proxy); } if (strip->crop) { @@ -517,6 +529,8 @@ void reload_sequence_new_file(Sequence * seq) seq->strip->len = seq->len; } + free_proxy_seq(seq); + calc_sequence(seq); } @@ -1053,6 +1067,12 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name) } } + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + snprintf(name, PROXY_MAXFILE, "%s/%s", + dir, seq->strip->proxy->file); + return TRUE; + } + /* generate a seperate proxy directory for each preview size */ if (seq->type == SEQ_IMAGE) { @@ -1099,6 +1119,20 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) return 0; } + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + if (!seq->strip->proxy->anim) { + if (!seq_proxy_get_fname(seq, cfra, name)) { + return 0; + } + + seq->strip->proxy->anim = openanim(name, IB_rect); + } + if (!seq->strip->proxy->anim) { + return 0; + } + return IMB_anim_absolute(seq->strip->proxy->anim, cfra); + } + if (!seq_proxy_get_fname(seq, cfra, name)) { return 0; } @@ -1131,6 +1165,11 @@ static void seq_proxy_build_frame(Sequence * seq, int cfra) return; } + /* that's why it is called custom... */ + if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + return; + } + if (!seq_proxy_get_fname(seq, cfra, name)) { return; } @@ -2866,6 +2905,7 @@ void free_imbuf_seq_except(int cfra) if(seq->type==SEQ_MOVIE) if(seq->startdisp > cfra || seq->enddisp < cfra) free_anim_seq(seq); + free_proxy_seq(seq); } } END_SEQ @@ -2909,6 +2949,7 @@ void free_imbuf_seq() if(seq->type==SEQ_SPEED) { sequence_effect_speed_rebuild_map(seq, 1); } + free_proxy_seq(seq); } } END_SEQ @@ -2974,6 +3015,7 @@ static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int l if(seq->type == SEQ_SPEED) { sequence_effect_speed_rebuild_map(seq, 1); } + free_proxy_seq(seq); } if(len_change) From 95e14ac4d3f1d2e399ea8e5646da3841544054d7 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 24 May 2009 14:11:16 +0000 Subject: [PATCH 313/444] == Sequencer == Fixed output rescaling, when changing between preview proxy rendering and final resolution. --- source/blender/src/drawseq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index f54ac186a21..6bba4fbdcc4 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -930,6 +930,7 @@ static void draw_image_seq(ScrArea *sa) zoom= SEQ_ZOOM_FAC(sseq->zoom); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + zoom /= G.scene->r.size / 100.0; zoomx = zoom * ((float)G.scene->r.xasp / (float)G.scene->r.yasp); zoomy = zoom; } else { From e5509b98ce253fddc7fdc85beb03702bf1d83254 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 24 May 2009 14:14:58 +0000 Subject: [PATCH 314/444] == Sequencer == Made relative paths work with custom proxy files. --- source/blender/src/sequence.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index d94f30a2bdb..e26df73b673 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1068,8 +1068,10 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name) } if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { - snprintf(name, PROXY_MAXFILE, "%s/%s", - dir, seq->strip->proxy->file); + BLI_join_dirfile(name, dir, seq->strip->proxy->file); + BLI_convertstringcode(name, G.sce); + BLI_convertstringframe(name, cfra); + return TRUE; } From 2f0ec4b7fc10bbf178220a67acd335e7ae82f7d8 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Sun, 24 May 2009 16:22:09 +0000 Subject: [PATCH 315/444] User Interface -------------- Bugfix 18817: DataBrowse for MTex used Material IDs instead of Texture IDs. --- source/blender/src/headerbuttons.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index f4135071e3e..17d16924ae6 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -896,10 +896,10 @@ void do_global_buttons(unsigned short event) } } if(G.qual & LR_CTRLKEY) { - activate_databrowse_imasel((ID*)lockpoin, ID_TE, 0, B_TEXBROWSE, menunr, do_global_buttons); + activate_databrowse_imasel(id, ID_TE, 0, B_TEXBROWSE, menunr, do_global_buttons); } else { - activate_databrowse((ID*)lockpoin, ID_TE, 0, B_TEXBROWSE, menunr, do_global_buttons); + activate_databrowse(id, ID_TE, 0, B_TEXBROWSE, menunr, do_global_buttons); } return; } From 4f7264ee529f980fa2635d7a3fa6ea1492c86f81 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sun, 24 May 2009 19:21:54 +0000 Subject: [PATCH 316/444] Action actuator default value changed from 0.0 to 1.0. Bookmark renamed to Mark and other small logic tooltip changes - IPOs and actions start it's frame counting in frame 1, not zero. - Talked with Ben and we agreed to rename the "bookmark" feature before an official release. - some English typos. - removed all period in the end of tooltips for consistency's sake. * note: I resisted one more time to the temptation of alphabetical ordering the Sensors and Actuators. That will be the first thing I would like to do after we are done with 2.49 :) It really annoys me as a user. --- source/blender/src/buttons_logic.c | 108 ++++++++++++++--------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index c283cd18ca2..b8c851f5ab8 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1155,11 +1155,11 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short uiDefButBitS(block, TOG, SENS_COLLISION_PULSE, B_REDR, "Pulse",(short)(xco + 10),(short)(yco - 44), (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, - "Changes to the set of colliding objects generate pulses"); + "Changes to the set of colliding objects generated pulses"); uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P",(short)(xco + 10 + (0.20 * (width-20))),(short)(yco - 44), (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, - "Toggle collision on material or property."); + "Toggle collision on material or property"); if (cs->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.40 * (width-20)), @@ -1215,12 +1215,12 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short uiDefButS(block, MENU, B_REDR, str, (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19, &rs->axis, 2.0, 31, 0, 0, - "Specify along which axis the radar cone is cast."); + "Specify along which axis the radar cone is cast"); uiDefButF(block, NUM, 1, "Ang:", (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19, &rs->angle, 0.0, 179.9, 10, 0, - "Opening angle of the radar cone."); + "Opening angle of the radar cone"); uiDefButF(block, NUM, 1, "Dist:", (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19, &rs->range, 0.01, 10000.0, 100, 0, @@ -1263,14 +1263,14 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19, ks->toggleName, 0, 31, 0, 0, "Property that indicates whether to log " - "keystrokes as a string."); + "keystrokes as a string"); /* line 5: target property for string logging mode */ uiDefBut(block, TEX, 1, "Target: ", xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19, ks->targetName, 0, 31, 0, 0, "Property that receives the keystrokes in case " - "a string is logged."); + "a string is logged"); yco-= ysize; break; @@ -1369,7 +1369,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, width-20, 19, &ms->type, 0, 31, 0, 0, - "Specify the type of event this mouse sensor should trigger on."); + "Specify the type of event this mouse sensor should trigger on"); yco-= ysize; break; @@ -1406,7 +1406,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P", xco + 10,yco - 44, 0.20 * (width-20), 19, &raySens->mode, 0.0, 0.0, 0, 0, - "Toggle collision on material or property."); + "Toggle collision on material or property"); if (raySens->mode & SENS_COLLISION_MATERIAL) { @@ -1435,7 +1435,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, &raySens->axisflag, 2.0, 31, 0, 0, - "Specify along which axis the ray is cast."); + "Specify along which axis the ray is cast"); yco-= ysize; break; @@ -1482,7 +1482,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short str= "Type %t|Button %x0|Axis %x1|Single Axis %x3|Hat%x2"; uiDefButC(block, MENU, B_REDR, str, xco+87, yco-44, 0.26 * (width-20), 19, &joy->type, 0, 31, 0, 0, - "The type of event this joystick sensor is triggered on."); + "The type of event this joystick sensor is triggered on"); if (joy->type != SENS_JOY_AXIS_SINGLE) { if (joy->flag & SENS_JOY_ANY_EVENT) { @@ -1518,7 +1518,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short { uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, &joy->axis, 1, 8.0, 100, 0, - "Specify which axis pair to use, 1 is useually the main direction input."); + "Specify which axis pair to use, 1 is useually the main direction input"); uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20),yco-44, 0.4 * (width-20), 19, &joy->precision, 0, 32768.0, 100, 0, @@ -1606,8 +1606,8 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco if(pc->mode==0) uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+90,yco-24,width-90, 19, &pc->text, "Blender textblock to run as a script"); else { - uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run eg \"someModule.main\", internal texts external python files can be used"); - uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restrting"); + uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used"); + uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting"); } uiBlockEndAlign(block); @@ -1837,13 +1837,13 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefBut(block, LABEL, 0, "Ref", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, ""); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+45, yco-45, wval*3, 19, &(oa->reference), "Reference object for velocity calculation, leave empty for world reference"); - uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Sets the target relative linear velocity, it will be achieve by automatic application of force. Null velocity is a valid target"); + uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Sets the target relative linear velocity, it will be achieved by automatic application of force. Null velocity is a valid target"); uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-68, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates"); - uiDefBut(block, LABEL, 0, "Limit", xco, yco-91, 45, 19, NULL, 0, 0, 0, 0, "Select if the force need to be limited along certain axis (local or global depending on LinV Local flag)"); + uiDefBut(block, LABEL, 0, "Limit", xco, yco-91, 45, 19, NULL, 0, 0, 0, 0, "Select if the force needs to be limited along certain axis (local or global depending on LinV Local flag)"); uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X", xco+45, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis"); uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y", xco+45+wval, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis"); uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z", xco+45+2*wval, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis"); @@ -1911,8 +1911,8 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh } else { - uiDefButI(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame"); - uiDefButI(block, NUM, 0, "End: ",xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame"); + uiDefButI(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 1.0, MAXFRAMEF, 0, 0, "Start frame"); + uiDefButI(block, NUM, 0, "End: ",xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 1.0, MAXFRAMEF, 0, 0, "End frame"); } uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending"); @@ -1963,7 +1963,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, "L", xco+width-30, yco-24, 20, 19, &ia->flag, 0, 0, 0, 0, - "Let the ipo acts in local coordinates, used in Force and Add mode."); + "Let the ipo acts in local coordinates, used in Force and Add mode"); } if(ia->type==ACT_IPO_FROM_PROP) { @@ -1989,7 +1989,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefBut(block, TEX, 0, "FrameProp: ", xco+10, yco-64, width-20, 19, ia->frameProp, 0.0, 31.0, 0, 0, - "Assign this property this action current frame number"); + "Assign the action's current frame number to this property"); yco-= ysize; break; @@ -2133,16 +2133,16 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh wval= (width-60)/3; uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, - "Velocity upon creation."); + "Velocity upon creation"); uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, eoa->linVelocity, -100.0, 100.0, 10, 0, - "Velocity upon creation, x component."); + "Velocity upon creation, x component"); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, eoa->linVelocity+1, -100.0, 100.0, 10, 0, - "Velocity upon creation, y component."); + "Velocity upon creation, y component"); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, eoa->linVelocity+2, -100.0, 100.0, 10, 0, - "Velocity upon creation, z component."); + "Velocity upon creation, z component"); uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19, &eoa->localflag, 0.0, 0.0, 0, 0, "Apply the transformation locally"); @@ -2150,16 +2150,16 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefBut(block, LABEL, 0, "AngV", xco, yco-90, 45, 19, NULL, 0, 0, 0, 0, - "Angular velocity upon creation."); + "Angular velocity upon creation"); uiDefButF(block, NUM, 0, "", xco+45, yco-90, wval, 19, eoa->angVelocity, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, x component."); + "Angular velocity upon creation, x component"); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-90, wval, 19, eoa->angVelocity+1, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, y component."); + "Angular velocity upon creation, y component"); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-90, wval, 19, eoa->angVelocity+2, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, z component."); + "Angular velocity upon creation, z component"); uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19, &eoa->localflag, 0.0, 0.0, 0, 0, "Apply the rotation locally"); @@ -2197,7 +2197,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh if(eoa->dyn_operation==4) { uiDefButF(block, NUM, 0, "", xco+40, yco-63, width-80, 19, &eoa->mass, 0.0, 10000.0, 10, 0, - "Mass for object."); + "Mass for object"); } } str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4"; @@ -2577,9 +2577,9 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh "Always false or always true"); break; case ACT_RANDOM_BOOL_UNIFORM: - uiDefBut(block, LABEL, 0, " Do a 50-50 pick.", (xco+10), yco-64, (width-20), 19, + uiDefBut(block, LABEL, 0, " Do a 50-50 pick", (xco+10), yco-64, (width-20), 19, NULL, 0, 0, 0, 0, - "Choose between true and false, 50% chance each."); + "Choose between true and false, 50% chance each"); break; case ACT_RANDOM_BOOL_BERNOUILLI: uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19, @@ -2596,16 +2596,16 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefButI(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, &randAct->int_arg_1, -1000, 1000, 0, 0, "Choose a number from a range. " - "Lower boundary of the range."); + "Lower boundary of the range"); uiDefButI(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, &randAct->int_arg_2, -1000, 1000, 0, 0, "Choose a number from a range. " - "Upper boundary of the range."); + "Upper boundary of the range"); break; case ACT_RANDOM_INT_POISSON: uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19, &randAct->float_arg_1, 0.01, 100.0, 0, 0, - "Expected mean value of the distribution."); + "Expected mean value of the distribution"); break; case ACT_RANDOM_FLOAT_CONST: uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, @@ -2615,26 +2615,26 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh case ACT_RANDOM_FLOAT_UNIFORM: uiDefButF(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, - "Choose a number from a range. " - "Lower boundary of the range."); + "Choose a number from a range" + "Lower boundary of the range"); uiDefButF(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, &randAct->float_arg_2, -10000.0, 10000.0, 0, 0, - "Choose a number from a range. " - "Upper boundary of the range."); + "Choose a number from a range" + "Upper boundary of the range"); break; case ACT_RANDOM_FLOAT_NORMAL: uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20)/2, 19, &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, - "A normal distribution. Mean of the distribution."); + "A normal distribution. Mean of the distribution"); uiDefButF(block, NUM, 1, "SD: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, &randAct->float_arg_2, 0.0, 10000.0, 0, 0, "A normal distribution. Standard deviation of the " - "distribution."); + "distribution"); break; case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL: uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19, &randAct->float_arg_1, 0.001, 10000.0, 0, 0, - "Negative exponential dropoff."); + "Negative exponential dropoff"); break; default: ; /* don't know what this distro is... can be useful for testing */ @@ -2664,13 +2664,13 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefBut(block, TEX, 1, "Subject: ", (xco+10), (yco-(myline++*24)), (width-20), 19, &ma->subject, 0, 31, 0, 0, - "Optional message subject. This is what can be filtered on."); + "Optional message subject. This is what can be filtered on"); /* line 3: Text/Property */ uiDefButBitS(block, TOG, 1, B_REDR, "T/P", (xco+10),(yco-(myline*24)), (0.20 * (width-20)), 19, &ma->bodyType, 0.0, 0.0, 0, 0, - "Toggle message type: either Text or a PropertyName."); + "Toggle message type: either Text or a PropertyName"); if (ma->bodyType == ACT_MESG_MESG) { @@ -3040,13 +3040,13 @@ static void buttons_ketsji(uiBlock *block, Object *ob) if (ob->gameflag & OB_ANISOTROPIC_FRICTION) { uiDefButF(block, NUM, B_DIFF, "x friction:", 10, 125, 114, 19, &ob->anisotropicFriction[0], 0.0, 1.0, 10, 0, - "Relative friction coefficient in the x-direction."); + "Relative friction coefficient in the x-direction"); uiDefButF(block, NUM, B_DIFF, "y friction:", 124, 125, 113, 19, &ob->anisotropicFriction[1], 0.0, 1.0, 10, 0, - "Relative friction coefficient in the y-direction."); + "Relative friction coefficient in the y-direction"); uiDefButF(block, NUM, B_DIFF, "z friction:", 237, 125, 113, 19, &ob->anisotropicFriction[2], 0.0, 1.0, 10, 0, - "Relative friction coefficient in the z-direction."); + "Relative friction coefficient in the z-direction"); } } @@ -3143,10 +3143,10 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) "Enable cluster collision between soft and soft body"); yco -= 20; xco = 0; - uiDefButI(block, NUM, 0, "Cluster Iter.", + uiDefButI(block, NUM, 0, "Cluster Iter", xco, yco, 180, 19, &ob->bsoft->numclusteriterations, 1.0, 128., 0, 0, "Specify the number of cluster iterations"); - uiDefButI(block, NUM, 0, "Position Iter.", + uiDefButI(block, NUM, 0, "Position Iter", xco+=180, yco, 180, 19, &ob->bsoft->piterations, 0, 10, 0, 0, "Position solver iterations"); uiBlockEndAlign(block); @@ -3260,10 +3260,10 @@ static uiBlock *advanced_bullet_menu(void *arg_ob) "Enable cluster collision between soft and soft body"); yco -= 20; xco = 0; - uiDefButI(block, NUM, 0, "Cluster Iter.", + uiDefButI(block, NUM, 0, "Cluster Iter", xco, yco, 180, 19, &ob->bsoft->numclusteriterations, 1.0, 128., 0, 0, "Specify the number of cluster iterations"); - uiDefButI(block, NUM, 0, "Position Iter.", + uiDefButI(block, NUM, 0, "Position Iter", xco+=180, yco, 180, 19, &ob->bsoft->piterations, 0, 10, 0, 0, "Position solver iterations"); #define OB_LOCK_RIGID_BODY_X_AXIS 4 @@ -3424,7 +3424,7 @@ static void buttons_bullet(uiBlock *block, Object *ob) 120, 185, 110, 19, &ob->bsoft->flag, 0, 0, 0, 0, "Enable soft body shape matching goal"); - uiDefButBitI(block, TOG, OB_BSB_BENDING_CONSTRAINTS, 0, "Bending Const.", + uiDefButBitI(block, TOG, OB_BSB_BENDING_CONSTRAINTS, 0, "Bending Const", 230, 185, 120, 19, &ob->bsoft->flag, 0, 0, 0, 0, "Enable bending constraints"); @@ -3467,13 +3467,13 @@ static void buttons_bullet(uiBlock *block, Object *ob) if (ob->gameflag & OB_ANISOTROPIC_FRICTION) { uiDefButF(block, NUM, B_DIFF, "x friction:", 10, 125, 114, 19, &ob->anisotropicFriction[0], 0.0, 1.0, 10, 0, - "Relative friction coefficient in the x-direction."); + "Relative friction coefficient in the x-direction"); uiDefButF(block, NUM, B_DIFF, "y friction:", 124, 125, 113, 19, &ob->anisotropicFriction[1], 0.0, 1.0, 10, 0, - "Relative friction coefficient in the y-direction."); + "Relative friction coefficient in the y-direction"); uiDefButF(block, NUM, B_DIFF, "z friction:", 237, 125, 113, 19, &ob->anisotropicFriction[2], 0.0, 1.0, 10, 0, - "Relative friction coefficient in the z-direction."); + "Relative friction coefficient in the z-direction"); } @@ -3830,7 +3830,7 @@ void logic_buts(void) uiBlockSetEmboss(block, UI_EMBOSSM); uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller"); uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings"); - uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Bookmarl controller to run before all other non-bookmarked controllers"); + uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)"); uiBlockSetEmboss(block, UI_EMBOSSP); sprintf(name, "%d", first_bit(cont->state_mask)+1); uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)"); From 4e0e720158d9aae16960a1b659def19d8d635b74 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 24 May 2009 19:54:35 +0000 Subject: [PATCH 317/444] == Sequencer == This fixes a stupid mistake in proxy handling with custom files: CFRA not calculated correctly for proxy... --- source/blender/src/sequence.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index e26df73b673..a6f264e2b09 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1122,6 +1122,8 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) } if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { + TStripElem * tse = give_tstripelem(seq, cfra); + int frameno = tse->nr + seq->anim_startofs; if (!seq->strip->proxy->anim) { if (!seq_proxy_get_fname(seq, cfra, name)) { return 0; @@ -1132,7 +1134,8 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) if (!seq->strip->proxy->anim) { return 0; } - return IMB_anim_absolute(seq->strip->proxy->anim, cfra); + + return IMB_anim_absolute(seq->strip->proxy->anim, frameno); } if (!seq_proxy_get_fname(seq, cfra, name)) { From 323052068a8f0c35ec293ff3bd70989acfc6be8e Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 24 May 2009 23:12:38 +0000 Subject: [PATCH 318/444] VideoTexture: exception in C++ was not returning an error in Python. Added function name ini PyArg_ParseTuple. --- source/gameengine/VideoTexture/ImageBase.cpp | 8 ++++++-- source/gameengine/VideoTexture/ImageBuff.cpp | 3 +-- source/gameengine/VideoTexture/ImageMix.cpp | 8 ++++++-- source/gameengine/VideoTexture/Texture.cpp | 4 ++-- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 7 ++++--- source/gameengine/VideoTexture/blendVideoTex.cpp | 4 ++-- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index dcca20de24a..5e2841271a6 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -437,7 +437,9 @@ PyObject * Image_getSource (PyImage * self, PyObject * args) { // get arguments char * id; - if (self->m_image != NULL && PyArg_ParseTuple(args, "s", &id)) + if (!PyArg_ParseTuple(args, "s:getSource", &id)) + return NULL; + if (self->m_image != NULL) { // get source object PyObject * src = reinterpret_cast(self->m_image->getSource(id)); @@ -460,7 +462,9 @@ PyObject * Image_setSource (PyImage * self, PyObject * args) // get arguments char * id; PyObject * obj; - if (self->m_image != NULL && PyArg_ParseTuple(args, "sO", &id, &obj)) + if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj)) + return NULL; + if (self->m_image != NULL) { // check type of object if (pyImageTypes.in(obj->ob_type)) diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index c8e62aff240..c7185660e83 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -71,10 +71,9 @@ static PyObject * load (PyImage * self, PyObject * args) short width; short height; // parse parameters - if (!PyArg_ParseTuple(args, "s#hh", &buff, &buffSize, &width, &height)) + if (!PyArg_ParseTuple(args, "s#hh:load", &buff, &buffSize, &width, &height)) { // report error - PyErr_SetString(PyExc_TypeError, "Parameters are not correct"); return NULL; } // else check buffer size diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index 2418ba254e4..067143e57bb 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -109,7 +109,9 @@ PyObject * getWeight (PyImage * self, PyObject * args) short weight = 0; // get arguments char * id; - if (self->m_image != NULL && PyArg_ParseTuple(args, "s", &id)) + if (!PyArg_ParseTuple(args, "s:getWeight", &id)) + return NULL; + if (self->m_image != NULL) // get weight weight = getImageMix(self)->getWeight(id); // return weight @@ -123,7 +125,9 @@ PyObject * setWeight (PyImage * self, PyObject * args) // get arguments char * id; short weight = 0; - if (self->m_image != NULL && PyArg_ParseTuple(args, "sh", &id, &weight)) + if (!PyArg_ParseTuple(args, "sh:setWeight", &id, &weight)) + return NULL; + if (self->m_image != NULL) // set weight if (!getImageMix(self)->setWeight(id, weight)) { diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index a8ece4bc17e..51d96d7596e 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -51,7 +51,7 @@ http://www.gnu.org/copyleft/lesser.txt. // macro for exception handling and logging #define CATCH_EXCP catch (Exception & exp) \ -{ exp.report(); } +{ exp.report(); return NULL; } // Blender GameObject type @@ -280,7 +280,7 @@ PyObject * Texture_refresh (Texture * self, PyObject * args) { // get parameter - refresh source PyObject * param; - if (!PyArg_ParseTuple(args, "O", ¶m) || !PyBool_Check(param)) + if (!PyArg_ParseTuple(args, "O:refresh", ¶m) || !PyBool_Check(param)) { // report error PyErr_SetString(PyExc_TypeError, "The value must be a bool"); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 08c02628f05..d509f366910 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -1178,7 +1178,7 @@ static int ImageFFmpeg_init (PyObject * pySelf, PyObject * args, PyObject * kwds char * file = NULL; // get parameters - if (!PyArg_ParseTuple(args, "s", &file)) + if (!PyArg_ParseTuple(args, "s:ImageFFmpeg", &file)) return -1; try @@ -1203,8 +1203,9 @@ static int ImageFFmpeg_init (PyObject * pySelf, PyObject * args, PyObject * kwds PyObject * Image_reload (PyImage * self, PyObject *args) { char * newname = NULL; - - if (self->m_image != NULL && PyArg_ParseTuple(args, "|s", &newname)) + if (!PyArg_ParseTuple(args, "|s:reload", &newname)) + return NULL; + if (self->m_image != NULL) { VideoFFmpeg* video = getFFmpeg(self); // check type of object diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 239f43763b8..1dcc72c8f7d 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -74,7 +74,7 @@ static PyObject * getLastError (PyObject *self, PyObject *args) static PyObject * setLogFile (PyObject *self, PyObject *args) { // get parameters - if (!PyArg_ParseTuple(args, "s", &Exception::m_logFile)) + if (!PyArg_ParseTuple(args, "s:setLogFile", &Exception::m_logFile)) return Py_BuildValue("i", -1); // log file was loaded return Py_BuildValue("i", 0); @@ -86,7 +86,7 @@ static PyObject * imageToArray (PyObject * self, PyObject *args) { // parameter is Image object PyObject * pyImg; - if (!PyArg_ParseTuple(args, "O", &pyImg) || !pyImageTypes.in(pyImg->ob_type)) + if (!PyArg_ParseTuple(args, "O:imageToArray", &pyImg) || !pyImageTypes.in(pyImg->ob_type)) { // if object is incorect, report error PyErr_SetString(PyExc_TypeError, "VideoTexture.imageToArray(image): The value must be a image source object"); From fe85bdd0401e92e82e39461d023bad34fe056c38 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 24 May 2009 23:43:10 +0000 Subject: [PATCH 319/444] - BGE Py API, any py function/attribute that took a KX_GameObject would not accept a KX_Light or KX_Camera (bad oversight on my part) - Typo in occlusion variable init "m_buffer == NULL;" -> "m_buffer = NULL;" CcdPhysicsEnvironment.cpp and CcdPhysicsController.cpp had too many warnings, fixed most of them. --- source/gameengine/Ketsji/KX_GameObject.cpp | 8 +++++++- .../Physics/Bullet/CcdPhysicsController.cpp | 16 ++++++---------- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 16 ++++------------ 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 3740972ba29..f1c3fb89df2 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -49,6 +49,8 @@ typedef unsigned long uint_ptr; #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" #include "KX_GameObject.h" +#include "KX_Camera.h" // only for their ::Type +#include "KX_Light.h" // only for their ::Type #include "RAS_MeshObject.h" #include "KX_MeshProxy.h" #include "KX_PolyProxy.h" @@ -2757,6 +2759,7 @@ void KX_GameObject::Relink(GEN_Map *map_parameter) } } + bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix) { if (value==NULL) { @@ -2787,7 +2790,10 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py } } - if (PyObject_TypeCheck(value, &KX_GameObject::Type)) { + if ( PyObject_TypeCheck(value, &KX_GameObject::Type) || + PyObject_TypeCheck(value, &KX_LightObject::Type) || + PyObject_TypeCheck(value, &KX_Camera::Type) ) + { *object = static_castBGE_PROXY_REF(value); /* sets the error */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 710d0656f6d..9a5f9644a47 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -185,12 +185,12 @@ void CcdPhysicsController::CreateRigidbody() rbci.m_restitution = m_cci.m_restitution; - int nodecount = 0; + + - int numtriangles = 1; btVector3 p(0,0,0);// = getOrigin(); - btScalar h = 1.f; + btSoftRigidDynamicsWorld* softDynaWorld = (btSoftRigidDynamicsWorld*)m_cci.m_physicsEnv->getDynamicsWorld(); @@ -794,7 +794,7 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); } - btRigidBody* body = GetRigidBody(); + // btRigidBody* body = GetRigidBody(); // not used anymore btVector3 dloc(dlocX,dlocY,dlocZ); btTransform xform = m_object->getWorldTransform(); @@ -1388,8 +1388,6 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, /* Convert blender geometry into bullet mesh, need these vars for mapping */ vector vert_tag_array(numverts, false); unsigned int tot_bt_verts= 0; - unsigned int orig_index; - int i; if (polytope) { @@ -1609,9 +1607,7 @@ bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo) btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) { btCollisionShape* collisionShape = 0; - btTriangleMeshShape* concaveShape = 0; - btCompoundShape* compoundShape = 0; - CcdShapeConstructionInfo* nextShapeInfo; + btCompoundShape* compoundShape = 0; if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) return m_shapeProxy->CreateBulletShape(margin); @@ -1684,7 +1680,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) collisionMeshData->m_weldingThreshold = m_weldingThreshold1; bool removeDuplicateVertices=true; // m_vertexArray not in multiple of 3 anymore, use m_triFaceArray - for(int i=0; i(rayResult.m_collisionObject->getUserPointer()); + //CcdPhysicsController* curHit = static_cast(rayResult.m_collisionObject->getUserPointer()); // save shape information as ClosestRayResultCallback::AddSingleResult() does not do it if (rayResult.m_localShapeInfo) { @@ -1021,10 +1021,6 @@ struct FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResul PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ) { - - - float minFraction = 1.f; - btVector3 rayFrom(fromX,fromY,fromZ); btVector3 rayTo(toX,toY,toZ); @@ -1174,7 +1170,7 @@ struct OcclusionBuffer { m_initialized=false; m_occlusion = false; - m_buffer == NULL; + m_buffer = NULL; m_bufferSize = 0; } // multiplication of column major matrices: m=m1*m2 @@ -1282,8 +1278,7 @@ struct OcclusionBuffer static bool project(btVector4* p,int n) { for(int i=0;igetDebugMode() & btIDebugDraw::DBG_DrawContactPoints))) { //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback From 48abe5a66efe886233c780dbffbe512f15a16720 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 00:30:06 +0000 Subject: [PATCH 320/444] utility script for cleaning ipos animation curves, used in YoFrankie to reduce file size for large actions --- release/scripts/animation_clean.py | 192 +++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 release/scripts/animation_clean.py diff --git a/release/scripts/animation_clean.py b/release/scripts/animation_clean.py new file mode 100644 index 00000000000..fc44f264ac1 --- /dev/null +++ b/release/scripts/animation_clean.py @@ -0,0 +1,192 @@ +#!BPY + +""" +Name: 'Clean Animation Curves' +Blender: 249 +Group: 'Animation' +Tooltip: 'Remove unused keyframes for ipo curves' +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Copyright (C) 2008-2009: Blender Foundation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# -------------------------------------------------------------------------- + +import bpy +from Blender import IpoCurve, Draw, Window + +def clean_ipos(ipos): + eul = 0.001 + + def isflat(vec): + prev_y = vec[0][1] + mid_y = vec[1][1] + next_y = vec[2][1] + + # flat status for prev and next + return abs(mid_y-prev_y) < eul, abs(mid_y-next_y) < eul + + + + X=0 + Y=1 + PREV=0 + MID=1 + NEXT=2 + + LEFT = 0 + RIGHT = 1 + + TOT = 0 + TOTBEZ = 0 + # for ipo in bpy.data.ipos: + for ipo in ipos: + if ipo.lib: + continue + # print ipo + for icu in ipo: + interp = icu.interpolation + extend = icu.extend + + bezierPoints = icu.bezierPoints + bezierVecs = [bez.vec for bez in bezierPoints] + + l = len(bezierPoints) + + TOTBEZ += l + + # our aim is to simplify this ipo as much as possible! + if interp == IpoCurve.InterpTypes.BEZIER or interp == interp == IpoCurve.InterpTypes.LINEAR: + #print "Not yet supported" + + if interp == IpoCurve.InterpTypes.BEZIER: + flats = [isflat(bez) for bez in bezierVecs] + else: + # A bit of a waste but fake the locations for these so they will always be flats + # IS better then too much duplicate code. + flats = [(True, True)] * l + for v in bezierVecs: + v[PREV][Y] = v[NEXT][Y] = v[MID][Y] + + + # remove middle points + if l>2: + done_nothing = False + + while not done_nothing and len(bezierVecs) > 2: + done_nothing = True + i = l-2 + + while i > 0: + #print i + #print i, len(bezierVecs) + if flats[i]==(True,True) and flats[i-1][RIGHT] and flats[i+1][LEFT]: + + if abs(bezierVecs[i][MID][Y] - bezierVecs[i-1][MID][Y]) < eul and abs(bezierVecs[i][MID][Y] - bezierVecs[i+1][MID][Y]) < eul: + done_nothing = False + + del flats[i] + del bezierVecs[i] + icu.delBezier(i) + TOT += 1 + l-=1 + i-=1 + + # remove endpoints + if extend == IpoCurve.ExtendTypes.CONST and len(bezierVecs) > 1: + #print l, len(bezierVecs) + # start + + while l > 2 and (flats[0][RIGHT] and flats[1][LEFT] and (abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul)): + print "\tremoving 1 point from start of the curve" + del flats[0] + del bezierVecs[0] + icu.delBezier(0) + TOT += 1 + l-=1 + + + # End + while l > 2 and flats[-2][RIGHT] and flats[-1][LEFT] and (abs(bezierVecs[-2][MID][Y] - bezierVecs[-1][MID][Y]) < eul): + print "\tremoving 1 point from end of the curve", l + del flats[l-1] + del bezierVecs[l-1] + icu.delBezier(l-1) + TOT += 1 + l-=1 + + + + if l==2: + if isflat( bezierVecs[0] )[RIGHT] and isflat( bezierVecs[1] )[LEFT] and abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul: + # remove the second point + print "\tremoving 1 point from 2 point bez curve" + # remove the second point + del flats[1] + del bezierVecs[1] + icu.delBezier(1) + TOT+=1 + l-=1 + + # Change to linear for faster evaluation + ''' + if l==1: + print 'Linear' + icu.interpolation = IpoCurve.InterpTypes.LINEAR + ''' + + + + + if interp== IpoCurve.InterpTypes.CONST: + print "Not yet supported" + + print 'total', TOT, TOTBEZ + return TOT, TOTBEZ + +def main(): + ret = Draw.PupMenu('Clean Selected Objects Ipos%t|Object IPO%x1|Object Action%x2|%l|All IPOs (be careful!)%x3') + + sce = bpy.data.scenes.active + ipos = [] + + if ret == 3: + ipos.extend(list(bpy.data.ipos)) + else: + for ob in sce.objects.context: + if ret == 1: + ipo = ob.ipo + if ipo: + ipos.append(ipo) + + elif ret == 2: + action = ob.action + if action: + ipos.extend([ipo for ipo in action.getAllChannelIpos().values() if ipo]) + + + + if not ipos: + Draw.PupMenu('Error%t|No ipos found') + else: + total_removed, total = clean_ipos(ipos) + Draw.PupMenu('Done!%t|Removed ' + str(total_removed) + ' of ' + str(total) + ' points') + + Window.RedrawAll() + + +if __name__ == '__main__': + main() From b7653ba5421a245957ac6170f0bbca0589220bae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 00:31:41 +0000 Subject: [PATCH 321/444] missing null check, would crash blender when loading some files --- source/blender/blenloader/intern/readfile.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d9df1ee4419..3284f8efdf2 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8116,11 +8116,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* check if top parent has compound shape set and if yes, set this object to compound shaper as well (was the behaviour before, now it's optional) */ Object *parent= newlibadr(fd, lib, ob->parent); - while (parent->parent != NULL) { - parent = newlibadr(fd, lib, parent->parent); + if(parent) { + while (parent->parent != NULL) { + parent = newlibadr(fd, lib, parent->parent); + } + if (parent->gameflag & OB_CHILD) + ob->gameflag |= OB_CHILD; } - if (parent->gameflag & OB_CHILD) - ob->gameflag |= OB_CHILD; } } for(wrld=main->world.first; wrld; wrld= wrld->id.next) { From 1266e0f2bffb95a59157075f9f4f071dcc744f73 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 01:00:17 +0000 Subject: [PATCH 322/444] quick fix still allowed for possible crash, check for valid newlibadr return value in the while loop. --- source/blender/blenloader/intern/readfile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3284f8efdf2..abfb8ebd04c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8116,10 +8116,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* check if top parent has compound shape set and if yes, set this object to compound shaper as well (was the behaviour before, now it's optional) */ Object *parent= newlibadr(fd, lib, ob->parent); + while (parent && parent->parent != NULL) { + parent = newlibadr(fd, lib, parent->parent); + } if(parent) { - while (parent->parent != NULL) { - parent = newlibadr(fd, lib, parent->parent); - } if (parent->gameflag & OB_CHILD) ob->gameflag |= OB_CHILD; } From 3ceed4cfb207e06c978d49f2992f8a19970cab22 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 01:45:35 +0000 Subject: [PATCH 323/444] [#18731] trouble with the python api in assigning script constraint's target. - Setting the constraint script from python didnt update the target count - Setting objects didnt work at all, since it checked the input sequence for being an BPy_Object type (rather then an item in the sequence) --- source/blender/python/api2_2x/Constraint.c | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/source/blender/python/api2_2x/Constraint.c b/source/blender/python/api2_2x/Constraint.c index 9ecec8eb973..ae96627cc2f 100644 --- a/source/blender/python/api2_2x/Constraint.c +++ b/source/blender/python/api2_2x/Constraint.c @@ -52,6 +52,7 @@ #include "blendef.h" #include "mydevice.h" +#include "../BPY_extern.h" // BPY_pyconstraint_update #include "IDProp.h" #include "Object.h" #include "NLA.h" @@ -1498,6 +1499,11 @@ static int script_setter( BPy_Constraint *self, int type, PyObject *value ) bConstraintTarget *ct; int ok= 0; + if (PySequence_Check(value) == 0 || PyString_Check(value)) { + PyErr_SetString(PyExc_TypeError, "expected a sequence of strings or blender"); + return -1; + } + if (cti) { /* change space of targets */ if (cti->get_constraint_targets) { @@ -1506,13 +1512,12 @@ static int script_setter( BPy_Constraint *self, int type, PyObject *value ) /* get targets, and extract values from the given list */ num_tars= cti->get_constraint_targets(self->con, &targets); + if ((PySequence_Size(value) != num_tars)) { + PyErr_Format(PyExc_TypeError, "expected sequence of strings or blender objects - %d length", num_tars); + return -1; + } + if (num_tars) { - if ((PySequence_Check(value) == 0) || (PySequence_Size(value) != num_tars)) { - char errorstr[64]; - sprintf(errorstr, "expected sequence of %d integer(s)", num_tars); - return EXPP_ReturnIntError(PyExc_TypeError, errorstr); - } - for (ct=targets.first; ct; ct=ct->next, i++) { PyObject *val= PySequence_ITEM(value, i); @@ -1530,10 +1535,11 @@ static int script_setter( BPy_Constraint *self, int type, PyObject *value ) BLI_strncpy(ct->subtarget, name, sizeof(ct->subtarget)); } - else { + else /* if EXPP_CONSTR_TARGET */ { + Object *obj = (( BPy_Object * )val)->object; - if ( !BPy_Object_Check(value) ) { + if ( !BPy_Object_Check(val) ) { // hrm... should we break here instead? ok = EXPP_ReturnIntError(PyExc_TypeError, "expected BPy object argument as member of list"); @@ -1564,6 +1570,7 @@ static int script_setter( BPy_Constraint *self, int type, PyObject *value ) return EXPP_ReturnIntError( PyExc_TypeError, "expected BPy text argument" ); con->text = text; + BPY_pyconstraint_update(self->obj, self->con); return 0; } case EXPP_CONSTR_PROPS: From 1af059b642c94b44e7d09c1546e583659775ceb8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 02:11:18 +0000 Subject: [PATCH 324/444] [#18808] Unstable results of Pack Margin in UV editor was scaling the margin by the area twice --- source/blender/src/parametrizer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/src/parametrizer.c b/source/blender/src/parametrizer.c index feb774b604a..46218ec921b 100644 --- a/source/blender/src/parametrizer.c +++ b/source/blender/src/parametrizer.c @@ -4188,11 +4188,11 @@ void param_pack(ParamHandle *handle, float margin) } box = boxarray+(i-unpacked); - trans[0] = margin * area; - trans[1] = margin * area; + trans[0] = margin; + trans[1] = margin; p_chart_uv_translate(chart, trans); - box->w += (margin * area) *2; - box->h += (margin * area) *2; + box->w += margin*2; + box->h += margin*2; } } From 3053ce1a8c93480d6412386c0afe11fac4c27f9c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 02:39:05 +0000 Subject: [PATCH 325/444] [#18819] save and load globalDictionary actuators don't load the proper files in 2.49 RC3 For this actuator to be useful it needs to use the first opened blendfile as the base name for the configuration file. A recent fix that made the gp_GamePythonPath always match the current loaded blend file made this actuator work differently. keep the original filename to use for making the config name so you can load the config between loading blendfiles. --- source/gameengine/Ketsji/KX_PythonInit.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 3626d7baa9a..7c131d01cd1 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -120,6 +120,7 @@ static KX_Scene* gp_KetsjiScene = NULL; static KX_KetsjiEngine* gp_KetsjiEngine = NULL; static RAS_IRasterizer* gp_Rasterizer = NULL; static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = ""; +static char gp_GamePythonPathOrig[FILE_MAXDIR + FILE_MAXFILE] = ""; // not super happy about this, but we need to remember the first loaded file for the global/dict load save static PyObject *gp_OrigPythonSysPath= NULL; void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) @@ -2096,9 +2097,9 @@ int loadGamePythonConfig(char *marshal_buffer, int marshal_length) void pathGamePythonConfig( char *path ) { - int len = strlen(gp_GamePythonPath); + int len = strlen(gp_GamePythonPathOrig); // Always use the first loaded blend filename - BLI_strncpy(path, gp_GamePythonPath, sizeof(gp_GamePythonPath)); + BLI_strncpy(path, gp_GamePythonPathOrig, sizeof(gp_GamePythonPathOrig)); /* replace extension */ if (BLI_testextensie(path, ".blend")) { @@ -2111,5 +2112,8 @@ void pathGamePythonConfig( char *path ) void setGamePythonPath(char *path) { BLI_strncpy(gp_GamePythonPath, path, sizeof(gp_GamePythonPath)); + + if (gp_GamePythonPathOrig[0] == '\0') + BLI_strncpy(gp_GamePythonPathOrig, path, sizeof(gp_GamePythonPathOrig)); } From 2a9d9605d08e2521b2c6aadafe8294e1eed78fc3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 03:06:03 +0000 Subject: [PATCH 326/444] Pressing the '~' key in the ipo view didnt store the view state in the ipo curves as clicking on the ipo channel names does. --- source/blender/src/header_ipo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index 27549a5b502..3ef76c31e53 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -1216,6 +1216,8 @@ void do_ipo_buttons(short event) if (ei->icu) ei->flag |= IPO_VISIBLE; else ei->flag &= ~IPO_VISIBLE; } + update_editipo_flags(); + break; case B_IPOREDRAW: DAG_object_flush_update(G.scene, ob, OB_RECALC); From 2fa8504dd104e0bde32ee487f97fbce4fd6d7104 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 06:24:23 +0000 Subject: [PATCH 327/444] BGE Joystick Hat Bugfix bug reported by blenderage on blenderartist (found other bugs too). - "All Hat Events" didnt work. - Multiple hats didnt work - use a menu with direction names rather then have the user guess. disallow zero as a direction. - Allow up to 4 hats (was 2). - Python api was clamping the axis to 2, maximum is currently JOYAXIS_MAX - 16 - New python attributes hatValues and hatSingle, match axis functions. - Use SDL Axis events to fill in the axis and hat array rather then filling in every axis with SDL_JoystickGetAxis for each axis event. --- source/blender/src/buttons_logic.c | 13 ++--- .../GameLogic/Joystick/SCA_Joystick.cpp | 34 ++++-------- .../GameLogic/Joystick/SCA_Joystick.h | 44 ++++------------ .../GameLogic/Joystick/SCA_JoystickDefines.h | 1 + .../GameLogic/Joystick/SCA_JoystickEvents.cpp | 13 +++-- .../GameLogic/SCA_JoystickSensor.cpp | 52 ++++++++++++------- .../gameengine/GameLogic/SCA_JoystickSensor.h | 17 +++--- source/gameengine/PyDoc/GameTypes.py | 25 +++++++-- 8 files changed, 99 insertions(+), 100 deletions(-) diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index b8c851f5ab8..25bed178130 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1534,13 +1534,14 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short else if (joy->type == SENS_JOY_HAT) { uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->hat, 1, 2.0, 100, 0, + &joy->hat, 1, 4.0, 100, 0, "Specify which hat to use"); if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { - uiDefButI(block, NUM, 1, "Direction:", xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->hatf, 0, 12, 100, 0, - "Specify hat direction"); + str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6"; + uiDefButI(block, MENU, B_NOP, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, + &joy->hatf, 2.0, 31, 0, 0, + "The direction of the hat, use 'All Events' to recieve events on any direction"); } } else { /* (joy->type == SENS_JOY_AXIS_SINGLE)*/ @@ -2752,12 +2753,12 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(parAct->ob), "Set this object as parent"); uiBlockBeginAlign(block); - uiDefButBitI(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, + uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, "Compound", xco + 40, yco - 64, (width - 80)/2, 19, &parAct->flag, 0.0, 0.0, 0, 0, "Add this object shape to the parent shape (only if the parent shape is already compound)"); - uiDefButBitI(block, TOGN, ACT_PARENT_GHOST, B_REDR, + uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR, "Ghost", xco + 40 + ((width - 80)/2), yco - 64, (width - 80)/2, 19, &parAct->flag, 0.0, 0.0, 0, 0, diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index b19424f20e9..7c4ebb4c330 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -42,7 +42,6 @@ SCA_Joystick::SCA_Joystick(short int index) m_axismax(-1), m_buttonmax(-1), m_hatmax(-1), - m_hatdir(-2), m_isinit(0), m_istrig_axis(0), m_istrig_button(0), @@ -50,6 +49,10 @@ SCA_Joystick::SCA_Joystick(short int index) { for(int i=0; i JOYAXIS_MAX) m_axismax= JOYAXIS_MAX; /* very unlikely */ else if (m_axismax < 0) m_axismax = 0; + if (m_hatmax > JOYHAT_MAX) m_hatmax= JOYHAT_MAX; /* very unlikely */ + else if(m_hatmax<0) m_hatmax= 0; + if(m_buttonmax<0) m_buttonmax= 0; - if(m_hatmax<0) m_hatmax= 0; + } return true; #endif @@ -278,15 +273,6 @@ int SCA_Joystick::Connected(void) return 0; } -void SCA_Joystick::pFillAxes() -{ -#ifndef DISABLE_SDL - for(int i=0; im_joystick, i); -#endif -} - - int SCA_Joystick::pGetAxis(int axisnum, int udlr) { #ifndef DISABLE_SDL diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h index 53cd65cd495..5822f8e8ff8 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h @@ -53,28 +53,20 @@ class SCA_Joystick int m_joyindex; /* - *support for 2 axes + *support for JOYAXIS_MAX axes (in pairs) */ int m_axis_array[JOYAXIS_MAX]; + + /* + *support for JOYHAT_MAX hats (each is a direction) + */ + int m_hat_array[JOYHAT_MAX]; /* * Precision or range of the axes */ int m_prec; - /* - * multiple axis values stored here - */ - int m_axisnum; - int m_axisvalue; - - /* - * max # of axes avail - */ - /*disabled - int m_axismax; - */ - /* * button values stored here */ @@ -88,18 +80,6 @@ class SCA_Joystick int m_buttonmax; int m_hatmax; - /* - * hat values stored here - */ - int m_hatnum; - int m_hatdir; - - /* - - * max # of hats avail - disabled - int m_hatmax; - */ /* is the joystick initialized ?*/ bool m_isinit; @@ -136,7 +116,6 @@ class SCA_Joystick /* * fills the axis mnember values */ - void pFillAxes(void); void pFillButtons(void); /* @@ -149,11 +128,6 @@ class SCA_Joystick */ int pGetAxis(int axisnum, int udlr); - /* - * gets the current hat direction - */ - int pGetHat(int direction); - SCA_Joystick(short int index); ~SCA_Joystick(); @@ -175,7 +149,7 @@ public: bool aAnyButtonReleaseIsPositive(void); bool aButtonPressIsPositive(int button); bool aButtonReleaseIsPositive(int button); - bool aHatIsPositive(int dir); + bool aHatIsPositive(int hatnum, int dir); /* * precision is default '3200' which is overridden by input @@ -191,8 +165,8 @@ public: return m_buttonnum; } - int GetHat(void){ - return m_hatdir; + int GetHat(int index){ + return m_hat_array[index]; } int GetThreshold(void){ diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h index 636c4dd5a42..c7a9a5114df 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h @@ -40,6 +40,7 @@ #define JOYINDEX_MAX 8 #define JOYAXIS_MAX 16 +#define JOYHAT_MAX 4 #define JOYAXIS_RIGHT 0 #define JOYAXIS_UP 1 diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp index 8e190060e95..3ca8d7d2329 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp @@ -35,17 +35,20 @@ #ifndef DISABLE_SDL void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event) { - pFillAxes(); - m_axisnum = sdl_event->jaxis.axis; - m_axisvalue = sdl_event->jaxis.value; + if(sdl_event->jaxis.axis >= JOYAXIS_MAX) + return; + + m_axis_array[sdl_event->jaxis.axis]= sdl_event->jaxis.value; m_istrig_axis = 1; } void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event) { - m_hatdir = sdl_event->jhat.value; - m_hatnum = sdl_event->jhat.hat; + if(sdl_event->jhat.hat >= JOYAXIS_MAX) + return; + + m_hat_array[sdl_event->jhat.hat]= sdl_event->jhat.value; m_istrig_hat = 1; } diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 906d454b728..16061d6fb6e 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -198,33 +198,20 @@ bool SCA_JoystickSensor::Evaluate() case KX_JOYSENSORMODE_HAT: { /* what is what! - numberof = m_hat -- max 2 + numberof = m_hat -- max 4 direction= m_hatf -- max 12 */ if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */ return false; - if(m_hat == 1){ - if(js->aHatIsPositive(m_hatf)){ - m_istrig = 1; + if((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) { + m_istrig = 1; + result = true; + }else{ + if(m_istrig){ + m_istrig = 0; result = true; - }else{ - if(m_istrig){ - m_istrig = 0; - result = true; - } - } - } - if(m_hat == 2){ - if(js->aHatIsPositive(m_hatf)){ - m_istrig = 1; - result = true; - }else{ - if(m_istrig){ - m_istrig = 0; - result = true; - } } } break; @@ -331,6 +318,8 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = { KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat), KX_PYATTRIBUTE_RO_FUNCTION("axisValues", SCA_JoystickSensor, pyattr_get_axis_values), KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single), + KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values), + KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single), KX_PYATTRIBUTE_RO_FUNCTION("numAxis", SCA_JoystickSensor, pyattr_get_num_axis), KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_JoystickSensor, pyattr_get_num_buttons), KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_JoystickSensor, pyattr_get_num_hats), @@ -617,6 +606,29 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYAT return PyInt_FromLong(joy->GetAxisPosition(self->m_axis-1)); } +PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_JoystickSensor* self= static_cast(self_v); + SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); + + int hat_index= joy->GetNumberOfHats(); + PyObject *list= PyList_New(hat_index); + + while(hat_index--) { + PyList_SET_ITEM(list, hat_index, PyInt_FromLong(joy->GetHat(hat_index))); + } + + return list; +} + +PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + SCA_JoystickSensor* self= static_cast(self_v); + SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); + + return PyInt_FromLong(joy->GetHat(self->m_hat-1)); +} + PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index e8185d1911e..e6a1d2eef32 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -30,6 +30,7 @@ #define __JOYSENSOR_H #include "SCA_ISensor.h" +#include "./Joystick/SCA_JoystickDefines.h" class SCA_JoystickSensor :public SCA_ISensor { @@ -37,7 +38,7 @@ class SCA_JoystickSensor :public SCA_ISensor class SCA_JoystickManager* m_pJoystickMgr; /** - * Axis 1-or-2, MUST be followed by m_axisf + * Axis 1-JOYAXIS_MAX, MUST be followed by m_axisf */ int m_axis; /** @@ -53,11 +54,11 @@ class SCA_JoystickSensor :public SCA_ISensor */ int m_buttonf; /** - * The actual hat. MUST be followed by m_hatf + * The actual hat 1-JOYHAT_MAX. MUST be followed by m_hatf */ int m_hat; /** - * Flag to find direction 0-11, MUST be an int + * Flag to find direction 1-12, MUST be an int */ int m_hatf; /** @@ -152,6 +153,8 @@ public: static PyObject* pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); @@ -164,8 +167,8 @@ public: SCA_JoystickSensor* sensor = reinterpret_cast(self); if (sensor->m_axis < 1) sensor->m_axis = 1; - else if (sensor->m_axis > 2) - sensor->m_axis = 2; + else if (sensor->m_axis > JOYAXIS_MAX) + sensor->m_axis = JOYAXIS_MAX; return 0; } static int CheckHat(void *self, const PyAttributeDef*) @@ -173,8 +176,8 @@ public: SCA_JoystickSensor* sensor = reinterpret_cast(self); if (sensor->m_hat < 1) sensor->m_hat = 1; - else if (sensor->m_hat > 2) - sensor->m_hat = 2; + else if (sensor->m_hat > JOYHAT_MAX) + sensor->m_hat = JOYHAT_MAX; return 0; } diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 8a590a48c9e..ca9c674a942 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -47,6 +47,7 @@ class CValue(PyObjectPlus): This class is a basis for other classes. @ivar name: The name of this CValue derived object (read-only). @type name: string + @group Deprecated: getName """ def getName(): """ @@ -259,7 +260,7 @@ class SCA_IController(SCA_ILogicBrick): @type actuators: sequence supporting index/string lookups and iteration. @ivar bookmark: the bookmark option. If set, the controller executes always before all other non-bookmarked controllers. - - note: Order of execution between bookmarked controllers is not guaranteed. + note: Order of execution between bookmarked controllers is not guaranteed. @type bookmark: bool """ #{ Deprecated @@ -4741,6 +4742,24 @@ class SCA_JoystickSensor(SCA_ISensor): Only use this for "Single Axis" type sensors otherwise it will raise an error. @type axisSingle: int + @ivar hatValues: (read-only) The state of the joysticks hats as a list of values L{numHats} long. + each spesifying the direction of the hat from 1 to 12, 0 when inactive. + Hat directions are as follows... + - 0:None + - 1:Up + - 2:Right + - 4:Down + - 8:Left + - 3:Up - Right + - 6:Down - Right + - 12:Down - Left + - 9:Up - Left + + @type hatValues: list of ints + + @ivar hatSingle: (read-only) like L{hatValues} but returns a single hat direction value that is set by the sensor. + @type hatSingle: int + @ivar numAxis: (read-only) The number of axes for the joystick at this index. @type numAxis: integer @ivar numButtons: (read-only) The number of buttons for the joystick at this index. @@ -4760,8 +4779,8 @@ class SCA_JoystickSensor(SCA_ISensor): axisDirection: 0=right, 1=up, 2=left, 3=down @type axis: [integer, integer] @ivar hat: The hat the sensor reacts to, as a list of two values: [hatIndex, hatDirection] - hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat. - hatDirection: 0-11 + hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat (4 max). + hatDirection: 1-12 @type hat: [integer, integer] """ From ca8497d001417ec110982b0d6ce7264da50e2b6d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 May 2009 11:39:09 +0000 Subject: [PATCH 328/444] * UI tweaks to python controller (more space for module name), setParent actuator use less space * object_drop.py - option to orient to face normal (useful for scattering objects over terrain), accounts for normal flipping and can adjust the orientation %. --- release/scripts/object_drop.py | 64 +++++++++++++++++++++--------- source/blender/src/buttons_logic.c | 18 ++++----- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/release/scripts/object_drop.py b/release/scripts/object_drop.py index f4803e62d98..19cc1f8d15a 100644 --- a/release/scripts/object_drop.py +++ b/release/scripts/object_drop.py @@ -1,13 +1,13 @@ #!BPY """ Name: 'Drop Onto Ground' -Blender: 245 +Blender: 249 Group: 'Object' Tooltip: 'Drop the selected objects onto "ground" objects' """ __author__= "Campbell Barton" __url__= ["blender.org", "blenderartists.org"] -__version__= "1.0" +__version__= "1.1" __bpydoc__= """ """ @@ -36,6 +36,7 @@ __bpydoc__= """ from Blender import Draw, Geometry, Mathutils, Window +from Blender.Mathutils import Vector, AngleBetweenVecs, RotationMatrix import bpy @@ -44,6 +45,8 @@ GLOBALS['GROUND_SOURCE'] = [Draw.Create(1), Draw.Create(0)] GLOBALS['GROUND_GROUP_NAME'] = Draw.Create('terrain') GLOBALS['DROP_AXIS'] = [Draw.Create(1), Draw.Create(0)] # on what axis will we drop? GLOBALS['DROP_OVERLAP_CHECK'] = Draw.Create(1) # is the terrain a single skin? +GLOBALS['DROP_ORIENT'] = Draw.Create(1) +GLOBALS['DROP_ORIENT_VALUE'] = Draw.Create(100.0) GLOBALS['EVENT'] = 2 GLOBALS['MOUSE'] = None @@ -52,19 +55,18 @@ def collect_terrain_triangles(obs_terrain): me = bpy.data.meshes.new() for ob in obs_terrain: - # this matrix takes the object and drop matrix into account - ob_mat = ob.matrixWorld # * drop_matrix - def blend_face_to_terrain_tris(f): - cos = [v.co*ob_mat for v in f] - if len(cos) == 4: return [(cos[0], cos[1], cos[2]), (cos[0], cos[2], cos[3])] - else: return [(cos[0], cos[1], cos[2]), ] + no = f.no + cos = [v.co for v in f] + if len(cos) == 4: return [(cos[0], cos[1], cos[2], no), (cos[0], cos[2], cos[3], no)] + else: return [(cos[0], cos[1], cos[2], no), ] # Clear me.verts = None try: me.getFromObject(ob) except: pass + me.transform(ob.matrixWorld) for f in me.faces: # may be [], thats ok terrain_tris.extend( blend_face_to_terrain_tris(f) ) @@ -72,30 +74,34 @@ def collect_terrain_triangles(obs_terrain): return terrain_tris def calc_drop_loc(ob, terrain_tris, axis): - pt = Mathutils.Vector(ob.loc) + pt = Vector(ob.loc) isect = None isect_best = None + isect_best_no = None isect_best_len = 0.0 - for t1,t2,t3 in terrain_tris: + for t1,t2,t3, no in terrain_tris: #if Geometry.PointInTriangle2D(pt, t1,t2,t3): isect = Mathutils.Intersect(t1, t2, t3, axis, pt, 1) # 1==clip if isect: if not GLOBALS['DROP_OVERLAP_CHECK'].val: # Find the first location - return isect + return isect, no else: if isect_best: isect_len = (pt-isect).length if isect_len < isect_best_len: isect_best_len = isect_len isect_best = isect + isect_best_no = no else: isect_best_len = (pt-isect).length isect_best = isect; - return isect_best + isect_best_no = no + + return isect_best, isect_best_no def error_nogroup(): @@ -135,13 +141,28 @@ def terrain_clamp(event, value): if GLOBALS['DROP_AXIS'][0].val: - axis = Mathutils.Vector(0,0,-1) + axis = Vector(0,0,-1) else: - axis = Mathutils.Vector(Window.GetViewVector()) + axis = Vector(Window.GetViewVector()) + + do_orient = GLOBALS['DROP_ORIENT'].val + do_orient_val = GLOBALS['DROP_ORIENT_VALUE'].val/100.0 + if not do_orient_val: do_orient = False for ob in obs_clamp: - loc = calc_drop_loc(ob, terrain_tris, axis) + loc, no = calc_drop_loc(ob, terrain_tris, axis) if loc: + if do_orient: + try: ang = AngleBetweenVecs(no, axis) + except:ang = 0.0 + if ang > 90.0: + no = -no + ang = 180.0-ang + + if ang > 0.0001: + ob_matrix = ob.matrixWorld * RotationMatrix(ang * do_orient_val, 4, 'r', axis.cross(no)) + ob.setMatrix(ob_matrix) + ob.loc = loc # to make the while loop exist @@ -175,7 +196,8 @@ def do_ground_group_name(e,v): if not g: error_nogroup() GLOBALS['EVENT'] = e - +def do_dummy(e,v): + GLOBALS['EVENT'] = e EVENT_NONE = 0 EVENT_EXIT = 1 @@ -185,7 +207,7 @@ def terain_clamp_ui(): # Only to center the UI x,y = GLOBALS['MOUSE'] x-=40 - y-=60 + y-=70 Draw.Label('Drop Axis', x-70,y+120, 60, 20) Draw.BeginAlign() @@ -204,7 +226,13 @@ def terain_clamp_ui(): GLOBALS['DROP_OVERLAP_CHECK'] = Draw.Toggle('Overlapping Terrain', EVENT_NONE, x-70, y+20, 190, 20, GLOBALS['DROP_OVERLAP_CHECK'].val, "Check all terrain triangles and use the top most (slow)") - Draw.PushButton('Drop Objects', EVENT_EXIT, x+20, y-10, 100, 20, 'Drop the selected objects', terrain_clamp) + Draw.BeginAlign() + GLOBALS['DROP_ORIENT'] = Draw.Toggle('Orient Normal', EVENT_REDRAW, x-70, y-10, 110, 20, GLOBALS['DROP_ORIENT'].val, "Rotate objects to the face normal", do_dummy) + if GLOBALS['DROP_ORIENT'].val: + GLOBALS['DROP_ORIENT_VALUE'] = Draw.Number('', EVENT_NONE, x+40, y-10, 80, 20, GLOBALS['DROP_ORIENT_VALUE'].val, 0.0, 100.0, "Percentage to orient 0.0 - 100.0") + Draw.EndAlign() + + Draw.PushButton('Drop Objects', EVENT_EXIT, x+20, y-40, 100, 20, 'Drop the selected objects', terrain_clamp) # So moving the mouse outside the popup exits the while loop GLOBALS['EVENT'] = EVENT_EXIT diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 25bed178130..a1fddfefb9c 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1603,12 +1603,12 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco uiBlockBeginAlign(block); - uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+24,yco-24, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)"); + uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+4,yco-23, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)"); if(pc->mode==0) - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+90,yco-24,width-90, 19, &pc->text, "Blender textblock to run as a script"); + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script"); else { - uiDefBut(block, TEX, 1, "", xco+90,yco-24,(width-90)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used"); - uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-24, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting"); + uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used"); + uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-23, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting"); } uiBlockEndAlign(block); @@ -2748,19 +2748,19 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh if(parAct->type==ACT_PARENT_SET) { - ysize= 68; + ysize= 48; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(parAct->ob), "Set this object as parent"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent"); uiBlockBeginAlign(block); uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, "Compound", - xco + 40, yco - 64, (width - 80)/2, 19, &parAct->flag, + xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag, 0.0, 0.0, 0, 0, "Add this object shape to the parent shape (only if the parent shape is already compound)"); uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR, "Ghost", - xco + 40 + ((width - 80)/2), yco - 64, (width - 80)/2, 19, &parAct->flag, + xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag, 0.0, 0.0, 0, 0, "Make this object ghost while parented (only if not compound)"); uiBlockEndAlign(block); @@ -2773,7 +2773,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh } str= "Parent %t|Set Parent %x0|Remove Parent %x1"; - uiDefButI(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &parAct->type, 0.0, 0.0, 0, 0, ""); + uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, parAct->type==1?(width-80):90, 19, &parAct->type, 0.0, 0.0, 0, 0, ""); yco-= ysize; break; From ca39228fb70a2c1b45c504ef344a5ac434f8989c Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Mon, 25 May 2009 16:09:22 +0000 Subject: [PATCH 329/444] Interface --------- Bugfix 18811: long filenames caused stack corruption in BLI_adddirstrings(). --- source/blender/blenlib/intern/storage.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 088b5e40a51..2ea9a54f13f 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -329,7 +329,7 @@ void BLI_builddir(char *dirname, char *relname) void BLI_adddirstrings() { char datum[100]; - char buf[250]; + char buf[512]; char size[250]; static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}; int num, mode; @@ -432,9 +432,6 @@ void BLI_adddirstrings() sprintf(size, "%10d", (int) st_size); } - sprintf(buf,"%s %s %10s %s", files[num].date, files[num].time, size, - files[num].relname); - sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, files[num].owner, files[num].date, files[num].time, size, files[num].relname); From 25c564c7c33701650dc9457969da0e596b787fa4 Mon Sep 17 00:00:00 2001 From: Stefan Gartner Date: Mon, 25 May 2009 23:20:38 +0000 Subject: [PATCH 330/444] tiny fix for irix: use putenv instead of setenv --- source/creator/creator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/creator/creator.c b/source/creator/creator.c index e04a5b1db3d..f8bf7288143 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -544,9 +544,13 @@ int main(int argc, char **argv) #else _putenv_s("SDL_VIDEODRIVER", "dummy"); #endif +#else +#ifdef __sgi + putenv("SDL_VIDEODRIVER=dummy"); #else setenv("SDL_VIDEODRIVER", "dummy", 1); /* initializing the video driver can cause crashes on some systems - Campbell */ #endif +#endif #ifdef __linux__ /* On linux the default SDL driver dma often would not play * use alsa if none is set */ From bbed7918c891c928cb18cc38e2497e9209da9ad7 Mon Sep 17 00:00:00 2001 From: Stefan Gartner Date: Mon, 25 May 2009 23:35:29 +0000 Subject: [PATCH 331/444] IRIX: use python 2.5 by default --- source/nan_definitions.mk | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index f7bcd47930c..953f8593f91 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -292,8 +292,12 @@ endif export HOST = $(shell /usr/bsd/hostname -s) #export NAN_NO_KETSJI=true export NAN_JUST_BLENDERDYNAMIC=true - export NAN_PYTHON ?= $(LCGDIR)/python - export NAN_PYTHON_VERSION ?= 2.3 + export NAN_PYTHON_VERSION ?= 2.5 + ifeq ($(IRIX_USE_GCC), true) + export NAN_PYTHON ?= $(LCGDIR)/python_gcc + else + export NAN_PYTHON ?= $(LCGDIR)/python + endif export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION) export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a -lpthread export NAN_OPENAL ?= $(LCGDIR)/openal From 5f82855a07eb1cfbb89aba654c9c8f7da1544c5b Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Tue, 26 May 2009 00:14:22 +0000 Subject: [PATCH 332/444] Interface --------- Fixing typo in TimeOffset tooltip. --- source/blender/src/buttons_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index edc8e2a56a1..a90dd0447e9 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2768,7 +2768,7 @@ static void object_panel_anim(Object *ob) uiBlockBeginAlign(block); timeoffset_ui = give_timeoffset(ob); - but = uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 24,35,115,20, &timeoffset_ui, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Animation offset in frames for ipo's and dupligroup instances"); + but = uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 24,35,115,20, &timeoffset_ui, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Animation offset in frames for IPOs and dupligroup instances"); uiButSetFunc(but, object_panel_anim_timeoffset_callback, ob, &timeoffset_ui); uiDefBut(block, BUT, B_AUTOTIMEOFS, "Auto", 139,35,34,20, 0, 0, 0, 0, 0, "Assign selected objects a timeoffset within a range, starting from the active object"); From 7ba91ddcc37bbc8cd6c417e588d7ca7a3bb65e24 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 26 May 2009 07:41:34 +0000 Subject: [PATCH 333/444] BGE Script template for a python module (set EOL to native this time) BGE PyAPI use defines for error return values - del gameOb['var'] error message was wrong. --- .../scripttemplate_gamelogic_module.py | 45 +++++++++++++++++++ .../gameengine/Expressions/PyObjectPlus.cpp | 18 ++++---- source/gameengine/Expressions/Value.cpp | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 8 ++-- 4 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 release/scripts/scripttemplate_gamelogic_module.py diff --git a/release/scripts/scripttemplate_gamelogic_module.py b/release/scripts/scripttemplate_gamelogic_module.py new file mode 100644 index 00000000000..2ef4950917b --- /dev/null +++ b/release/scripts/scripttemplate_gamelogic_module.py @@ -0,0 +1,45 @@ +#!BPY +""" +Name: 'GameLogic Module' +Blender: 249 +Group: 'ScriptTemplate' +Tooltip: 'Basic template for new game logic modules' +""" + +from Blender import Window +import bpy + +script_data = \ +''' +# This module can be accessed by a python controller with +# its execution method set to 'Module' +# * Set the module string to "gamelogic_module.main" (without quotes) +# * When renaming the script it MUST have a .py extension +# * External text modules are supported as long as they are at +# the same location as the blendfile or one of its libraries. + +import GameLogic + +# variables defined here will only be set once when the +# module is first imported. Set object spesific vars +# inside the function if you intend to use the module +# with multiple objects. + +def main(cont): + own = cont.owner + + sens = cont.sensors['mySensor'] + actu = cont.actuators['myActuator'] + + if sens.positive: + cont.activate(actu) + else: + cont.deactivate(actu) + +# dont call main(GameLogic.getCurrentController()), the py controller will +''' + +new_text = bpy.data.texts.new('gamelogic_module.py') +new_text.write(script_data) +bpy.data.texts.active = new_text +Window.RedrawAll() diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 720094b6f98..defb6853e67 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -362,12 +362,12 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb if (!PySequence_Check(value)) { PyErr_Format(PyExc_TypeError, "expected a sequence for attribute \"%s\"", attrdef->m_name); - return 1; + return PY_SET_ATTR_FAIL; } if (PySequence_Size(value) != attrdef->m_length) { PyErr_Format(PyExc_TypeError, "incorrect number of elements in sequence for attribute \"%s\"", attrdef->m_name); - return 1; + return PY_SET_ATTR_FAIL; } switch (attrdef->m_type) { @@ -375,7 +375,7 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb if (attrdef->m_setFunction == NULL) { PyErr_Format(PyExc_AttributeError, "function attribute without function for attribute \"%s\", report to blender.org", attrdef->m_name); - return 1; + return PY_SET_ATTR_FAIL; } return (*attrdef->m_setFunction)(self, attrdef, value); case KX_PYATTRIBUTE_TYPE_BOOL: @@ -394,7 +394,7 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb default: // should not happen PyErr_Format(PyExc_AttributeError, "Unsupported attribute type for attribute \"%s\", report to blender.org", attrdef->m_name); - return 1; + return PY_SET_ATTR_FAIL; } // let's implement a smart undo method bufferSize *= attrdef->m_length; @@ -542,12 +542,12 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb memcpy(sourceBuffer, undoBuffer, bufferSize); free(undoBuffer); } - return 1; + return PY_SET_ATTR_FAIL; } } if (undoBuffer) free(undoBuffer); - return 0; + return PY_SET_ATTR_SUCCESS; } else // simple attribute value { @@ -556,7 +556,7 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb if (attrdef->m_setFunction == NULL) { PyErr_Format(PyExc_AttributeError, "function attribute without function \"%s\", report to blender.org", attrdef->m_name); - return 1; + return PY_SET_ATTR_FAIL; } return (*attrdef->m_setFunction)(self, attrdef, value); } @@ -589,7 +589,7 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb break; default: PyErr_Format(PyExc_AttributeError, "unknown type for attribute \"%s\", report to blender.org", attrdef->m_name); - return 1; + return PY_SET_ATTR_FAIL; } if (bufferSize) { @@ -712,7 +712,7 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb 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; + return PY_SET_ATTR_FAIL; } MT_Vector3 *var = reinterpret_cast(ptr); for (int i=0; i<3; i++) diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index f61ef1455b4..773fd94a0fb 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -662,7 +662,7 @@ int CValue::py_delattro(PyObject *attr) return 0; PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str); - return 1; + return PY_SET_ATTR_MISSING; } int CValue::py_setattro(PyObject *attr, PyObject* pyobj) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index f1c3fb89df2..1f7eeca1b69 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1342,7 +1342,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) if (del==0) { if(attr_str) PyErr_Format(PyExc_KeyError, "gameOb[key] = value: KX_GameObject, key \"%s\" could not be set", attr_str); - else PyErr_SetString(PyExc_KeyError, "gameOb[key] = value: KX_GameObject, key could not be set"); + else PyErr_SetString(PyExc_KeyError, "del gameOb[key]: KX_GameObject, key could not be deleted"); return -1; } else if (self->m_attr_dict) { @@ -1902,13 +1902,13 @@ int KX_GameObject::py_delattro(PyObject *attr) char *attr_str= PyString_AsString(attr); if (RemoveProperty(attr_str)) // XXX - should call CValues instead but its only 2 lines here - return 0; + return PY_SET_ATTR_SUCCESS; if (m_attr_dict && (PyDict_DelItem(m_attr_dict, attr) == 0)) - return 0; + return PY_SET_ATTR_SUCCESS; PyErr_Format(PyExc_AttributeError, "del gameOb.myAttr: KX_GameObject, attribute \"%s\" dosnt exist", attr_str); - return 1; + return PY_SET_ATTR_MISSING; } From ca4d741ce9865c696ef0e41c0c44dd916974d099 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 26 May 2009 08:30:28 +0000 Subject: [PATCH 334/444] Bugfix: (discovered by course participant :) Brush option "Clone" didn't read linked Clone Image from file. No idea how this ever could work even... even for Undo it would crash. --- source/blender/blenloader/intern/readfile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index abfb8ebd04c..a99cb86f86b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1459,6 +1459,8 @@ static void lib_link_brush(FileData *fd, Main *main) if(brush->id.flag & LIB_NEEDLINK) { brush->id.flag -= LIB_NEEDLINK; + brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image); + for(a=0; amtex[a]; if(mtex) From e93d1ba8e775a481e9a719355b12d4523cabcae1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 26 May 2009 10:44:14 +0000 Subject: [PATCH 335/444] Misc warnings - Removed/Commented some unused vars - CValue::GetPropertyText() could return a temp reference to a variable on the stack, option wasnt used anywhere so removed. - KX_ConstraintWrapper::GetConstraintId allows args but ignored them - KX_ConstraintWrapper::PySetParam didnt return NULL on an error (messing up pythons exceptions). - BLI_natstrcmp didnt return 0 when the while loop exited --- .../blenkernel/bad_level_call_stubs/stubs.c | 3 ++- source/blender/blenkernel/intern/anim.c | 2 +- source/blender/blenlib/intern/util.c | 2 +- .../imbuf/intern/openexr/openexr_api.cpp | 2 +- source/blender/python/api2_2x/Geometry.c | 2 +- source/blender/src/butspace.c | 2 +- source/blender/src/buttons_editing.c | 2 +- source/blender/src/drawobject.c | 2 +- source/gameengine/Expressions/Value.cpp | 4 +--- source/gameengine/Expressions/Value.h | 2 +- .../GamePlayer/common/GPC_RenderTools.cpp | 3 --- source/gameengine/Ketsji/KX_Camera.cpp | 1 - .../gameengine/Ketsji/KX_ConstraintWrapper.cpp | 17 +++++++---------- source/gameengine/Ketsji/KX_ConstraintWrapper.h | 3 +-- source/gameengine/Ketsji/KX_MeshProxy.cpp | 1 - source/gameengine/VideoTexture/PyTypeList.cpp | 1 - 16 files changed, 19 insertions(+), 30 deletions(-) diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 3012c19ff02..1a33102f845 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -57,6 +57,7 @@ struct bConstraintOb; struct bConstraintTarget; struct ListBase; struct EditFace; +struct LOD_Decimation_Info; char *getIpoCurveName( struct IpoCurve * icu ); void insert_vert_icu(struct IpoCurve *icu, float x, float y, short fast); @@ -160,7 +161,7 @@ void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTa void free_oops(struct Oops *oops){} void exit_posemode(int freedata){} void error(char *str, ...){} -int okee(char *str, ...){} +int okee(char *str, ...){return 1;} /* anim.c */ ListBase editNurb; diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 50be417c8ef..ffb7ff51b87 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -747,7 +747,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_ float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], size=0.0; float (*obmat)[4], (*oldobmat)[4]; - int lay, a, b, k, counter, hair = 0; + int lay, a, b, counter, hair = 0; int totpart, totchild, totgroup=0, pa_num; if(psys==0) return; diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 842ebc4c0a9..e202d91f0e6 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -2030,7 +2030,7 @@ int BLI_natstrcmp(const char *s1, const char *s2) d1++; d2++; } - + return 0; } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 9e077cbc809..32d97d79bd7 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -865,7 +865,7 @@ static const char *exr_rgba_channelname(InputFile *file, const char *chan) for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { - const Channel &channel = i.channel(); + /* const Channel &channel = i.channel(); */ /* Not used yet */ const char *str= i.name(); int len= strlen(str); if(len) { diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index 2ac6b8a714a..f875cbc52fb 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -488,7 +488,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) float k2[4] = {0.0, 0.0, 0.0, 0.0}; float h2[4] = {0.0, 0.0, 0.0, 0.0}; - float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, newvec[2]; + if( !PyArg_ParseTuple ( args, "O!O!O!O!i", &vector_Type, &vec_k1, &vector_Type, &vec_h1, diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c index ba4d02d2355..38d628d2056 100644 --- a/source/blender/src/butspace.c +++ b/source/blender/src/butspace.c @@ -511,7 +511,7 @@ void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short static void do_node_buts(unsigned short event) { Material *ma; - SpaceNode *snode = curarea->spacedata.first; + /* SpaceNode *snode = curarea->spacedata.first; */ /* all operations default on active material layer here */ /* but this also gets called for lamp and world... */ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 1ecc63fe93d..43fafeb387a 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -6437,7 +6437,7 @@ void brush_buttons(uiBlock *block, short sima, } else { if ( - (sima==NULL) && /* 3D View */ + (!sima) && /* 3D View */ (settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0 && /* Projection Painting */ (settings->imapaint.tool == PAINT_TOOL_CLONE) ) { diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 5fb60449a25..ef37b184a85 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2918,7 +2918,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) float cfra=bsystem_time(ob,(float)CFRA,0.0); float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3]; float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f; - int a, k, k_max=0, totpart, totpoint=0, draw_as, totchild=0; + int a, totpart, totpoint=0, draw_as, totchild=0; int select=ob->flag&SELECT, create_cdata=0; GLint polygonmode[2]; char val[32]; diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 773fd94a0fb..08249f92902 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -292,15 +292,13 @@ CValue* CValue::GetProperty(const char *inName) // // Get text description of property with name , returns an empty string if there is no property named // -const STR_String& CValue::GetPropertyText(const STR_String & inName,const char *deftext) +const STR_String& CValue::GetPropertyText(const STR_String & inName) { const static STR_String sEmpty(""); CValue *property = GetProperty(inName); if (property) return property->GetText(); - else if (deftext) - return STR_String(deftext); else return sEmpty; } diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 0be76c4f452..29ef19b46c9 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -310,7 +310,7 @@ public: virtual void SetProperty(const char* name,CValue* ioProperty); virtual CValue* GetProperty(const char* inName); // Get pointer to a property with name , returns NULL if there is no property named virtual CValue* GetProperty(const STR_String & inName); - const STR_String& GetPropertyText(const STR_String & inName,const char *deftext=NULL); // Get text description of property with name , returns an empty string if there is no property named + const STR_String& GetPropertyText(const STR_String & inName); // Get text description of property with name , returns an empty string if there is no property named float GetPropertyNumber(const STR_String& inName,float defnumber); virtual bool RemoveProperty(const char *inName); // Remove the property named , returns true if the property was succesfully removed, false if property was not found or could not be removed virtual vector GetPropertyNames(); diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 1a0d985a864..02f23a8431b 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -288,10 +288,7 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode, int height) { STR_String tmpstr(text); - int lines; char* s = tmpstr.Ptr(); - char* p; - // Save and change OpenGL settings int texture2D; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 144ff4ac883..1d6c5f77ae5 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -1105,7 +1105,6 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay, "getScreenRay()\n" ) { - KX_Camera* cam; MT_Vector3 vect; double x,y,dist; char *propName = NULL; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index b40100db2f7..3e5594e0d1c 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -49,23 +49,20 @@ KX_ConstraintWrapper::~KX_ConstraintWrapper() { } -PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds) +PyObject* KX_ConstraintWrapper::PyGetConstraintId() { return PyInt_FromLong(m_constraintId); } PyObject* KX_ConstraintWrapper::PySetParam(PyObject* args, PyObject* kwds) { - int len = PyTuple_Size(args); - int success = 1; - int dof; float minLimit,maxLimit; - success = PyArg_ParseTuple(args,"iff:setParam",&dof,&minLimit,&maxLimit); - if (success) - { - m_physenv->setConstraintParam(m_constraintId,dof,minLimit,maxLimit); - } + + if (!PyArg_ParseTuple(args,"iff:setParam",&dof,&minLimit,&maxLimit)) + return NULL; + + m_physenv->setConstraintParam(m_constraintId,dof,minLimit,maxLimit); Py_RETURN_NONE; } @@ -120,7 +117,7 @@ int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value) PyMethodDef KX_ConstraintWrapper::Methods[] = { - {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS}, + {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_NOARGS}, {"setParam",(PyCFunction) KX_ConstraintWrapper::sPySetParam, METH_VARARGS}, {NULL,NULL} //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index b8ac464ceab..d4f038e2898 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -43,8 +43,7 @@ public: virtual ~KX_ConstraintWrapper (); int getConstraintId() { return m_constraintId;}; - KX_PYMETHOD(KX_ConstraintWrapper,TestMethod); - KX_PYMETHOD(KX_ConstraintWrapper,GetConstraintId); + KX_PYMETHOD_NOARGS(KX_ConstraintWrapper,GetConstraintId); KX_PYMETHOD(KX_ConstraintWrapper,SetParam); private: diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 0d1bc289a5c..11effa1ca98 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -222,7 +222,6 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* args, PyObject* kwds) { int vertexindex; int matindex; - PyObject* vertexob = NULL; if (!PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex)) return NULL; diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp index 6d2676dce09..2d571675dbd 100644 --- a/source/gameengine/VideoTexture/PyTypeList.cpp +++ b/source/gameengine/VideoTexture/PyTypeList.cpp @@ -45,7 +45,6 @@ bool PyTypeList::in (PyTypeObject * type) /// add type to list void PyTypeList::add (PyTypeObject * type, const char * name) { - PyTypeListItem * typeItem; // if list doesn't exist, create it if (m_list.get() == NULL) m_list.reset(new PyTypeListType()); From 137b3e1dc519bef99bad4201e9374346877bbe40 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 26 May 2009 12:57:16 +0000 Subject: [PATCH 336/444] == Sequencer == This adds a per preview option to set render sizes (which proxy size is used). That makes it possible to have * several small preview screens which update really fast using the proxy files * one large output screen that operates in full resolution Since most of the time not all input strips are considered when calculating an output screen, this is a big win. Also: one can disable a preview screen completely using this option. Other use cases: vector + chromaviews don't always need full resolution pictures and work equally well on proxy files! This option finally makes my working setup _completely_ realtime :) --- source/blender/include/BSE_sequence.h | 10 +- source/blender/makesdna/DNA_space_types.h | 3 +- source/blender/src/drawseq.c | 35 +++-- source/blender/src/header_seq.c | 16 +++ source/blender/src/sequence.c | 154 +++++++++++++--------- 5 files changed, 142 insertions(+), 76 deletions(-) diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 0d96de7be60..33a43e1a458 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -68,18 +68,20 @@ char *give_seqname(struct Sequence *seq); int evaluate_seq_frame(int cfra); struct StripElem *give_stripelem(struct Sequence *seq, int cfra); struct TStripElem *give_tstripelem(struct Sequence *seq, int cfra); -struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel); +struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel, + int render_size); /* chansel: render this channel. Default=0 (renders end result)*/ struct ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, - struct Sequence * seq); + int render_size, struct Sequence * seq); /* sequence prefetch API */ void seq_start_threads(); void seq_stop_threads(); -void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown); +void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown, + int render_size); void seq_wait_for_prefetch_ready(); struct ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, - int chanshown); + int chanshown, int render_size); void free_imbuf_seq_except(int cfra); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d14acc12693..4cbd31b4519 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -146,7 +146,8 @@ typedef struct SpaceSeq { View2D v2d; float xof, yof; /* offset for drawing the image preview */ - short mainb, pad; + short mainb; + short render_size; short chanshown; short zebra; int flag; diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 6bba4fbdcc4..7fd7d8880a1 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -849,6 +849,7 @@ static void draw_image_seq(ScrArea *sa) static int recursive= 0; float zoom; float zoomx, zoomy; + int render_size = 0; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -856,8 +857,16 @@ static void draw_image_seq(ScrArea *sa) sseq= sa->spacedata.first; if(sseq==0) return; - rectx= (G.scene->r.size*G.scene->r.xsch)/100; - recty= (G.scene->r.size*G.scene->r.ysch)/100; + render_size = sseq->render_size; + if (render_size == 0) { + render_size = G.scene->r.size; + } + if (render_size < 0) { + return; + } + + rectx= (render_size*G.scene->r.xsch)/100; + recty= (render_size*G.scene->r.ysch)/100; /* BIG PROBLEM: the give_ibuf_seq() can call a rendering, which in turn calls redraws... this shouldn't belong in a window drawing.... @@ -870,16 +879,16 @@ static void draw_image_seq(ScrArea *sa) recursive= 1; if (special_seq_update) { ibuf= give_ibuf_seq_direct( - rectx, recty, (G.scene->r.cfra), + rectx, recty, (G.scene->r.cfra), render_size, special_seq_update); } else if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) { ibuf= (ImBuf *)give_ibuf_seq( rectx, recty, (G.scene->r.cfra), - sseq->chanshown); + sseq->chanshown, render_size); } else { ibuf= (ImBuf *)give_ibuf_seq_threaded( rectx, recty, (G.scene->r.cfra), - sseq->chanshown); + sseq->chanshown, render_size); } recursive= 0; @@ -930,7 +939,7 @@ static void draw_image_seq(ScrArea *sa) zoom= SEQ_ZOOM_FAC(sseq->zoom); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - zoom /= G.scene->r.size / 100.0; + zoom /= render_size / 100.0; zoomx = zoom * ((float)G.scene->r.xasp / (float)G.scene->r.yasp); zoomy = zoom; } else { @@ -1112,13 +1121,21 @@ void drawprefetchseqspace(ScrArea *sa, void *spacedata) { SpaceSeq *sseq= sa->spacedata.first; int rectx, recty; + int render_size = sseq->render_size; + if (render_size == 0) { + render_size = G.scene->r.size; + } + if (render_size < 0) { + return; + } - rectx= (G.scene->r.size*G.scene->r.xsch)/100; - recty= (G.scene->r.size*G.scene->r.ysch)/100; + rectx= (render_size*G.scene->r.xsch)/100; + recty= (render_size*G.scene->r.ysch)/100; if(sseq->mainb) { give_ibuf_prefetch_request( - rectx, recty, (G.scene->r.cfra), sseq->chanshown); + rectx, recty, (G.scene->r.cfra), sseq->chanshown, + render_size); } } diff --git a/source/blender/src/header_seq.c b/source/blender/src/header_seq.c index 8138918877f..23712b93b50 100644 --- a/source/blender/src/header_seq.c +++ b/source/blender/src/header_seq.c @@ -740,6 +740,22 @@ void seq_buttons() xco+= 8 + XIC*3.5; + uiDefButS(block, MENU, B_REDR, + "Render size: %t" + "|R 100 %x100" + "|R 75 %x75" + "|R 50 %x50" + "|R 25 %x25" + "|R Sce %x0" + "|R Off %x-1", + xco,0,3.0 * XIC, YIC, &sseq->render_size, + 0,0,0,0, + "Use different (proxy) render size " + "for this preview screen, use scene render size " + "or disable this preview completely"); + + xco+= 8 + XIC*3.0; + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { uiDefButS(block, MENU, B_REDR, "Show zebra: %t" diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index a6f264e2b09..cf2b28c6d72 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1047,7 +1047,8 @@ static int get_shown_sequences( #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE) -static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name) +static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name, + int render_size) { int frameno; char dir[FILE_MAXDIR]; @@ -1080,7 +1081,7 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name) if (seq->type == SEQ_IMAGE) { StripElem * se = give_stripelem(seq, cfra); snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", - dir, G.scene->r.size, se->name); + dir, render_size, se->name); frameno = 1; } else if (seq->type == SEQ_MOVIE) { TStripElem * tse = give_tstripelem(seq, cfra); @@ -1089,14 +1090,14 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name) snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir, seq->strip->stripdata->name, - G.scene->r.size); + render_size); } else { TStripElem * tse = give_tstripelem(seq, cfra); frameno = tse->nr + seq->anim_startofs; snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir, - G.scene->r.size); + render_size); } BLI_convertstringcode(name, G.sce); @@ -1108,7 +1109,8 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name) return TRUE; } -static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) +static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra, + int render_size) { char name[PROXY_MAXFILE]; @@ -1117,7 +1119,7 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) } /* rendering at 100% ? No real sense in proxy-ing, right? */ - if (G.scene->r.size == 100.0) { + if (render_size == 100) { return 0; } @@ -1125,7 +1127,7 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) TStripElem * tse = give_tstripelem(seq, cfra); int frameno = tse->nr + seq->anim_startofs; if (!seq->strip->proxy->anim) { - if (!seq_proxy_get_fname(seq, cfra, name)) { + if (!seq_proxy_get_fname(seq, cfra,name,render_size)) { return 0; } @@ -1138,7 +1140,7 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) return IMB_anim_absolute(seq->strip->proxy->anim, frameno); } - if (!seq_proxy_get_fname(seq, cfra, name)) { + if (!seq_proxy_get_fname(seq, cfra, name, render_size)) { return 0; } @@ -1150,9 +1152,9 @@ static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra) } static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, - int build_proxy_run); + int build_proxy_run, int render_size); -static void seq_proxy_build_frame(Sequence * seq, int cfra) +static void seq_proxy_build_frame(Sequence * seq, int cfra, int render_size) { char name[PROXY_MAXFILE]; int quality; @@ -1166,7 +1168,7 @@ static void seq_proxy_build_frame(Sequence * seq, int cfra) } /* rendering at 100% ? No real sense in proxy-ing, right? */ - if (G.scene->r.size == 100.0) { + if (render_size == 100.0) { return; } @@ -1175,7 +1177,7 @@ static void seq_proxy_build_frame(Sequence * seq, int cfra) return; } - if (!seq_proxy_get_fname(seq, cfra, name)) { + if (!seq_proxy_get_fname(seq, cfra, name, render_size)) { return; } @@ -1189,14 +1191,14 @@ static void seq_proxy_build_frame(Sequence * seq, int cfra) se->ibuf = 0; } - do_build_seq_ibuf(seq, se, cfra, TRUE); + do_build_seq_ibuf(seq, se, cfra, TRUE, render_size); if (!se->ibuf) { return; } - rectx= (G.scene->r.size*G.scene->r.xsch)/100; - recty= (G.scene->r.size*G.scene->r.ysch)/100; + rectx= (render_size*G.scene->r.xsch)/100; + recty= (render_size*G.scene->r.ysch)/100; ibuf = se->ibuf; @@ -1251,7 +1253,8 @@ void seq_proxy_rebuild(Sequence * seq) TStripElem * tse = give_tstripelem(seq, cfra); if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) { - seq_proxy_build_frame(seq, cfra); + seq_proxy_build_frame(seq, cfra, + G.scene->r.size); tse->flag |= STRIPELEM_PREVIEW_DONE; } if (blender_test_break()) { @@ -1264,7 +1267,8 @@ void seq_proxy_rebuild(Sequence * seq) TStripElem * tse = give_tstripelem(seq, cfra); if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) { - seq_proxy_build_frame(seq, cfra); + seq_proxy_build_frame(seq, cfra, + G.scene->r.size); tse->flag |= STRIPELEM_PREVIEW_DONE; } if (blender_test_break()) { @@ -1752,10 +1756,10 @@ static void check_limiter_refcount_comp(const char * func, TStripElem *se) } static TStripElem* do_build_seq_array_recursively( - ListBase *seqbasep, int cfra, int chanshown); + ListBase *seqbasep, int cfra, int chanshown, int render_size); static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, - int build_proxy_run) + int build_proxy_run, int render_size) { char name[FILE_MAXDIR+FILE_MAXFILE]; int use_limiter = TRUE; @@ -1769,7 +1773,7 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, use_limiter = FALSE; if (!build_proxy_run && se->ibuf == 0) { - se->ibuf = seq_proxy_fetch(seq, cfra); + se->ibuf = seq_proxy_fetch(seq, cfra, render_size); if (se->ibuf) { use_limiter = TRUE; use_preprocess = TRUE; @@ -1778,7 +1782,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, if(!se->ibuf && seq->seqbase.first) { meta_se = do_build_seq_array_recursively( - &seq->seqbase, seq->start + se->nr, 0); + &seq->seqbase, seq->start + se->nr, 0, + render_size); check_limiter_refcount("do_build_seq_ibuf: for META", meta_se); @@ -1820,7 +1825,7 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, /* should the effect be recalculated? */ if (!build_proxy_run && se->ibuf == 0) { - se->ibuf = seq_proxy_fetch(seq, cfra); + se->ibuf = seq_proxy_fetch(seq, cfra, render_size); } if(se->ibuf == 0) { @@ -1841,7 +1846,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, BLI_convertstringcode(name, G.sce); BLI_convertstringframe(name, G.scene->r.cfra); if (!build_proxy_run) { - se->ibuf = seq_proxy_fetch(seq, cfra); + se->ibuf = seq_proxy_fetch(seq, cfra, + render_size); } copy_from_ibuf_still(seq, se); @@ -1866,7 +1872,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, } else if(seq->type == SEQ_MOVIE) { if(se->ok == STRIPELEM_OK && se->ibuf==0) { if(!build_proxy_run) { - se->ibuf = seq_proxy_fetch(seq, cfra); + se->ibuf = seq_proxy_fetch(seq, cfra, + render_size); } copy_from_ibuf_still(seq, se); @@ -1912,7 +1919,7 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, int sce_valid =sce&& (sce->camera || sce->r.scemode & R_DOSEQ); if (se->ibuf == NULL && sce_valid && !build_proxy_run) { - se->ibuf = seq_proxy_fetch(seq, cfra); + se->ibuf = seq_proxy_fetch(seq, cfra, render_size); if (se->ibuf) { input_preprocess(seq, se, cfra); } @@ -2010,9 +2017,11 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, } } -static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra); +static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra, + int render_size); -static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) +static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra, + int render_size) { float fac, facf; struct SeqEffectHandle sh = get_sequence_effect(seq); @@ -2038,22 +2047,27 @@ static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) /* no input needed */ break; case 0: - se->se1 = do_build_seq_recursively(seq->seq1, cfra); - se->se2 = do_build_seq_recursively(seq->seq2, cfra); + se->se1 = do_build_seq_recursively(seq->seq1, cfra, + render_size); + se->se2 = do_build_seq_recursively(seq->seq2, cfra, + render_size); if (seq->seq3) { - se->se3 = do_build_seq_recursively(seq->seq3, cfra); + se->se3 = do_build_seq_recursively(seq->seq3, cfra, + render_size); } break; case 1: - se->se1 = do_build_seq_recursively(seq->seq1, cfra); + se->se1 = do_build_seq_recursively(seq->seq1, cfra, + render_size); break; case 2: - se->se2 = do_build_seq_recursively(seq->seq2, cfra); + se->se2 = do_build_seq_recursively(seq->seq2, cfra, + render_size); break; } - do_build_seq_ibuf(seq, se, cfra, FALSE); + do_build_seq_ibuf(seq, se, cfra, FALSE, render_size); /* children are not needed anymore ... */ @@ -2069,7 +2083,8 @@ static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) check_limiter_refcount("do_effect_seq_recursively", se); } -static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra) +static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra, + int render_size) { TStripElem *se; @@ -2077,9 +2092,9 @@ static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra) if(se) { if (seq->type & SEQ_EFFECT) { - do_effect_seq_recursively(seq, se, cfra); + do_effect_seq_recursively(seq, se, cfra, render_size); } else { - do_build_seq_ibuf(seq, se, cfra, FALSE); + do_build_seq_ibuf(seq, se, cfra, FALSE, render_size); } } check_limiter_refcount("do_build_seq_recursively_impl", se); @@ -2094,7 +2109,8 @@ instead of faking using the blend code below... */ -static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) +static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra, + int render_size) { SpeedControlVars * s = (SpeedControlVars *)seq->effectdata; int nr = cfra - seq->start; @@ -2124,7 +2140,7 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) if (se->ibuf == NULL) { se1 = do_build_seq_recursively_impl( - seq->seq1, cfra_left); + seq->seq1, cfra_left, render_size); if((se1 && se1->ibuf && se1->ibuf->rect_float)) se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); @@ -2157,9 +2173,9 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) if (se->ibuf == NULL) { se1 = do_build_seq_recursively_impl( - seq->seq1, cfra_left); + seq->seq1, cfra_left, render_size); se2 = do_build_seq_recursively_impl( - seq->seq1, cfra_right); + seq->seq1, cfra_right, render_size); if((se1 && se1->ibuf && se1->ibuf->rect_float)) se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0); @@ -2211,13 +2227,14 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) * */ -static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) +static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra, + int render_size) { TStripElem* se; if (seq->type == SEQ_SPEED) { - se = do_handle_speed_effect(seq, cfra); + se = do_handle_speed_effect(seq, cfra, render_size); } else { - se = do_build_seq_recursively_impl(seq, cfra); + se = do_build_seq_recursively_impl(seq, cfra, render_size); } check_limiter_refcount("do_build_seq_recursively", se); @@ -2226,7 +2243,7 @@ static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) } static TStripElem* do_build_seq_array_recursively( - ListBase *seqbasep, int cfra, int chanshown) + ListBase *seqbasep, int cfra, int chanshown, int render_size) { Sequence* seq_arr[MAXSEQ+1]; int count; @@ -2256,7 +2273,7 @@ static TStripElem* do_build_seq_array_recursively( if(count == 1) { - se = do_build_seq_recursively(seq_arr[0], cfra); + se = do_build_seq_recursively(seq_arr[0], cfra, render_size); if (se->ibuf) { se->ibuf_comp = se->ibuf; IMB_refImBuf(se->ibuf_comp); @@ -2278,7 +2295,7 @@ static TStripElem* do_build_seq_array_recursively( break; } if (seq->blend_mode == SEQ_BLEND_REPLACE) { - do_build_seq_recursively(seq, cfra); + do_build_seq_recursively(seq, cfra, render_size); if (se->ibuf) { se->ibuf_comp = se->ibuf; IMB_refImBuf(se->ibuf); @@ -2311,7 +2328,7 @@ static TStripElem* do_build_seq_array_recursively( switch (early_out) { case -1: case 2: - do_build_seq_recursively(seq, cfra); + do_build_seq_recursively(seq, cfra, render_size); if (se->ibuf) { se->ibuf_comp = se->ibuf; IMB_refImBuf(se->ibuf_comp); @@ -2335,7 +2352,7 @@ static TStripElem* do_build_seq_array_recursively( } break; case 0: - do_build_seq_recursively(seq, cfra); + do_build_seq_recursively(seq, cfra, render_size); if (!se->ibuf) { se->ibuf = IMB_allocImBuf( (short)seqrectx, (short)seqrecty, @@ -2449,7 +2466,8 @@ static TStripElem* do_build_seq_array_recursively( * you have to unref after usage! */ -static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) +static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown, + int render_size) { Editing *ed; int count; @@ -2470,7 +2488,8 @@ static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) seqrectx= rectx; /* bad bad global! */ seqrecty= recty; - se = do_build_seq_array_recursively(seqbasep, cfra, chanshown); + se = do_build_seq_array_recursively(seqbasep, cfra, chanshown, + render_size); if(!se) { return 0; @@ -2481,7 +2500,7 @@ static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) return se->ibuf_comp; } -ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, +ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, int render_size, Sequence * seq) { TStripElem* se; @@ -2489,7 +2508,7 @@ ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, seqrectx= rectx; /* bad bad global! */ seqrecty= recty; - se = do_build_seq_recursively(seq, cfra); + se = do_build_seq_recursively(seq, cfra, render_size); if(!se) { return 0; @@ -2504,9 +2523,11 @@ ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, return se->ibuf; } -ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown) +ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown, + int render_size) { - ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown); + ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown, + render_size); if (i) { IMB_cache_limiter_unref(i); @@ -2558,6 +2579,7 @@ typedef struct PrefetchQueueElem { int recty; int cfra; int chanshown; + int render_size; int monoton_cfra; @@ -2603,7 +2625,8 @@ static void * seq_prefetch_thread(void * This_) if (e->cfra >= s_last) { e->ibuf = give_ibuf_seq_impl( - e->rectx, e->recty, e->cfra, e->chanshown); + e->rectx, e->recty, e->cfra, e->chanshown, + e->render_size); } pthread_mutex_lock(&queue_lock); @@ -2712,7 +2735,8 @@ void seq_stop_threads() BLI_end_threads(0); } -void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown) +void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown, + int render_size) { PrefetchQueueElem * e; if (seq_thread_shutdown) { @@ -2724,6 +2748,7 @@ void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown) e->recty = recty; e->cfra = cfra; e->chanshown = chanshown; + e->render_size = render_size; e->monoton_cfra = monoton_cfra++; pthread_mutex_lock(&queue_lock); @@ -2764,13 +2789,15 @@ void seq_wait_for_prefetch_ready() fprintf(stderr, "SEQ-THREAD: prefetch done\n"); } -ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown) +ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown, + int render_size) { PrefetchQueueElem * e = 0; int found_something = FALSE; if (seq_thread_shutdown) { - return give_ibuf_seq(rectx, recty, cfra, chanshown); + return give_ibuf_seq(rectx, recty, cfra, chanshown, + render_size); } while (!e) { @@ -2781,7 +2808,8 @@ ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown) if (cfra == e->cfra && chanshown == e->chanshown && rectx == e->rectx && - recty == e->recty) { + recty == e->recty && + render_size == e->render_size) { success = TRUE; found_something = TRUE; break; @@ -2793,7 +2821,8 @@ ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown) if (cfra == e->cfra && chanshown == e->chanshown && rectx == e->rectx && - recty == e->recty) { + recty == e->recty && + render_size == e->render_size) { found_something = TRUE; break; } @@ -2809,7 +2838,8 @@ ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown) cfra == tslot->current->cfra && chanshown == tslot->current->chanshown && rectx == tslot->current->rectx && - recty == tslot->current->recty) { + recty == tslot->current->recty && + render_size== tslot->current->render_size){ found_something = TRUE; break; } @@ -3048,7 +3078,7 @@ void do_render_seq(RenderResult *rr, int cfra) G.f |= G_PLAYANIM; /* waitcursor patch */ - ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0); + ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0, G.scene->r.size); if(ibuf) { if(ibuf->rect_float) { From 33304d022d7f43eb1319fe7e9db33ec6559c275d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 26 May 2009 13:46:08 +0000 Subject: [PATCH 337/444] Bugfix #18801 Third transparent shadow bug... this time it's a Material Node, which has mirror + transp-shadow on, and when it traces its own material it enters an eternal loop... Raytracing + shading + materialnode combo really needs work! --- source/blender/nodes/intern/SHD_nodes/SHD_material.c | 2 ++ source/blender/render/extern/include/RE_shader_ext.h | 1 + source/blender/render/intern/source/rayshade.c | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c index c0a2534ac4a..69c2c0a345c 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c @@ -130,7 +130,9 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, nodestack_get_vec(&shi->translucency, SOCK_VALUE, in[MAT_IN_TRANSLUCENCY]); } + shi->nodes= 1; /* temp hack to prevent trashadow recursion */ node_shader_lamp_loop(shi, &shrnode); /* clears shrnode */ + shi->nodes= 0; /* write to outputs */ if(node->custom1 & SH_NODE_MAT_DIFF) { diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 2cee2673a26..0ad48fe97a9 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -171,6 +171,7 @@ typedef struct ShadeInput /* from initialize, part or renderlayer */ short do_preview; /* for nodes, in previewrender */ short thread, sample; /* sample: ShadeSample array index */ + short nodes; /* indicate node shading, temp hack to prevent recursion */ unsigned int lay; int layflag, passflag, combinedflag; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index f4dcbe9e186..75b9557f337 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -263,7 +263,8 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shade_input_set_shade_texco(shi); if(is->mode==RE_RAY_SHADOW_TRA) { - if(shi->mat->nodetree && shi->mat->use_nodes) { + /* temp hack to prevent recursion */ + if(shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ } @@ -1299,6 +1300,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int shi.xs= origshi->xs; shi.ys= origshi->ys; shi.lay= origshi->lay; + shi.nodes= origshi->nodes; shade_ray(is, &shi, &shr); if (traflag & RAY_TRA) From 7e48820a97a1cc5d806caa2c7ea5b47f4809aa58 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 26 May 2009 15:01:06 +0000 Subject: [PATCH 338/444] Fix for bug #18788: vector math node subtract did not work, patch by Matt D., thanks. --- source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c b/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c index 96db8db18a6..8a73a318f70 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c @@ -101,7 +101,7 @@ static void node_shader_exec_vect_math(void *data, bNode *node, bNodeStack **in, static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { - static char *names[] = {"vec_math_add", "vec_math_subtract", + static char *names[] = {"vec_math_add", "vec_math_sub", "vec_math_average", "vec_math_dot", "vec_math_cross", "vec_math_normalize"}; From 33b974ee43c2d6c131860efbe02fd478197b9fda Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 26 May 2009 16:15:40 +0000 Subject: [PATCH 339/444] BGE Py API - Deprecation warnings for using attribute access - Added dictionary functions to KX_GameObject and ListValue ob.get(key, default=None) ob.has_key(key) ob.has_key is important since there was no way to do something like hasattr(ob, "attr") which can be replaced by ob.has_key("attr") - (both still work of course). ob.get is just useful in many cases where you want a property if it exists but can fallback to a default. - CListValue::FindValue was adding a reference but the ~3 places it was used were releasing the reference. added a FindValue that accepts a const char* type to avoid converting python strings to STR_String. --- source/gameengine/Expressions/ListValue.cpp | 65 +++++++++++++------ source/gameengine/Expressions/ListValue.h | 3 + source/gameengine/Expressions/Value.cpp | 6 ++ .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 1 - source/gameengine/Ketsji/KX_GameObject.cpp | 50 +++++++++++++- source/gameengine/Ketsji/KX_GameObject.h | 5 ++ source/gameengine/PyDoc/GameTypes.py | 24 +++++++ 7 files changed, 132 insertions(+), 22 deletions(-) diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 75ae2cb787f..c741a6d8809 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -76,13 +76,9 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) if (PyString_Check(pyindex)) { - const char *index = PyString_AsString(pyindex); - CValue *item = ((CListValue*) list)->FindValue(index); + CValue *item = ((CListValue*) list)->FindValue(PyString_AsString(pyindex)); if (item) - { - item->Release(); /* FindValue() AddRef's */ return item->GetProxy(); - } } else if (PyInt_Check(pyindex)) { @@ -279,10 +275,17 @@ PyParentObject CListValue::Parents[] = { PyMethodDef CListValue::Methods[] = { + /* List style access */ {"append", (PyCFunction)CListValue::sPyappend,METH_O}, {"reverse", (PyCFunction)CListValue::sPyreverse,METH_NOARGS}, {"index", (PyCFunction)CListValue::sPyindex,METH_O}, {"count", (PyCFunction)CListValue::sPycount,METH_O}, + + /* Dict style access */ + {"get", (PyCFunction)CListValue::sPyget,METH_VARARGS}, + {"has_key", (PyCFunction)CListValue::sPyhas_key,METH_O}, + + /* Own cvalue funcs */ {"from_id", (PyCFunction)CListValue::sPyfrom_id,METH_O}, {NULL,NULL} //Sentinel @@ -395,25 +398,23 @@ void CListValue::ReleaseAndRemoveAll() -CValue* CListValue::FindValue(const char * name) +CValue* CListValue::FindValue(const STR_String & name) { - CValue* resultval = NULL; - int i=0; + for (int i=0; i < GetCount(); i++) + if (GetValue(i)->GetName() == name) + return GetValue(i); - while (!resultval && i < GetCount()) - { - CValue* myval = GetValue(i); - - if (myval->GetName() == name) - resultval = GetValue(i)->AddRef(); // add referencecount - else - i++; - - } - return resultval; + return NULL; } - +CValue* CListValue::FindValue(const char * name) +{ + for (int i=0; i < GetCount(); i++) + if (GetValue(i)->GetName() == name) + return GetValue(i); + + return NULL; +} bool CListValue::SearchValue(CValue *val) { @@ -564,7 +565,31 @@ PyObject* CListValue::Pycount(PyObject* value) return PyInt_FromLong(numfound); } +/* Matches python dict.get(key, [default]) */ +PyObject* CListValue::Pyget(PyObject *args) +{ + char *key; + PyObject* def = Py_None; + if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) + return NULL; + + CValue *item = FindValue((const char *)key); + if (item) + return item->GetProxy(); + + Py_INCREF(def); + return def; +} + +/* Matches python dict.has_key() */ +PyObject* CListValue::Pyhas_key(PyObject* value) +{ + if (PyString_Check(value) && FindValue((const char *)PyString_AsString(value))) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} PyObject* CListValue::Pyfrom_id(PyObject* value) { diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index ad918cbb925..68e900e25e0 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -45,6 +45,7 @@ public: void SetReleaseOnDestruct(bool bReleaseContents); bool SearchValue(CValue* val); + CValue* FindValue(const STR_String & name); CValue* FindValue(const char *name); void ReleaseAndRemoveAll(); @@ -74,6 +75,8 @@ public: KX_PYMETHOD_NOARGS(CListValue,reverse); KX_PYMETHOD_O(CListValue,index); KX_PYMETHOD_O(CListValue,count); + KX_PYMETHOD_VARARGS(CListValue,get); + KX_PYMETHOD_O(CListValue,has_key); KX_PYMETHOD_O(CListValue,from_id); diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 08249f92902..7f4ed388442 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -556,6 +556,8 @@ PyAttributeDef CValue::Attributes[] = { PyObject* CValue::py_getattro(PyObject *attr) { + ShowDeprecationWarning("val = ob.attr", "val = ob['attr']"); + char *attr_str= PyString_AsString(attr); CValue* resultattr = GetProperty(attr_str); if (resultattr) @@ -655,6 +657,8 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) int CValue::py_delattro(PyObject *attr) { + ShowDeprecationWarning("del ob.attr", "del ob['attr']"); + char *attr_str= PyString_AsString(attr); if (RemoveProperty(attr_str)) return 0; @@ -665,6 +669,8 @@ int CValue::py_delattro(PyObject *attr) int CValue::py_setattro(PyObject *attr, PyObject* pyobj) { + ShowDeprecationWarning("ob.attr = val", "ob['attr'] = val"); + char *attr_str= PyString_AsString(attr); CValue* oldprop = GetProperty(attr_str); CValue* vallie; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index f1543d752f1..bc2d718203b 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -714,7 +714,6 @@ void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras) mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame); if(!obj) return; - obj->Release(); /* FindValue() AddRef's */ obj->Release(); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 1f7eeca1b69..f75f611f9bb 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1190,7 +1190,11 @@ PyMethodDef KX_GameObject::Methods[] = { KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo), KX_PYMETHODTABLE_O(KX_GameObject, getVectTo), KX_PYMETHODTABLE(KX_GameObject, sendMessage), - + + // dict style access for props + {"has_key",(PyCFunction) KX_GameObject::sPyhas_key, METH_O}, + {"get",(PyCFunction) KX_GameObject::sPyget, METH_VARARGS}, + // deprecated {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS}, {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O}, @@ -1899,6 +1903,8 @@ int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro m int KX_GameObject::py_delattro(PyObject *attr) { + ShowDeprecationWarning("del ob.attr", "del ob['attr'] for user defined properties"); + char *attr_str= PyString_AsString(attr); if (RemoveProperty(attr_str)) // XXX - should call CValues instead but its only 2 lines here @@ -2737,6 +2743,48 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage, Py_RETURN_NONE; } +/* dict style access */ + + +/* Matches python dict.get(key, [default]) */ +PyObject* KX_GameObject::Pyget(PyObject *args) +{ + PyObject *key; + PyObject* def = Py_None; + PyObject* ret; + + if (!PyArg_ParseTuple(args, "O|O:get", &key, &def)) + return NULL; + + + if(PyString_Check(key)) { + CValue *item = GetProperty(PyString_AsString(key)); + if (item) + return item->GetProxy(); + } + + if (m_attr_dict && (ret=PyDict_GetItem(m_attr_dict, key))) { + Py_INCREF(ret); + return ret; + } + + Py_INCREF(def); + return def; +} + +/* Matches python dict.has_key() */ +PyObject* KX_GameObject::Pyhas_key(PyObject* value) +{ + if(PyString_Check(value) && GetProperty(PyString_AsString(value))) + Py_RETURN_TRUE; + + if (m_attr_dict && PyDict_GetItem(m_attr_dict, value)) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + + /* --------------------------------------------------------------------- * Some stuff taken from the header * --------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index c89b8f30779..dbdea97031d 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -872,6 +872,11 @@ public: KX_PYMETHOD_DOC_O(KX_GameObject,getDistanceTo); KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo); KX_PYMETHOD_DOC_VARARGS(KX_GameObject, sendMessage); + + /* Dict access */ + KX_PYMETHOD_VARARGS(KX_GameObject,get); + KX_PYMETHOD_O(KX_GameObject,has_key); + /* attributes */ static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index ca9c674a942..d951ec0c954 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -1008,6 +1008,17 @@ class CListValue(CPropValue): """ Reverse the order of the list. """ + def get(key, default=None): + """ + Return the value matching key, or the default value if its not found. + @return: The key value or a default. + """ + def has_key(key): + """ + Return True if the key is found. + @rtype: boolean + @return: The key value or a default. + """ def from_id(id): """ This is a funtion especially for the game engine to return a value with a spesific id. @@ -1614,6 +1625,7 @@ class KX_GameObject(SCA_IObject): @ivar childrenRecursive: all children of this object including childrens children, (read-only). @type childrenRecursive: L{CListValue} of L{KX_GameObject}'s @group Deprecated: getPosition, setPosition, setWorldPosition, getOrientation, setOrientation, getState, setState, getParent, getVisible, getMass, getMesh, getChildren, getChildrenRecursive + @group Property Access: get, has_key, attrDict, getPropertyNames """ def endObject(): """ @@ -2056,6 +2068,18 @@ class KX_GameObject(SCA_IObject): @param to: The name of the object to send the message to (optional) @type to: string """ + def get(key, default=None): + """ + Return the value matching key, or the default value if its not found. + @return: The key value or a default. + """ + def has_key(key): + """ + Return True if the key is found. + @rtype: boolean + @return: The key value or a default. + """ + class KX_IpoActuator(SCA_IActuator): """ From 74977721a4516bf29052ff927e4752376e795e77 Mon Sep 17 00:00:00 2001 From: Chris Want Date: Tue, 26 May 2009 17:15:29 +0000 Subject: [PATCH 340/444] BGE build probs with CMake: directory "source/gameengine/SceneGraph" was been referenced as "source/gameengine/Scenegraph" in some include paths. --- source/gameengine/Expressions/CMakeLists.txt | 2 +- source/gameengine/GameLogic/CMakeLists.txt | 2 +- source/gameengine/Ketsji/KXNetwork/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index eb87fdcee81..e3942b46557 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -31,7 +31,7 @@ SET(INC ../../../source/kernel/gen_system ../../../intern/string ../../../intern/moto/include - ../../../source/gameengine/Scenegraph + ../../../source/gameengine/SceneGraph ${PYTHON_INC} ) diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt index 449aae3ac84..7e2bc85bd1f 100644 --- a/source/gameengine/GameLogic/CMakeLists.txt +++ b/source/gameengine/GameLogic/CMakeLists.txt @@ -31,7 +31,7 @@ SET(INC ../../../source/kernel/gen_system ../../../intern/string ../../../source/gameengine/Expressions - ../../../source/gameengine/Scenegraph + ../../../source/gameengine/SceneGraph ../../../intern/moto/include ../../../source/gameengine/Rasterizer ${PYTHON_INC} diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt index 999e7148039..d9a9fc54f4b 100644 --- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt +++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt @@ -34,7 +34,7 @@ SET(INC ../../../../source/gameengine/Ketsji ../../../../source/gameengine/GameLogic ../../../../source/gameengine/Expressions - ../../../../source/gameengine/Scenegraph + ../../../../source/gameengine/SceneGraph ../../../../source/gameengine/Network ${PYTHON_INC} ) From 25569b0f7df6c29033834c281f246523b42bf16c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 26 May 2009 18:06:09 +0000 Subject: [PATCH 341/444] BGE PyAPI Bug reported by Pitel on blenderartist. importing "pygame" failed when running the BGE for the second time. Rather then clearing modules, backup and restore them (as its doing with sys.path) This way the BGE will never remember any modules imported during game play (which can cause bugs/crashes), but it also wont break pythons state by possibly removing modules that are being used internally. --- .../python/api2_2x/bpy_internal_import.c | 3 +- .../python/api2_2x/bpy_internal_import.h | 2 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 99 +++++++------------ 3 files changed, 38 insertions(+), 66 deletions(-) diff --git a/source/blender/python/api2_2x/bpy_internal_import.c b/source/blender/python/api2_2x/bpy_internal_import.c index 3bc90eb4f54..4aa703e8be4 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.c +++ b/source/blender/python/api2_2x/bpy_internal_import.c @@ -281,6 +281,7 @@ PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", blender_reload, METH_VARAR * even if we remove a python module a reimport will bring it back again. */ +#if 0 // not used anymore but may still come in handy later #if defined(WIN32) || defined(WIN64) #define SEPSTR "\\" @@ -336,4 +337,4 @@ void bpy_text_clear_modules(int clear_all) Py_DECREF(list); /* removes all references from append */ } - +#endif diff --git a/source/blender/python/api2_2x/bpy_internal_import.h b/source/blender/python/api2_2x/bpy_internal_import.h index 7220212f13e..c93d930dab0 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.h +++ b/source/blender/python/api2_2x/bpy_internal_import.h @@ -37,7 +37,7 @@ PyObject* bpy_text_import( char *name, int *found ); PyObject* bpy_text_reimport( PyObject *module, int *found ); -void bpy_text_clear_modules( int clear_all ); /* Clear user modules */ +/* void bpy_text_clear_modules( int clear_all );*/ /* Clear user modules */ extern PyMethodDef bpy_import_meth[]; extern PyMethodDef bpy_reload_meth[]; diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 7c131d01cd1..ff5a37801f4 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -112,7 +112,6 @@ extern "C" { #include "GPU_material.h" static void setSandbox(TPythonSecurityLevel level); -static void clearGameModules(); // 'local' copy of canvas ptr, for window height/width python scripts static RAS_ICanvas* gp_Canvas = NULL; @@ -122,6 +121,7 @@ static RAS_IRasterizer* gp_Rasterizer = NULL; static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = ""; static char gp_GamePythonPathOrig[FILE_MAXDIR + FILE_MAXFILE] = ""; // not super happy about this, but we need to remember the first loaded file for the global/dict load save static PyObject *gp_OrigPythonSysPath= NULL; +static PyObject *gp_OrigPythonSysModules= NULL; void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) { @@ -1465,9 +1465,9 @@ void setSandbox(TPythonSecurityLevel level) /* Explanation of * - * - backupPySysPath() : stores sys.path in gp_OrigPythonSysPath - * - initPySysPath(main) : initializes the blendfile and library paths - * - restorePySysPath() : restores sys.path from gp_OrigPythonSysPath + * - backupPySysObjects() : stores sys.path in gp_OrigPythonSysPath + * - initPySysObjects(main) : initializes the blendfile and library paths + * - restorePySysObjects() : restores sys.path from gp_OrigPythonSysPath * * These exist so the current blend dir "//" can always be used to import modules from. * the reason we need a few functions for this is that python is not only used by the game engine @@ -1482,23 +1482,27 @@ void setSandbox(TPythonSecurityLevel level) /** * So we can have external modules mixed with our blend files. */ -static void backupPySysPath(void) +static void backupPySysObjects(void) { PyObject *sys_path= PySys_GetObject("path"); /* should never fail */ + PyObject *sys_mods= PySys_GetObject("modules"); /* should never fail */ - /* just incase its set */ - Py_XDECREF(gp_OrigPythonSysPath); - gp_OrigPythonSysPath= NULL; - + /* paths */ + Py_XDECREF(gp_OrigPythonSysPath); /* just incase its set */ gp_OrigPythonSysPath = PyList_GetSlice(sys_path, 0, INT_MAX); /* copy the list */ + + /* modules */ + Py_XDECREF(gp_OrigPythonSysModules); /* just incase its set */ + gp_OrigPythonSysModules = PyDict_Copy(sys_mods); /* copy the list */ + } -/* for initPySysPath only, +/* for initPySysObjects only, * takes a blend path and adds a scripts dir from it * * "/home/me/foo.blend" -> "/home/me/scripts" */ -static void initPySysPath__append(PyObject *sys_path, char *filename) +static void initPySysObjects__append(PyObject *sys_path, char *filename) { PyObject *item; char expanded[FILE_MAXDIR + FILE_MAXFILE]; @@ -1515,13 +1519,13 @@ static void initPySysPath__append(PyObject *sys_path, char *filename) Py_DECREF(item); } -static void initPySysPath(Main *maggie) +static void initPySysObjects(Main *maggie) { PyObject *sys_path= PySys_GetObject("path"); /* should never fail */ if (gp_OrigPythonSysPath==NULL) { /* backup */ - backupPySysPath(); + backupPySysObjects(); } else { /* get the original sys path when the BGE started */ @@ -1531,27 +1535,36 @@ static void initPySysPath(Main *maggie) Library *lib= (Library *)maggie->library.first; while(lib) { - initPySysPath__append(sys_path, lib->name); + initPySysObjects__append(sys_path, lib->name); lib= (Library *)lib->id.next; } - initPySysPath__append(sys_path, gp_GamePythonPath); + initPySysObjects__append(sys_path, gp_GamePythonPath); // fprintf(stderr, "\nNew Path: %d ", PyList_Size(sys_path)); // PyObject_Print(sys_path, stderr, 0); } -static void restorePySysPath(void) +static void restorePySysObjects(void) { if (gp_OrigPythonSysPath==NULL) return; PyObject *sys_path= PySys_GetObject("path"); /* should never fail */ - + PyObject *sys_mods= PySys_GetObject("modules"); /* should never fail */ + + /* paths */ PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath); Py_DECREF(gp_OrigPythonSysPath); gp_OrigPythonSysPath= NULL; + /* modules */ + PyDict_Clear(sys_mods); + PyDict_Update(sys_mods, gp_OrigPythonSysModules); + Py_DECREF(gp_OrigPythonSysModules); + gp_OrigPythonSysModules= NULL; + + // fprintf(stderr, "\nRestore Path: %d ", PyList_Size(sys_path)); // PyObject_Print(sys_path, stderr, 0); } @@ -1588,7 +1601,7 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur bpy_import_main_set(maggie); - initPySysPath(maggie); + initPySysObjects(maggie); first_time = false; @@ -1599,11 +1612,9 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur } void exitGamePlayerPythonScripting() -{ - //clearGameModules(); // were closing python anyway - +{ /* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */ - restorePySysPath(); /* get back the original sys.path and clear the backup */ + restorePySysObjects(); /* get back the original sys.path and clear the backup */ Py_Finalize(); bpy_import_main_set(NULL); @@ -1629,10 +1640,7 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev bpy_import_main_set(maggie); - initPySysPath(maggie); - - /* clear user defined modules that may contain data from the last run */ - clearGameModules(); + initPySysObjects(maggie); PyObjectPlus::NullDeprecationWarning(); @@ -1640,46 +1648,9 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev return PyModule_GetDict(moduleobj); } -static void clearModule(PyObject *modules, const char *name) -{ - PyObject *mod= PyDict_GetItemString(modules, name); - - if (mod==NULL) - return; - - PyDict_Clear(PyModule_GetDict(mod)); /* incase there are any circular refs */ - PyDict_DelItemString(modules, name); -} - -static void clearGameModules() -{ - /* references to invalid BGE data is better supported in 2.49+ so dont clear dicts */ -#if 0 - /* Note, user modules could still reference these modules - * but since the dict's are cleared their members wont be accessible */ - - PyObject *modules= PySys_GetObject((char *)"modules"); - clearModule(modules, "Expression"); - clearModule(modules, "CValue"); - clearModule(modules, "PhysicsConstraints"); - clearModule(modules, "GameLogic"); - clearModule(modules, "Rasterizer"); - clearModule(modules, "GameKeys"); - clearModule(modules, "VideoTexture"); - clearModule(modules, "Mathutils"); - clearModule(modules, "Geometry"); - clearModule(modules, "BGL"); - PyErr_Clear(); // incase some of these were alredy removed. -#endif - - /* clear user defined modules, arg '1' for clear external py modules too */ - bpy_text_clear_modules(1); -} - void exitGamePythonScripting() { - clearGameModules(); - restorePySysPath(); /* get back the original sys.path and clear the backup */ + restorePySysObjects(); /* get back the original sys.path and clear the backup */ bpy_import_main_set(NULL); PyObjectPlus::ClearDeprecationWarning(); } From 328d3128a5806be3bb4f11f852fde108ebba955a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 26 May 2009 18:37:46 +0000 Subject: [PATCH 342/444] BGE VideoTexture: VideoFFmpeg was missing a rewind function: rename stop() to pause() and add stop() that will also reset the frame counter. --- source/gameengine/VideoTexture/VideoBase.cpp | 5 +- source/gameengine/VideoTexture/VideoBase.h | 13 +++- .../gameengine/VideoTexture/VideoFFmpeg.cpp | 66 ++++++++++++++----- source/gameengine/VideoTexture/VideoFFmpeg.h | 5 +- 4 files changed, 70 insertions(+), 19 deletions(-) diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp index 3c703d75cda..ada672c5569 100644 --- a/source/gameengine/VideoTexture/VideoBase.cpp +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -113,7 +113,10 @@ void Video_open (VideoBase * self, char * file, short captureID) PyObject * Video_play (PyImage * self) { if (getVideo(self)->play()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } -// stop video +// pause video +PyObject * Video_pause (PyImage * self) +{ if (getVideo(self)->pause()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } + PyObject * Video_stop (PyImage * self) { if (getVideo(self)->stop()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h index 15ecb7a78f4..0c8668ee0bc 100644 --- a/source/gameengine/VideoTexture/VideoBase.h +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -80,7 +80,17 @@ public: } return false; } - /// stop/pause video + /// pause video + virtual bool pause (void) + { + if (m_status == SourcePlaying) + { + m_status = SourceStopped; + return true; + } + return false; + } + /// stop video virtual bool stop (void) { if (m_status == SourcePlaying) @@ -170,6 +180,7 @@ template void Video_init (PyImage * self) // video functions void Video_open (VideoBase * self, char * file, short captureID); PyObject * Video_play (PyImage * self); +PyObject * Video_pause (PyImage * self); PyObject * Video_stop (PyImage * self); PyObject * Video_refresh (PyImage * self); PyObject * Video_getStatus (PyImage * self, void * closure); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index d509f366910..7910113a225 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -669,15 +669,29 @@ bool VideoFFmpeg::play (void) } +// pause video +bool VideoFFmpeg::pause (void) +{ + try + { + if (VideoBase::pause()) + { + return true; + } + } + CATCH_EXCP; + return false; +} + // stop video bool VideoFFmpeg::stop (void) { try { - if (VideoBase::stop()) - { - return true; - } + VideoBase::stop(); + // force restart when play + m_lastFrame = -1; + return true; } CATCH_EXCP; return false; @@ -721,6 +735,8 @@ void VideoFFmpeg::loadFrame (void) { // get actual time double startTime = PIL_check_seconds_timer(); + if (m_lastFrame == -1) + m_startTime = startTime; double actTime = startTime - m_startTime; // if video has ended if (m_isFile && actTime * m_frameRate >= m_range[1]) @@ -886,28 +902,47 @@ AVFrame *VideoFFmpeg::grabFrame(long position) if (position != m_curPosition + 1) { double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base); - long long pos = (long long) - ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate); - long long startTs = m_formatCtx->streams[m_videoStream]->start_time; + int64_t pos = (int64_t)((position - m_preseek) / (m_baseFrameRate*timeBase)); + int64_t startTs = m_formatCtx->streams[m_videoStream]->start_time; + int seekres; if (pos < 0) pos = 0; if (startTs != AV_NOPTS_VALUE) - pos += (long long)(startTs * AV_TIME_BASE * timeBase); + pos += startTs; if (position <= m_curPosition || !m_eof) { - // no need to seek past the end of the file - if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0) +#if 0 + // Tried to make this work but couldn't: seeking on byte is ignored by the + // format plugin and it will generally continue to read from last timestamp. + // Too bad because frame seek is not always able to get the first frame + // of the file. + if (position <= m_preseek) + { + // we can safely go the begining of the file + if (av_seek_frame(m_formatCtx, m_videoStream, 0, AVSEEK_FLAG_BYTE) >= 0) + { + // binary seek does not reset the timestamp, must do it now + av_update_cur_dts(m_formatCtx, m_formatCtx->streams[m_videoStream], startTs); + m_curPosition = 0; + } + } + else +#endif { // current position is now lost, guess a value. - // It's not important because it will be set at this end of this function - m_curPosition = position - m_preseek - 1; + if (av_seek_frame(m_formatCtx, m_videoStream, pos, AVSEEK_FLAG_BACKWARD) >= 0) + { + // current position is now lost, guess a value. + // It's not important because it will be set at this end of this function + m_curPosition = position - m_preseek - 1; + } } } // this is the timestamp of the frame we're looking for - targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase); + targetTs = (int64_t)(position / (m_baseFrameRate * timeBase)); if (startTs != AV_NOPTS_VALUE) targetTs += startTs; @@ -1097,8 +1132,9 @@ int VideoFFmpeg_setDeinterlace (PyImage * self, PyObject * value, void * closure // methods structure static PyMethodDef videoMethods[] = { // methods from VideoBase class - {"play", (PyCFunction)Video_play, METH_NOARGS, "Play video"}, - {"stop", (PyCFunction)Video_stop, METH_NOARGS, "Stop (pause) video"}, + {"play", (PyCFunction)Video_play, METH_NOARGS, "Play (restart) video"}, + {"pause", (PyCFunction)Video_pause, METH_NOARGS, "pause video"}, + {"stop", (PyCFunction)Video_stop, METH_NOARGS, "stop video (play will replay it from start)"}, {"refresh", (PyCFunction)Video_refresh, METH_NOARGS, "Refresh video - get its status"}, {NULL} }; diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index 51f1067c466..fbd04e7e1fc 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -83,9 +83,10 @@ public: /// play video virtual bool play (void); - /// stop/pause video + /// pause video + virtual bool pause (void); + /// stop video virtual bool stop (void); - /// set play range virtual void setRange (double start, double stop); /// set frame rate From 191e22dd62ee53fa8f6410d384116278c36e00b5 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 26 May 2009 21:32:19 +0000 Subject: [PATCH 343/444] BGE: fix a bug with kinematic object not giving the correct friction to dynamic object when they have a translation and rotation movement at the same time (translation is ignored). Performance: avoid unnecessary synchronization for static object. --- .../Physics/Bullet/CcdPhysicsController.cpp | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 9a5f9644a47..6b904364fbe 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -789,9 +789,12 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc if (m_object) { m_object->activate(true); - if (m_object->isStaticObject() && !m_cci.m_bSensor) + if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + // kinematic object should not set the transform, it disturbs the velocity interpolation + return; } // btRigidBody* body = GetRigidBody(); // not used anymore @@ -815,9 +818,12 @@ void CcdPhysicsController::RelativeRotate(const float rotval[9],bool local) if (m_object) { m_object->activate(true); - if (m_object->isStaticObject() && !m_cci.m_bSensor) + if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + // kinematic object should not set the transform, it disturbs the velocity interpolation + return; } btMatrix3x3 drotmat( rotval[0],rotval[4],rotval[8], @@ -840,10 +846,9 @@ void CcdPhysicsController::RelativeRotate(const float rotval[9],bool local) void CcdPhysicsController::GetWorldOrientation(btMatrix3x3& mat) { - float orn[4]; - m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - btQuaternion quat(orn[0],orn[1],orn[2],orn[3]); - mat.setRotation(quat); + float ori[12]; + m_MotionState->getWorldOrientation(ori); + mat.setFromOpenGLSubMatrix(ori); } void CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) @@ -859,9 +864,12 @@ void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float if (m_object) { m_object->activate(true); - if (m_object->isStaticObject() && !m_cci.m_bSensor) + if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + // kinematic object should not set the transform, it disturbs the velocity interpolation + return; } // not required //m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal); @@ -911,9 +919,12 @@ void CcdPhysicsController::setPosition(float posX,float posY,float posZ) if (m_object) { m_object->activate(true); - if (m_object->isStaticObject() && !m_cci.m_bSensor) + if (m_object->isStaticObject()) { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + if (!m_cci.m_bSensor) + m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + // kinematic object should not set the transform, it disturbs the velocity interpolation + return; } // not required, this function is only used to update the physic controller //m_MotionState->setWorldPosition(posX,posY,posZ); From da270c6691bb902eb65ed303ff5857633b063221 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Wed, 27 May 2009 01:29:41 +0000 Subject: [PATCH 344/444] "Motor at limit" jitter fixed for btGeneric6Dof constraint, fix taken from Bullet SVN repo. Now we need some cool constraint limit/motor/spring demos, such as a Forklift demo, moving robots, ragdolls etc. for Blender 2.49! --- .../btGeneric6DofConstraint.cpp | 19 ++++++++++++++----- .../btGeneric6DofConstraint.h | 13 +++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index 2edf28c6bac..cd34724932e 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -420,6 +420,7 @@ void btGeneric6DofConstraint::buildAngularJacobian( bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) { btScalar angle = m_calculatedAxisAngleDiff[axis_index]; + m_angularLimits[axis_index].m_currentPosition = angle; //test limits m_angularLimits[axis_index].testLimitValue(angle); return m_angularLimits[axis_index].needApplyTorques(); @@ -544,6 +545,7 @@ int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) { // re-use rotational motor code limot.m_bounce = btScalar(0.f); limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; + limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; limot.m_damping = m_linearLimits.m_damping; limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; @@ -696,6 +698,7 @@ void btGeneric6DofConstraint::calculateLinearInfo() m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff; for(int i = 0; i < 3; i++) { + m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i]; m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); } } @@ -740,16 +743,21 @@ int btGeneric6DofConstraint::get_limit_motor_info2( } // if we're limited low and high simultaneously, the joint motor is // ineffective - if (limit && (limot->m_loLimit == limot->m_hiLimit)) - powered = 0; - + if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = 0; info->m_constraintError[srow] = btScalar(0.f); if (powered) { info->cfm[srow] = 0.0f; - if(!limit) +// if(!limit) { - info->m_constraintError[srow] += limot->m_targetVelocity; + btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; + + btScalar mot_fact = getMotorFactor( limot->m_currentPosition, + limot->m_loLimit, + limot->m_hiLimit, + tag_vel, + info->fps * info->erp); + info->m_constraintError[srow] += mot_fact * limot->m_targetVelocity; info->m_lowerLimit[srow] = -limot->m_maxMotorForce; info->m_upperLimit[srow] = limot->m_maxMotorForce; } @@ -831,6 +839,7 @@ int btGeneric6DofConstraint::get_limit_motor_info2( + btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) : btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA) { diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h index 33e4749ffd0..d01c9cf63ab 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -54,6 +54,7 @@ public: //! temp_variables //!@{ btScalar m_currentLimitError;//! How much is violated this limit + btScalar m_currentPosition; //! current value of angle int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit btScalar m_accumulatedImpulse; //!@} @@ -134,6 +135,7 @@ public: btVector3 m_targetVelocity;//!< target motor velocity btVector3 m_maxMotorForce;//!< max force on motor btVector3 m_currentLimitError;//! How much is violated this limit + btVector3 m_currentLinearDiff;//! Current relative offset of constraint frames int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit btTranslationalLimitMotor() @@ -478,6 +480,16 @@ public: }; +/// Generic 6 DOF constraint that allows to set spring motors to any translational and rotational DOF + +/// DOF index used in enableSpring() and setStiffness() means: +/// 0 : translation X +/// 1 : translation Y +/// 2 : translation Z +/// 3 : rotation X (3rd Euler rotational around new position of X axis, range [-PI+epsilon, PI-epsilon] ) +/// 4 : rotation Y (2nd Euler rotational around new position of Y axis, range [-PI/2+epsilon, PI/2-epsilon] ) +/// 5 : rotation Z (1st Euler rotational around Z axis, range [-PI+epsilon, PI-epsilon] ) + class btGeneric6DofSpringConstraint : public btGeneric6DofConstraint { protected: @@ -494,4 +506,5 @@ public: virtual void getInfo2 (btConstraintInfo2* info); }; + #endif //GENERIC_6DOF_CONSTRAINT_H From 0cab562e466352b9aaa409797e2efba7336554f5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 27 May 2009 02:03:22 +0000 Subject: [PATCH 345/444] Workaround for size 1 brushes not working with projection paint, need to investigate why this wont work but for now just clamp the value while projection painting. --- source/blender/src/imagepaint.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 1a6eb10b00b..e6b14497838 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -4438,6 +4438,7 @@ void imagepaint_paint(short mousebutton, short texpaint) BrushPainter *painter; ToolSettings *settings= G.scene->toolsettings; short prevmval[2], mval[2], project = 0; + short brush_size_orig; /* not nice hack because 1 size brushes always fail with projection paint */ double time; float pressure; int init = 1; @@ -4472,6 +4473,8 @@ void imagepaint_paint(short mousebutton, short texpaint) ps.brush = s.brush; ps.tool = s.tool; ps.blend = s.blend; + + brush_size_orig = ps.brush->size; /* hack, fixme */ } if(texpaint) { @@ -4535,6 +4538,10 @@ void imagepaint_paint(short mousebutton, short texpaint) persp(PERSP_WIN); return; } + + /* Dont allow brush size below 2 */ + if (ps.brush->size<=1) + ps.brush->size = 2; } settings->imapaint.flag |= IMAGEPAINT_DRAWING; @@ -4613,6 +4620,7 @@ void imagepaint_paint(short mousebutton, short texpaint) brush_painter_free(painter); if (project) { + ps.brush->size = brush_size_orig; project_paint_end(&ps); } From fb7d688c1bd327f17b86ac74dab511bab40496df Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 27 May 2009 03:43:22 +0000 Subject: [PATCH 346/444] flag the images as dirty when projection painting (so there is the option to repack a packed image) --- source/blender/src/imagepaint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index e6b14497838..afe9678a216 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -3300,6 +3300,7 @@ static void project_paint_end(ProjPaintState *ps) int size = sizeof(UndoTile **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y); last_projIma->undoRect = (UndoTile **) BLI_memarena_alloc(arena, size); memset(last_projIma->undoRect, 0, size); + last_projIma->ibuf->userflags |= IB_BITMAPDIRTY; } for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { From 00ff608991dfc713662295e9b35fec6644f2f371 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Wed, 27 May 2009 11:57:39 +0000 Subject: [PATCH 347/444] DXF-importer update: v1.12 - 2009.05.26 by migius - bugfix WORLDY(1,1,0) to (0,1,0) --- release/scripts/import_dxf.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py index ceb4dd56722..27a330d19fc 100644 --- a/release/scripts/import_dxf.py +++ b/release/scripts/import_dxf.py @@ -7,7 +7,7 @@ Group: 'Import' Tooltip: 'Import for DWG/DXF geometry data.' """ __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)' -__version__ = '1.12 - 2009.04.11 by migius' +__version__ = '1.12 - 2009.05.26 by migius' __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319", "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"] __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"] @@ -111,7 +111,8 @@ History: -- support DXF-definitions of scene, lights and cameras -- support ortho mode for VIEWs and VPORTs as cameras - + v1.12 - 2009.05.26 by migius + d5 bugfix WORLDY(1,1,0) to (0,1,0) v1.12 - 2009.04.11 by migius d4 added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter v1.12 - 2009.03.14 by migius @@ -350,7 +351,7 @@ print 'DXF/DWG-Importer v%s *** start ***' %(__version__) #------------------- SCENE = None WORLDX = Mathutils.Vector((1,0,0)) -WORLDY = Mathutils.Vector((1,1,0)) +WORLDY = Mathutils.Vector((0,1,0)) WORLDZ = Mathutils.Vector((0,0,1)) G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data From 059b4bf8fc79994a9e7191bc4ecf6b664b48aff3 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Wed, 27 May 2009 13:32:09 +0000 Subject: [PATCH 348/444] DXF-importer second update: v1.12 - 2009.05.26 by migius - changed to the new 2.49 method Vector.cross() --- release/scripts/import_dxf.py | 39 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py index 27a330d19fc..d1ea36ed2b7 100644 --- a/release/scripts/import_dxf.py +++ b/release/scripts/import_dxf.py @@ -2,7 +2,7 @@ """ Name: 'Autodesk DXF (.dxf .dwg)' -Blender: 246 +Blender: 249 Group: 'Import' Tooltip: 'Import for DWG/DXF geometry data.' """ @@ -112,6 +112,7 @@ History: -- support ortho mode for VIEWs and VPORTs as cameras v1.12 - 2009.05.26 by migius + d5 changed to the new 2.49 method Vector.cross() d5 bugfix WORLDY(1,1,0) to (0,1,0) v1.12 - 2009.04.11 by migius d4 added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter @@ -344,8 +345,6 @@ if os.name != 'mac': except ImportError: print 'psyco not imported' -#try: Curve.orderU - print '\n\n\n' print 'DXF/DWG-Importer v%s *** start ***' %(__version__) #--------------------- @@ -4420,11 +4419,14 @@ def getOCS(az): #-------------------------------------------------------------- cap = 0.015625 # square polar cap value (1/64.0) if abs(az.x) < cap and abs(az.y) < cap: - ax = Mathutils.CrossVecs(WORLDY, az) + #ax = Mathutils.CrossVecs(WORLDY, az) #for<2.49 + ax = WORLDY.cross(az) else: - ax = Mathutils.CrossVecs(WORLDZ, az) + #ax = Mathutils.CrossVecs(WORLDZ, az) #for<2.49 + ax = WORLDZ.cross(az) ax = ax.normalize() - ay = Mathutils.CrossVecs(az, ax) + #ay = Mathutils.CrossVecs(az, ax) #for<2.49 + ay = az.cross(ax) ay = ay.normalize() return ax, ay, az @@ -6156,19 +6158,22 @@ def multi_import(DIR): if __name__ == "__main__": - UI_MODE = True - # recall last used DXF-file and INI-file names - dxffilename = check_RegistryKey('dxfFileName') - #print 'deb:start dxffilename:', dxffilename #---------------- - if dxffilename: dxfFileName.val = dxffilename + if 'cross' not in dir(Mathutils.Vector()): + Draw.PupMenu('DXF importer: Abort%t|This script version works for Blender up 2.49 only!') else: - dirname = sys.dirname(Blender.Get('filename')) - #print 'deb:start dirname:', dirname #---------------- - dxfFileName.val = sys.join(dirname, '') - inifilename = check_RegistryKey('iniFileName') - if inifilename: iniFileName.val = inifilename + UI_MODE = True + # recall last used DXF-file and INI-file names + dxffilename = check_RegistryKey('dxfFileName') + #print 'deb:start dxffilename:', dxffilename #---------------- + if dxffilename: dxfFileName.val = dxffilename + else: + dirname = sys.dirname(Blender.Get('filename')) + #print 'deb:start dirname:', dirname #---------------- + dxfFileName.val = sys.join(dirname, '') + inifilename = check_RegistryKey('iniFileName') + if inifilename: iniFileName.val = inifilename - Draw.Register(draw_UI, event, bevent) + Draw.Register(draw_UI, event, bevent) """ From 65d980155d78f75a8f7cea28748fe846cc41fb12 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Wed, 27 May 2009 22:27:10 +0000 Subject: [PATCH 349/444] last-minute Bullet bugfix: accidently commented out a constraint limit test, causing instability for springs. --- .../BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index cd34724932e..f60eabe2d2b 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -748,7 +748,7 @@ int btGeneric6DofConstraint::get_limit_motor_info2( if (powered) { info->cfm[srow] = 0.0f; -// if(!limit) + if(!limit) { btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; From 01f8956a6d6848e738dbd665b1c1b4dee6dbb445 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Wed, 27 May 2009 22:37:45 +0000 Subject: [PATCH 350/444] == FFMPEG == This fixes: [#17505] Bad Interlacing for NTSC in mpeg-2 files --- source/blender/blenkernel/intern/writeffmpeg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index c3d8ed855a2..6576d25dd76 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -248,6 +248,9 @@ static void write_video_frame(AVFrame* frame) #ifdef FFMPEG_CODEC_TIME_BASE frame->pts = G.scene->r.cfra - G.scene->r.sfra; #endif + if (G.scene->r.mode & R_FIELDS) { + frame->top_field_first = ((G.scene->r.mode & R_ODDFIELD) != 0); + } outsize = avcodec_encode_video(c, video_buffer, video_buffersize, frame); From ea826759c459f675d53c2ee95870397d235d45b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 May 2009 06:13:56 +0000 Subject: [PATCH 351/444] Projection paint, cloning from 1 layer to another would show ugly black lines at the seams because interpolation didnt wrap across the image. Added bilinear_interpolation_color_wrap to be used instead of bilinear_interpolation_color for painting. --- source/blender/imbuf/IMB_imbuf.h | 1 + source/blender/imbuf/intern/imageprocess.c | 67 ++++++++++++++++++++++ source/blender/src/imagepaint.c | 12 ++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 8bc1439fd09..1d8035a2358 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -410,6 +410,7 @@ void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); +void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); /** * Change the ordering of the color bytes pointed to by rect from diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 6be257ff737..e4977c77155 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -303,6 +303,73 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float * } } +/* function assumes out to be zero'ed, only does RGBA */ +/* BILINEAR INTERPOLATION */ + +/* Note about wrapping, the u/v still needs to be within the image bounds, + * just the interpolation is wrapped. + * This the same as bilinear_interpolation_color except it wraps rather then using empty and emptyI */ +void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) +{ + float *row1, *row2, *row3, *row4, a, b; + unsigned char *row1I, *row2I, *row3I, *row4I; + float a_b, ma_b, a_mb, ma_mb; + int y1, y2, x1, x2; + + + /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */ + + x1= (int)floor(u); + x2= (int)ceil(u); + y1= (int)floor(v); + y2= (int)ceil(v); + + // sample area entirely outside image? + if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return; + + /* wrap interpolation pixels - main difference from bilinear_interpolation_color */ + if(x1<0)x1= in->x+x1; + if(y1<0)y1= in->y+y1; + + if(x2>=in->x)x2= x2-in->x; + if(y2>=in->y)y2= y2-in->y; + + if (outF) { + // sample including outside of edges of image + row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1; + row2= (float *)in->rect_float + in->x * y2 * 4 + 4*x1; + row3= (float *)in->rect_float + in->x * y1 * 4 + 4*x2; + row4= (float *)in->rect_float + in->x * y2 * 4 + 4*x2; + + a= u-floor(u); + b= v-floor(v); + a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); + + outF[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0]; + outF[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1]; + outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2]; + outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3]; + } + if (outI) { + // sample including outside of edges of image + row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1; + row2I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x1; + row3I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x2; + row4I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x2; + + a= u-floor(u); + b= v-floor(v); + a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b); + + /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) + * tested with white images and this should not wrap back to zero */ + outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f; + outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f; + outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f; + outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f; + } +} + void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) { diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index afe9678a216..3ec4205d9cf 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -716,21 +716,21 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float if (ibuf->rect_float) { if (rgba_fp) { - bilinear_interpolation_color(ibuf, NULL, rgba_fp, x, y); + bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y); } else { float rgba_tmp_f[4]; - bilinear_interpolation_color(ibuf, NULL, rgba_tmp_f, x, y); + bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y); IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f); } } else { if (rgba) { - bilinear_interpolation_color(ibuf, rgba, NULL, x, y); + bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y); } else { unsigned char rgba_tmp[4]; - bilinear_interpolation_color(ibuf, rgba_tmp, NULL, x, y); + bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y); IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp); } } @@ -1342,10 +1342,10 @@ static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const if (ibuf_other->rect_float) { /* from float to float */ - bilinear_interpolation_color(ibuf_other, NULL, rgba_f, x, y); + bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y); } else { /* from char to float */ - bilinear_interpolation_color(ibuf_other, rgba_ub, NULL, x, y); + bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y); } } From ca5d429bf9f324d8e9291c66dab400d2677834d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 May 2009 06:34:56 +0000 Subject: [PATCH 352/444] grsaaynoel spent ~2hrs to figure this out, theeth, feel free to elaborate if the tip isnt quite correct. --- source/blender/src/drawview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 9b2f7fe53d9..50deea9e831 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2321,7 +2321,7 @@ static void view3d_panel_bonesketch_spaces(short cntrl) uiBlockBeginAlign(block); /* use real flag instead of 1 */ - uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones"); + uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones, (Ctrl snaps to mesh volume)"); uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them"); uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end"); yco -= 20; From b9d8a2716ae1fb85f2497352566b51b6073e038d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 May 2009 07:11:12 +0000 Subject: [PATCH 353/444] renamed python 'bookmark' attribute to 'useHighPriority', was renamed in the UI but not in python. --- source/gameengine/GameLogic/SCA_IController.cpp | 2 +- source/gameengine/PyDoc/GameTypes.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index 84a6bfb8085..f2c3c83a2d9 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -244,7 +244,7 @@ PyAttributeDef SCA_IController::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state), KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors), KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators), - KX_PYATTRIBUTE_BOOL_RW("bookmark",SCA_IController,m_bookmark), + KX_PYATTRIBUTE_BOOL_RW("useHighPriority",SCA_IController,m_bookmark), { NULL } //Sentinel }; diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index d951ec0c954..4f176c17af2 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -258,10 +258,9 @@ class SCA_IController(SCA_ILogicBrick): - note: the sensors are not necessarily owned by the same object. - note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup. @type actuators: sequence supporting index/string lookups and iteration. - @ivar bookmark: the bookmark option. - If set, the controller executes always before all other non-bookmarked controllers. - note: Order of execution between bookmarked controllers is not guaranteed. - @type bookmark: bool + @ivar useHighPriority: When set the controller executes always before all other controllers that dont have this set. + note: Order of execution between high priority controllers is not guaranteed. + @type useHighPriority: bool """ #{ Deprecated def getState(): @@ -2385,7 +2384,7 @@ class KX_MeshProxy(SCA_IObject): and have all collision primitives in one vertex array (ie. < 65535 verts) and be either a polytope or polyheder mesh. If you don't get a warning in the console when the collision type is polytope, the mesh is suitable for reinstance. - + @bug: This currently does not work. @rtype: boolean @return: True if reinstance succeeded, False if it failed. """ From 6ac072e1bd05d41ae0c713b9ab0c5b83477c2919 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 28 May 2009 11:04:45 +0000 Subject: [PATCH 354/444] BGE: no sleeping and lock axis physics options were not propagated to replicas. --- .../Physics/Bullet/CcdPhysicsController.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6b904364fbe..3a3c817698b 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -700,17 +700,25 @@ void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta } } + // load some characterists that are not + btRigidBody* oldbody = GetRigidBody(); m_object = 0; CreateRigidbody(); - btRigidBody* body = GetRigidBody(); - if (body) { if (m_cci.m_mass) { body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); } + + if (oldbody) + { + body->setLinearFactor(oldbody->getLinearFactor()); + body->setAngularFactor(oldbody->getAngularFactor()); + if (oldbody->getActivationState() == DISABLE_DEACTIVATION) + body->setActivationState(DISABLE_DEACTIVATION); + } } // sensor object are added when needed if (!m_cci.m_bSensor) From 8c4620f3d3d5cb533f3d1bf5c526c6ffc0355aaa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 May 2009 13:44:32 +0000 Subject: [PATCH 355/444] [#18840] Joystick sensor lag if(SDL_PollEvent(&sdl_event)) // if -> while fixed it removed 'm_buttonnum' was misleading, wasn't used as you expect. Added gravity to variable to world to be used by collada. --- source/blender/python/api2_2x/World.c | 23 ++++++++++++ source/blender/python/api2_2x/doc/World.py | 2 + .../GameLogic/Joystick/SCA_Joystick.cpp | 20 ++++++---- .../GameLogic/Joystick/SCA_Joystick.h | 11 +----- .../GameLogic/Joystick/SCA_JoystickDefines.h | 1 + .../GameLogic/Joystick/SCA_JoystickEvents.cpp | 37 ++++++++----------- 6 files changed, 55 insertions(+), 39 deletions(-) diff --git a/source/blender/python/api2_2x/World.c b/source/blender/python/api2_2x/World.c index 354d8cda0b7..a209ec5a53d 100644 --- a/source/blender/python/api2_2x/World.c +++ b/source/blender/python/api2_2x/World.c @@ -106,6 +106,8 @@ static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args ); static PyObject *World_setCurrent( BPy_World * self ); static PyObject *World_getTextures( BPy_World * self ); static int World_setTextures( BPy_World * self, PyObject * value ); +static PyObject *World_getGravity( BPy_World * self ); +static int World_setGravity( BPy_World * self, PyObject * value ); static PyObject *World_copy( BPy_World * self ); @@ -259,6 +261,9 @@ static PyGetSetDef BPy_World_getseters[] = { "world ipo", NULL}, {"textures", (getter)World_getTextures, (setter)World_setTextures, "The World's texture list as a tuple", + NULL}, + {"gravity", (getter)World_getGravity, (setter)World_setGravity, + "Physics gravity setting", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -1136,3 +1141,21 @@ static int World_setTextures( BPy_World * self, PyObject * value ) Py_DECREF(value); return 0; } + +static PyObject *World_getGravity( BPy_World * self ) +{ + return PyFloat_FromDouble(self->world->gravity); +} + +static int World_setGravity( BPy_World * self, PyObject * value ) +{ + float f = PyFloat_AsDouble(value); + if (f==-1 && PyErr_Occurred()) + return EXPP_ReturnIntError( PyExc_TypeError, "expected a float or int" ); + + if (f<0.0f)f= 0.0f; + else if (f>25.0f)f= 25.0f; + + self->world->gravity= f; + return 0; +} diff --git a/source/blender/python/api2_2x/doc/World.py b/source/blender/python/api2_2x/doc/World.py index d8052c609cd..e81521b65d0 100644 --- a/source/blender/python/api2_2x/doc/World.py +++ b/source/blender/python/api2_2x/doc/World.py @@ -84,6 +84,8 @@ class World: @ivar ipo: The world type ipo linked to this world object. @type textures: a tuple of Blender MTex objects. @ivar textures: The World's texture list. Empty texture channels contains None. + @type gravity: float + @ivar gravity: World physics gravity setting between 0.0 and 25.0 """ def getRange(): diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index 7c4ebb4c330..d83179d4f80 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -38,7 +38,6 @@ SCA_Joystick::SCA_Joystick(short int index) : m_joyindex(index), m_prec(3200), - m_buttonnum(-2), m_axismax(-1), m_buttonmax(-1), m_hatmax(-1), @@ -68,6 +67,7 @@ SCA_Joystick::~SCA_Joystick() } SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX]; +int SCA_Joystick::m_joynum = 0; int SCA_Joystick::m_refCount = 0; SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex ) @@ -88,6 +88,9 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex ) echo("Error-Initializing-SDL: " << SDL_GetError()); return NULL; } + + m_joynum = SDL_NumJoysticks(); + for (i=0; iCreateJoystickDevice(); @@ -155,12 +158,13 @@ bool SCA_Joystick::aAxisIsPositive(int axis_single) bool SCA_Joystick::aAnyButtonPressIsPositive(void) { - return (m_buttonnum==-2) ? false : true; -} - -bool SCA_Joystick::aAnyButtonReleaseIsPositive(void) -{ - return (m_buttonnum==-2) ? true : false; + /* this is needed for the "all events" option + * so we know if there are no buttons pressed */ + for (int i=0; im_joystick, i)) + return true; + + return false; } bool SCA_Joystick::aButtonPressIsPositive(int button) @@ -217,7 +221,7 @@ bool SCA_Joystick::CreateJoystickDevice(void) return false; #else if(m_isinit == false){ - if (m_joyindex>=SDL_NumJoysticks()) { + if (m_joyindex>=m_joynum) { // don't print a message, because this is done anyway //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)"); diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h index 5822f8e8ff8..6324b898247 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h @@ -44,6 +44,7 @@ class SCA_Joystick { static SCA_Joystick *m_instance[JOYINDEX_MAX]; + static int m_joynum; static int m_refCount; class PrivateData; @@ -67,11 +68,6 @@ class SCA_Joystick */ int m_prec; - /* - * button values stored here - */ - int m_buttonnum; - /* * max # of buttons avail */ @@ -146,7 +142,6 @@ public: bool aAxisIsPositive(int axis_single); /* check a single axis only */ bool aAnyButtonPressIsPositive(void); - bool aAnyButtonReleaseIsPositive(void); bool aButtonPressIsPositive(int button); bool aButtonReleaseIsPositive(int button); bool aHatIsPositive(int hatnum, int dir); @@ -160,10 +155,6 @@ public: int GetAxisPosition(int index){ return m_axis_array[index]; } - - int GetButton(void){ - return m_buttonnum; - } int GetHat(int index){ return m_hat_array[index]; diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h index c7a9a5114df..70619ff337a 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h @@ -40,6 +40,7 @@ #define JOYINDEX_MAX 8 #define JOYAXIS_MAX 16 +#define JOYBUT_MAX 18 #define JOYHAT_MAX 4 #define JOYAXIS_RIGHT 0 diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp index 3ca8d7d2329..66193a2f4b9 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp @@ -42,7 +42,7 @@ void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event) m_istrig_axis = 1; } - +/* See notes below in the event loop */ void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event) { if(sdl_event->jhat.hat >= JOYAXIS_MAX) @@ -52,30 +52,20 @@ void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event) m_istrig_hat = 1; } +/* See notes below in the event loop */ void SCA_Joystick::OnButtonUp(SDL_Event* sdl_event) { m_istrig_button = 1; - - /* this is needed for the "all events" option - * so we know if there are no buttons pressed */ - int i; - for (i=0; im_joystick, i)) { - m_buttonnum = i; - return; - } - } - m_buttonnum = -2; } void SCA_Joystick::OnButtonDown(SDL_Event* sdl_event) { - if(sdl_event->jbutton.button <= m_buttonmax) /* unsigned int so always above 0 */ - { - m_istrig_button = 1; - m_buttonnum = sdl_event->jbutton.button; - } + //if(sdl_event->jbutton.button > m_buttonmax) /* unsigned int so always above 0 */ + // return; + // sdl_event->jbutton.button; + + m_istrig_button = 1; } @@ -84,22 +74,27 @@ void SCA_Joystick::OnNothing(SDL_Event* sdl_event) m_istrig_axis = m_istrig_button = m_istrig_hat = 0; } -/* only handle events for 1 joystick */ - void SCA_Joystick::HandleEvents(void) { SDL_Event sdl_event; int i; - for (i=0; iOnNothing(&sdl_event); } - if(SDL_PollEvent(&sdl_event)) + while(SDL_PollEvent(&sdl_event)) { /* Note! m_instance[sdl_event.jaxis.which] * will segfault if over JOYINDEX_MAX, not too nice but what are the chances? */ + + /* Note!, with buttons, this wont care which button is pressed, + * only to set 'm_istrig_button', actual pressed buttons are detected by SDL_JoystickGetButton */ + + /* Note!, if you manage to press and release a button within 1 logic tick + * it wont work as it should */ + switch(sdl_event.type) { case SDL_JOYAXISMOTION: From 0edb6e89be23c20f1b1e3521ea854e44829b4969 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 May 2009 14:01:10 +0000 Subject: [PATCH 356/444] [#18803] 'ShadeModes' dictionary and 'shadeMode' instance variable exported to Python API Ton was ok with adding Vladislav Turbanov (vladius)'s patch during the freeze. --- source/blender/python/api2_2x/Material.c | 49 ++++++++++++++++++- source/blender/python/api2_2x/doc/Material.py | 7 +++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c index cb2c81aba6e..ad4296d19d8 100644 --- a/source/blender/python/api2_2x/Material.c +++ b/source/blender/python/api2_2x/Material.c @@ -335,6 +335,20 @@ static PyObject *M_Material_Get( PyObject * self, PyObject * args ) } } +static PyObject *Material_ShadeModesDict( void ) +{ + PyObject *ShadeModes = PyConstant_New( ); + + if( ShadeModes ) { + BPy_constant *c = ( BPy_constant * ) ShadeModes; + + PyConstant_Insert(c, "CUBIC", PyInt_FromLong(MA_CUBIC)); + PyConstant_Insert(c, "OBCOLOR", PyInt_FromLong(MA_OBCOLOR)); + } + + return ShadeModes; +} + static PyObject *Material_ModesDict( void ) { PyObject *Modes = PyConstant_New( ); @@ -454,12 +468,13 @@ static PyObject *Material_ColorRampInputDict( void ) /*****************************************************************************/ PyObject *Material_Init( void ) { - PyObject *submodule, *Modes, *Shaders, *ColorbandInput, *ColorbandMethod; + PyObject *submodule, *Modes, *ShadeModes, *Shaders, *ColorbandInput, *ColorbandMethod; if( PyType_Ready( &Material_Type ) < 0) return NULL; Modes = Material_ModesDict( ); + ShadeModes = Material_ShadeModesDict( ); Shaders = Material_ShadersDict( ); ColorbandMethod = Material_ColorRampMethodsDict( ); ColorbandInput = Material_ColorRampInputDict( ); @@ -469,6 +484,8 @@ PyObject *Material_Init( void ) if( Modes ) PyModule_AddObject( submodule, "Modes", Modes ); + if( ShadeModes ) + PyModule_AddObject( submodule, "ShadeModes", ShadeModes ); if( Shaders ) PyModule_AddObject( submodule, "Shaders", Shaders ); if( ColorbandMethod ) @@ -541,6 +558,7 @@ static PyObject *Matr_oldsetTranslucency( BPy_Material * self, PyObject * args ) static int Material_setIpo( BPy_Material * self, PyObject * value ); static int Material_setMode( BPy_Material * self, PyObject * value ); +static int Material_setShadeMode( BPy_Material * self, PyObject * value ); static int Material_setRGBCol( BPy_Material * self, PyObject * value ); static int Material_setSpecCol( BPy_Material * self, PyObject * value ); static int Material_setMirCol( BPy_Material * self, PyObject * value ); @@ -620,6 +638,7 @@ static PyObject *Material_getColorComponent( BPy_Material * self, /*****************************************************************************/ static PyObject *Material_getIpo( BPy_Material * self ); static PyObject *Material_getMode( BPy_Material * self ); +static PyObject *Material_getShadeMode( BPy_Material * self ); static PyObject *Material_getRGBCol( BPy_Material * self ); /*static PyObject *Material_getAmbCol(BPy_Material *self);*/ static PyObject *Material_getSpecCol( BPy_Material * self ); @@ -1098,6 +1117,10 @@ static PyGetSetDef BPy_Material_getseters[] = { (getter)Material_getMode, (setter)Material_setMode, "Material mode bitmask", NULL}, + {"shadeMode", + (getter)Material_getShadeMode, (setter)Material_setShadeMode, + "Material shade mode bitmask", + NULL}, {"nFlares", (getter)Material_getNFlares, (setter)Material_setNFlares, "Number of subflares with halo", @@ -1495,6 +1518,11 @@ static PyObject *Material_getMode( BPy_Material * self ) return PyInt_FromLong( ( long ) self->material->mode ); } +static PyObject *Material_getShadeMode( BPy_Material * self ) +{ + return PyInt_FromLong( ( long ) self->material->shade_flag ); +} + static PyObject *Material_getRGBCol( BPy_Material * self ) { return rgbTuple_getCol( self->col ); @@ -1970,6 +1998,24 @@ static int Material_setMode( BPy_Material * self, PyObject * value ) return 0; } +static int Material_setShadeMode( BPy_Material * self, PyObject * value ) +{ + int param; + + if( !PyInt_Check( value ) ) { + char errstr[128]; + sprintf ( errstr , "expected int bitmask of 0x%08x", (MA_CUBIC | MA_OBCOLOR) ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + param = PyInt_AS_LONG ( value ); + if ( ( param & (MA_CUBIC | MA_OBCOLOR) ) != param ) + return EXPP_ReturnIntError( PyExc_ValueError, + "invalid bit(s) set in mask" ); + self->material->shade_flag |= param; + + return 0; +} + static int Material_setRGBCol( BPy_Material * self, PyObject * value ) { return rgbTuple_setCol( self->col, value ); @@ -3476,4 +3522,3 @@ static int Material_setColorbandSpecularInput ( BPy_Material * self, PyObject * return EXPP_setIValueClamped(value, &self->material->rampin_spec, MA_RAMP_IN_SHADER, MA_RAMP_IN_RESULT, 'b'); } - diff --git a/source/blender/python/api2_2x/doc/Material.py b/source/blender/python/api2_2x/doc/Material.py index b37fd660810..3b8148b3f11 100644 --- a/source/blender/python/api2_2x/doc/Material.py +++ b/source/blender/python/api2_2x/doc/Material.py @@ -69,6 +69,11 @@ Example:: - NMAP_TS - Tangent space normal mapping. - GROUP_EXCLUSIVE - Light from this group even if the lights are on a hidden Layer. +@type ShadeModes: readonly dictionary +@var ShadeModes: The available Material Shade Modes. + - CUBIC - Use cubic interpolation of diffuse values, for smoother transitions. + - OBCOLOR - Modulate result with a per object color. + @type Shaders: readonly dictionary @var Shaders: The available Material Shaders. - DIFFUSE_LAMBERT - Make Material use the lambert diffuse shader. @@ -246,6 +251,8 @@ class Material: @ivar mode: Mode mode bitfield. See L{the Modes dictionary} keys and descriptions. @type mode: int + @ivar shadeMode: Shade mode bitfield. See L{the ShadeModes dictionary} keys and descriptions. + @type shadeMode: int @ivar nFlares: Number of subflares with halo. Value is clamped to the range [1,32]. @type nFlares: int From bdfa07cddb4aaec98e761d2b06730fdf49a8365d Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Thu, 28 May 2009 14:24:16 +0000 Subject: [PATCH 357/444] Python API ---------- Bugfix: make bpy.data.meshes.new() work the same way as Blender.Mesh.New(). --- source/blender/python/api2_2x/bpy_data.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/bpy_data.c b/source/blender/python/api2_2x/bpy_data.c index d3499a79874..d2e80bc3611 100644 --- a/source/blender/python/api2_2x/bpy_data.c +++ b/source/blender/python/api2_2x/bpy_data.c @@ -404,6 +404,7 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd) float color[] = {0, 0, 0, 1}; short data_code = 0; int user_count = 0; + PyObject *newOb = NULL; /* Load from file */ if ( ( self->type==ID_IM || self->type==ID_VF || @@ -594,7 +595,13 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd) /* set some types user count to 1, otherwise zero */ id->us = user_count; - return GetPyObjectFromID(id); + newOb = GetPyObjectFromID(id); + /* if object is a mesh, set the new flag so memory can be deallocated + * later if the mesh is not linked to an object (consistent with the + * Blender.Mesh.New() method */ + if (self->type == ID_ME) + ((BPy_Mesh *)newOb)->new = 1; + return newOb; } From 4026e6341e4499067ace0d1fbb6801907d33974c Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Thu, 28 May 2009 20:28:52 +0000 Subject: [PATCH 358/444] bugfix: added import Curve module --- release/scripts/import_dxf.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py index d1ea36ed2b7..6cc80a0dfed 100644 --- a/release/scripts/import_dxf.py +++ b/release/scripts/import_dxf.py @@ -7,7 +7,7 @@ Group: 'Import' Tooltip: 'Import for DWG/DXF geometry data.' """ __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)' -__version__ = '1.12 - 2009.05.26 by migius' +__version__ = '1.12 - 2009.05.27 by migius' __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319", "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"] __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"] @@ -111,6 +111,9 @@ History: -- support DXF-definitions of scene, lights and cameras -- support ortho mode for VIEWs and VPORTs as cameras + v1.12 - 2009.05.27 by migius + d6 todo: bugfix negative scaled INSERTs - isLeftHand(Matrix) check + v1.12 - 2009.05.26 by migius d5 changed to the new 2.49 method Vector.cross() d5 bugfix WORLDY(1,1,0) to (0,1,0) @@ -311,7 +314,7 @@ History: import Blender from Blender import Mathutils, BezTriple, Draw, Registry, sys,\ -Text3d, Window, Mesh, Material, Group +Text3d, Window, Mesh, Material, Group, Curve #from Blender.Mathutils import Vector, Matrix #import bpy #not used yet #import BPyMessages @@ -392,7 +395,15 @@ ALIGN = BezTriple.HandleTypes.ALIGN UI_MODE = True #activates UI-popup-print, if not multiple files imported - +#TODO:---patch for pre2.49------------- +if 0: + print Blender.Get('version') + #def Mathutil_CrossVecs(v1,v2): + az = Mathutils.Vector((0,0.5,0.4)) + print dir(az) + ax = WORLDZ.cross(az) + print ax + #-------- DWG support ------------------------------------------ extCONV_OK = True extCONV = 'DConvertCon.exe' From 17c51c6cb778aa584dee93c9bd70d1a0844d53ac Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Thu, 28 May 2009 22:26:28 +0000 Subject: [PATCH 359/444] Bullet Physics maxphystep = 1 is better general default to avoid vicious circle (graphics slower -> physics slower -> overall frametime slower -> graphics slower etc.) See difference in vault.blend --- source/blender/blenkernel/intern/world.c | 2 +- source/blender/blenloader/intern/readfile.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index d47f4efeb4e..41017cb0116 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -112,7 +112,7 @@ World *add_world(char *name) wrld->ticrate = 60; wrld->maxlogicstep = 5; wrld->physubstep = 1; - wrld->maxphystep = 5; + wrld->maxphystep = 1; return wrld; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a99cb86f86b..8cfe3ea8ace 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8131,7 +8131,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) wrld->ticrate = 60; wrld->maxlogicstep = 5; wrld->physubstep = 1; - wrld->maxphystep = 5; + wrld->maxphystep = 1; } } From 9c158175ab78936b6694320dbfe0f9b3bd989e11 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Fri, 29 May 2009 06:50:31 +0000 Subject: [PATCH 360/444] bugfix and update DXF-Exporter scripts please get it in 2.49 release --- release/scripts/bpymodules/dxfLibrary.py | 16 +- release/scripts/export_dxf.py | 2490 +++++++++++++++++++--- 2 files changed, 2212 insertions(+), 294 deletions(-) diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py index 55907e03bc1..1e190fec772 100644 --- a/release/scripts/bpymodules/dxfLibrary.py +++ b/release/scripts/bpymodules/dxfLibrary.py @@ -1,6 +1,6 @@ #dxfLibrary.py : provides functions for generating DXF files # -------------------------------------------------------------------------- -__version__ = "v1.29beta - 2008.12.28" +__version__ = "v1.30 - 2009.05.28" __author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)" __license__ = "GPL" __url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" @@ -18,9 +18,12 @@ IDEAs: - TODO: -- add support for SPLINEs, (bad idea, cause DXF r14 object :( +- add support for DXFr14 (new file header) +- add support for SPLINEs, although it is DXFr14 object History +v1.30 - 2009.05.28 by migius +- bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0 v1.29 - 2008.12.28 by Yorik - modif POLYLINE to support bulge segments v1.28 - 2008.12.13 by Steeve/BlenderArtists @@ -42,7 +45,7 @@ ______________________________________________________________ # -------------------------------------------------------------------------- # DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani) -# 2008 modif by Remigiusz Fiedler (AKA migius) +# 2008/2009 modif by Remigiusz Fiedler (AKA migius) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -85,7 +88,6 @@ def _point(x,index=0): def _points(plist): """Convert a list of tuples to dxf points""" out = '\n'.join([_point(plist[i],i)for i in range(len(plist))]) - #print 'deb: points=\n', out #------------------- return out #---base classes---------------------------------------- @@ -326,7 +328,6 @@ class PolyLine(_Entity): def __str__(self): result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag) - #print 'deb: self._common()', self._common() #---------- result+=' 66\n1\n' result+='%s\n' %_point(self.org_point) if self.polyface: @@ -337,10 +338,11 @@ class PolyLine(_Entity): for point in self.points: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(point[0:2]) if self.polyface: + result+='%s\n' %_point(point[0:3]) result+=' 70\n192\n' elif self.polyline2d: + result+='%s\n' %_point(point[0:2]) if len(point)>4: width1, width2 = point[3], point[4] if width1!=None: result+=' 40\n%s\n' %width1 @@ -348,6 +350,8 @@ class PolyLine(_Entity): if len(point)==6: bulge = point[5] if bulge: result+=' 42\n%s\n' %bulge + else: + result+='%s\n' %_point(point[0:3]) for face in self.faces: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py index 84a173c1e7d..5f7a6ecad37 100644 --- a/release/scripts/export_dxf.py +++ b/release/scripts/export_dxf.py @@ -1,47 +1,76 @@ #!BPY """ - Name: 'Autodesk (.dxf .dwg)' - Blender: 247 + Name: 'Autodesk DXF (.dxf)' + Blender: 249 Group: 'Export' - Tooltip: 'Export geometry to Autocad DXF/DWG-r12 (Drawing eXchange Format).' + Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).' """ -__version__ = "v1.29 - 2009.04.11" -__author__ = "Remigiusz Fiedler (AKA migius), Alexandros Sigalas (AKA alxarch), Stani Michiels" +__version__ = "1.34 - 2009.05.28" +__author__ = "Remigiusz Fiedler (AKA migius)" __license__ = "GPL" -__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" +__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" __bpydoc__ ="""The script exports Blender geometry to DXF format r12 version. Version %s Copyright %s License %s -extern dependances: dxfLibrary.py +extern dependances: dxfLibrary.py, (optionaly: DConvertCon.exe) + +CONTRIBUTORS: +Remigiusz Fiedler (AKA migius) +Alexandros Sigalas (AKA alxarch) +Stani Michiels (AKA stani) See the homepage for documentation. url: %s IDEAs: - - correct normals for POLYLINE-POLYFACE via proper point-order - - HPGL output for 2d and flattened 3d content - +- correct normals for POLYLINE-POLYFACE via proper vertex-order +- HPGL output, especially usefull for correct scaled printing of 2d drawings + TODO: - export dupligroups and dupliverts as blocks ( option for the user to decide ) -- optimize back-faces removal (probably needs matrix transform) - optimize POLYFACE routine: remove double-vertices - optimize POLYFACE routine: remove unused vertices - support hierarchies: groups, instances, parented structures - support 210-code (3d orientation vector) -- presets for architectural scales - write drawing extends for automatic view positioning in CAD +- support mapping: materials to DXF-styles History -v1.29 - 2009.04.11 by migius +v1.34 - 2009.05.28 by migius +- bugfix POLYFACE export, synchronized with dxfLibrary.py +- changed to the new 2.49 method Vector.cross() +- output style manager (first try) +v1.33 - 2009.05.25 by migius +- bugfix flipping normals in mirrored objects +- added UI-Button for future Shadow Generator +- support curve objects in projection-2d mode +- UI stuff: camera selector/manager +v1.32 - 2009.05.22 by migius +- debug mode for curve-objects: output pass to Blender +- wip support 210-code(extrusion) calculation +- default settings for 2D and 3D export +v1.31 - 2009.05.18 by migius +- globals translated to GUI_A/B dictionary +- optimizing back-faces removal for "hidden-lines" mode +- presets for global location and scale (architecture) +- UI layout: scrollbars, pan with MMB/WHEEL, dynamic width +- new GUI with Draw.Register() from DXF-importer.py +v1.30 - 2008.12.14 by migius +- started work on GUI with Draw.Register() +v1.29 - 2009.04.11 by stani - added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter -v1.28 - 2009.02.05 by alxarch +v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch) - added option to apply modifiers on exported meshes - added option to also export duplicates (from dupliverts etc) +v1.28 - 2008.10.22 by migius +- workaround for PVert-bug on ubuntu (reported by Yorik) +- add support for FGons - ignore invisible_tagged edges +- add support for camera: ortho and perspective v1.27 - 2008.10.07 by migius - exclude Stani's DXF-Library to extern module v1.26 - 2008.10.05 by migius @@ -92,46 +121,161 @@ ______________________________________________________________ import Blender -from Blender import Mathutils, Window, Scene, sys, Draw, Mesh -import BPyMessages -try: import os -except: os = None -try: import subprocess -except: subprocess = None -try: import copy -except: copy = None +from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple +from Blender import Registry, Object, Mesh +import os +import subprocess -#print os.sys.platform -#print dir(os.sys.version) - -#import dxfLibrary +import dxfLibrary as DXF +#reload(DXF) #reload(dxfLibrary) -if copy and os: - from dxfLibrary import * - #-------- DWG support ------------------------------------------ - extCONV_OK = True - extCONV = 'DConvertCon.exe' - extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) - if not os.path.isfile(extCONV_PATH): - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ - Copy first %s into Blender script directory.|\ - More details in online Help.' %extCONV - else: - if not os.sys.platform.startswith('win'): - # check if Wine installed: - if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): - extCONV_PATH = 'wine %s'%extCONV_PATH - else: - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ - The external DWG-converter (%s) needs Wine installed on your system.|\ - More details in online Help.' %extCONV - #print 'extCONV_PATH = ', extCONV_PATH +#from dxfLibrary import * + +import math +from math import atan, log10 + +#pi = math.pi +#pi = 3.14159265359 +d2r = math.pi / 180.0 +#note: d2r * angle == math.radians(angle) + +print '\n\n\n' +print 'DXF-Exporter v%s *** start ***' %(__version__) #--------------------- + +#DEBUG = True #activets debug mode +#----globals------------------------------------------ +ONLYSELECTED = 1 # 0/1 = False/True +POLYLINES = 1 # prefer POLYLINEs not LINEs +POLYFACES = 1 # prefer POLYFACEs not 3DFACEs +PROJECTION = 0 # flatten output geometry to Z = 0.0 +HIDDEN_LINES = 0 #filter out hidden geometry +SHADOWS = 0 # sun/shadows simulation +CAMERA = 1 # view from active camera or from 3d-view +PERSPECTIVE = 0 #perspective camera +APPLY_MODIFIERS = 1 +INCLUDE_DUPLIS = 0 +OUTPUT_DWG = 0 #optional save to DWG with extern converter -#----------------------------------------------------- +G_SCALE = 1.0 #(0.0001-1000) global scaling factor for output dxf data +G_ORIGIN = [0.0,0.0,0.0] #global translation-vector (x,y,z) in Blender units +ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units + +MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex" +CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution +CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve +THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments +MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness +MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width + +BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults +BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults +PREFIX = 'BF_' #used as prefix for DXF names +LAYERNAME_DEF = '' #default layer name +LAYERCOLOR_DEF = 7 #default layer color index +LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType +ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index +ENTITYCOLOR_DEF = BYLAYER #default entity color index +ENTITYLTYPE_DEF = BYLAYER #default entity lineType +E_M = 0 +LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction" +M_OBJ = 0 + +FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE) +MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001) +INIFILE_DEFAULT_NAME = 'exportDXF' +INIFILE_EXTENSION = '.ini' +INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data' +INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data' + +SCENE = None +WORLDX = Mathutils.Vector((1,0,0)) +#TODO: a bug? WORLDY = Mathutils.Vector((1,1,0)) +WORLDY = Mathutils.Vector((0,1,0)) +WORLDZ = Mathutils.Vector((0,0,1)) + +AUTO = BezTriple.HandleTypes.AUTO +FREE = BezTriple.HandleTypes.FREE +VECT = BezTriple.HandleTypes.VECT +ALIGN = BezTriple.HandleTypes.ALIGN + + +#-------- DWG support ------------------------------------------ +extCONV_OK = True +extCONV = 'DConvertCon.exe' +extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) +if not os.path.isfile(extCONV_PATH): + extCONV_OK = False + extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ +Copy first %s into Blender script directory.|\ +More details in online Help.' %extCONV +else: + if not os.sys.platform.startswith('win'): + # check if Wine installed: + if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): + extCONV_PATH = 'wine %s'%extCONV_PATH + else: + extCONV_OK = False + extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ +The external DWG-converter (%s) needs Wine installed on your system.|\ +More details in online Help.' %extCONV +#print 'extCONV_PATH = ', extCONV_PATH + + +#---------------------------------------------- +def updateMenuCAMERA(): + global CAMERAS + global MenuCAMERA + global MenuLIGHT + + scn = Scene.GetCurrent() + objs = scn.getChildren() + currcam = scn.getCurrentCamera() + if currcam: currcam = currcam.getName() + maincams = [] + MenuCAMERA = "Select Camera%t" + for cam in objs: + if cam.getType() == 'Camera': + if cam.getName()[0:4] != "Temp": + maincams.append(cam.getName()) + maincams.sort() + maincams.reverse() + CAMERAS = maincams + for i, cam in enumerate(CAMERAS): + if cam==currcam: + MenuCAMERA += "|* " + cam + else: MenuCAMERA += "| " + cam + MenuCAMERA += "|current 3d-View" + MenuLIGHT = "Select Sun%t| *todo" + + +#---------------------------------------------- +def updateCAMERA(): + global CAMERA, GUI_A + #CAMERA = 1 + scn = Scene.GetCurrent() + currcam = scn.getCurrentCamera() + if currcam: currcam = currcam.getName() + if currcam in CAMERAS: + CAMERA = CAMERAS.index(currcam)+1 + GUI_A['camera_on'].val = CAMERA + +#---------------------------------------------- +def gotoCAMERA(): + cam = Object.Get(CAMERAS[CAMERA-1]) + print 'deb: CAMERA, cam',CAMERA, cam + if cam.getType() != 'Camera': + sure = Draw.PupMenu("Info: %t| It is not a Camera Object.") + else: + scn = Scene.getCurrent() + scn.setCurrentCamera(cam) + Window.CameraView(0) + Window.Redraw() + updateMenuCAMERA() + + +#------- Duplicats support ---------------------------------------------- def dupTest(object): """ Checks objects for duplicates enabled (any type) @@ -160,7 +304,7 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): result = [] for ob in oblist: - if dupTest(ob): + if INCLUDE_DUPLIS and dupTest(ob): dup_obs=ob.DupObjects if len(dup_obs): for dup_ob, dup_mx in dup_obs: @@ -185,39 +329,52 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): return result #----------------------------------------------------- -def hidden_status(faces, mx_n): - #print 'HIDDEN_MODE: caution! not full implemented yet' - ok_faces = [] - ok_edges = [] - #sort out back-faces = with normals pointed away from camera +def hidden_status(faces, mx, mx_n): + # sort out back-faces = with normals pointed away from camera + print 'HIDDEN_LINES: caution! not full implemented yet' + front_faces = [] + front_edges = [] for f in faces: #print 'deb: face=', f #--------- + #print 'deb: dir(face)=', dir(f) #--------- # get its normal-vector in localCS vec_normal = f.no.copy() #print 'deb: vec_normal=', vec_normal #------------------ - #must be transfered to camera/view-CS + # must be transfered to camera/view-CS vec_normal *= mx_n #vec_normal *= mb.rotationPart() #print 'deb:2vec_normal=', vec_normal #------------------ #vec_normal *= mw0.rotationPart() #print 'deb:3vec_normal=', vec_normal, '\n' #------------------ - # normal must point the Z direction-hemisphere - if vec_normal[2] > 0.0 : - ok_faces.append(f.index) + + frontFace = False + if not PERSPECTIVE: #for ortho mode ---------- + # normal must point the Z direction-hemisphere + if vec_normal[2] > 0.00001: + frontFace = True + else: + v = f.verts[0] + vert = Mathutils.Vector(v.co) * mx + if Mathutils.DotVecs(vert, vec_normal) < 0.00001: + frontFace = True + + if frontFace: + front_faces.append(f.index) for key in f.edge_keys: #this test can be done faster with set() - if key not in ok_edges: - ok_edges.append(key) - #print 'deb: amount of visible faces=', len(ok_faces) #--------- - #print 'deb: visible faces=', ok_faces #--------- - #print 'deb: amount of visible edges=', len(ok_edges) #--------- - #print 'deb: visible edges=', ok_edges #--------- - return ok_faces, ok_edges + if key not in front_edges: + front_edges.append(key) + + #print 'deb: amount of visible faces=', len(front_faces) #--------- + #print 'deb: visible faces=', front_faces #--------- + #print 'deb: amount of visible edges=', len(front_edges) #--------- + #print 'deb: visible edges=', front_edges #--------- + return front_faces, front_edges -#----------------------------------------------------- -def projected_co(vec, mw): +#--------not used------------------------------------- +def projected_co0(vec, mw): # convert the world coordinates of vector to screen coordinates #co = vec.co.copy().resize4D() co = vec.copy().resize4D() @@ -235,181 +392,580 @@ def flatten(points, mw): #print 'deb: flatten points=', points #--------- return points + #----------------------------------------------------- -def exportMesh(ob, mx, mx_n,me=None): - entities = [] +def getExtrusion(matrix): + + print 'deb:getExtrusion() matrix=\n', matrix #--------- + ma = matrix.copy().normalize() + AZaxis = ma[2] # = ArbitraryZvector + ArbitraryZaxis = [AZaxis[0],AZaxis[1],AZaxis[2]] + threshold = 1.0 / 64.0 + if abs(Zaxis[0]) < threshold or abs(Zaxis[1]) < threshold: + #AXaxis = Mathutils.CrossVecs(WORLDY,AZaxis) #for<2.49 + AXaxis = WORLDY.cross(AZaxis) + else: + #AXaxis = Mathutils.CrossVecs(WORLDZ,AZaxis) #for<2.49 + AXaxis = WORLDZ.cross(AZaxis) + + Rotation = Mathutils.AngleBetweenVecs(WORLDX,AXaxis) #output in degrees + Elevation = 1.0 + + return ArbitraryZaxis, Rotation, Elevation + + +#----------------------------------------------------- +def projected_co(verts, mx): + # converts world coordinates of points to screen coordinates + temp_verts = [] + for v in verts: + #temp_verts.append(Blender.Mesh.MVert(v.co)) + temp_verts.append(Mesh.MVert(v)) + #print 'deb: temp_verts=', temp_verts #--------- + + if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val + else: locZ = 0.0 + + for v in temp_verts: + v.co *= mx + if PROJECTION: + if PERSPECTIVE: + clipStart = 10.0 + for v in temp_verts: + coef = - clipStart / v.co[2] + v.co[0] *= coef + v.co[1] *= coef + v.co[2] = locZ + for v in temp_verts: + v.co[2] = locZ + temp_verts = [v.co[:3] for v in temp_verts] + return temp_verts + + +#----------------------------------------------------- +def isLeftHand(matrix): + #Is the matrix a left-hand-system, or not? + ma = matrix.rotationPart() + #crossXY = Mathutils.CrossVecs(ma[0], ma[1]) #for<2.49 + crossXY = ma[0].cross(ma[1]) + #check = Mathutils.DotVecs(ma[2], crossXY) #for<2.49 + check = ma[2].dot(crossXY) + if check < 0.00001: return 1 + return 0 + + +#----------------------------------------------------- +def exportMesh(ob, mx, mx_n, me=None, **common): global APPLY_MODIFIERS - if me is None: + entities = [] + #print 'deb:exportMesh() common=', common #--------- + if me is None: # me means mesh me = ob.getData(mesh=1) else: me.getFromObject(ob) - #me.transform(mx) + # me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state # above is eventualy faster, but bad, cause - # directly transforms origin geometry and write back rounding errors - me_verts = me.verts[:] #we dont want manipulate origin data - #print 'deb: me_verts=', me_verts #--------- - #me.transform(mx_inv) #counterpart to - back to the origin state - for v in me_verts: - v.co *= mx - faces=[] - edges=[] - if HIDDEN_MODE: - ok_faces, ok_edges = hidden_status(me.faces, mx_n) - - #if (not FLATTEN) and len(me.faces)>0 and ONLYFACES: - if ONLYFACES: - if POLYFACES: #export 3D as POLYFACEs - allpoints = [] - allfaces = [] - allpoints = [v.co[:3] for v in me_verts] - for f in me.faces: - #print 'deb: face=', f #--------- - if not HIDDEN_MODE or \ - (HIDDEN_MODE and f.index in ok_faces): - if 1: - points = f.verts - face = [p.index+1 for p in points] - #print 'deb: face=', face #--------- - allfaces.append(face) - else: #bad, cause create multiple vertex instances - points = f.verts - points = [ me_verts[p.index].co[:3] for p in points] - #points = [p.co[:3] for p in points] - #print 'deb: points=', points #--------- - index = len(allpoints)+1 - face = [index+i for i in range(len(points))] - allpoints.extend(points) - allfaces.append(face) - if allpoints and allfaces: - #print 'deb: allpoints=', allpoints #--------- - #print 'deb: allfaces=', allfaces #--------- - dxfPOLYFACE = PolyLine([allpoints, allfaces], flag=64) - entities.append(dxfPOLYFACE) - else: #export 3D as 3DFACEs - for f in me.faces: - #print 'deb: face=', f #--------- - if not HIDDEN_MODE or \ - (HIDDEN_MODE and f.index in ok_faces): - points = f.verts - points = [ me_verts[p.index].co[:3] for p in points] - #points = [p.co[:3] for p in points] - #print 'deb: points=', points #--------- - dxfFACE = Face(points) - entities.append(dxfFACE) - - else: #export 3D as LINEs - if HIDDEN_MODE and len(me.faces)!=0: - for e in ok_edges: - points = [ me_verts[key].co[:3] for key in e] - dxfLINE = Line(points) - entities.append(dxfLINE) - + # invasive: directly transforms origin geometry and write back rounding errors + #we dont want to manipulate origin data + #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug? + if me.verts: + #print 'deb:exportMesh() started' #--------- + allpoints = [v.co for v in me.verts] + allpoints = projected_co(allpoints, mx) + if GUI_A['g_origin_on'].val: #TODO: scale and object orientation + for p in allpoints: + p[0] += G_ORIGIN[0] + p[1] += G_ORIGIN[1] + p[2] += G_ORIGIN[2] + faces=[] + edges=[] + if me.faces and HIDDEN_LINES: + if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #--------- + faces, edges = hidden_status(me.faces, mx, mx_n) + faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces] else: - for e in me.edges: - #print 'deb: edge=', e #--------- - points=[] - #points = [e.v1.co*mx, e.v2.co*mx] - points = [ me_verts[key].co[:3] for key in e.key] - #print 'deb: points=', points #--------- - dxfLINE = Line(points) - entities.append(dxfLINE) + if DEBUG: print 'deb:exportMesh STANDARD mode' #--------- + for e in me.edges: edges.append(e.key) + #faces = [f.index for f in me.faces] + faces = [[v.index for v in f.verts] for f in me.faces] + #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces] + #print 'deb: allpoints=\n', allpoints #--------- + #print 'deb: edges=\n', edges #--------- + #print 'deb: faces=\n', faces #--------- + if isLeftHand(mx): # then change vertex-order in every face + for f in faces: + f.reverse() + #f = [f[-1]] + f[:-1] #TODO: might be needed + #print 'deb: faces=\n', faces #--------- + + c = mesh_as_list[GUI_A['mesh_as'].val] + if 'POINTs'==c: # export Mesh as multiple POINTs + for p in allpoints: + dxfPOINT = DXF.Point(p, **common) + entities.append(dxfPOINT) + elif 'LINEs'==c or (not faces): + if edges and allpoints: + if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene + for e in edges: + points = [allpoints[e[0]], allpoints[e[1]]] + dxfLINE = DXF.Line(points, **common) + entities.append(dxfLINE) + elif faces: + if c in ('POLYFACE','POLYLINE'): + if allpoints: + #TODO: purge allpoints: left only vertices used by faces + if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + faces = [[v+1 for v in f] for f in faces] + dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common) + #dxfPOLYFACE = DXF.PolyLine([allpoints, faces],org_point=[0,0,0], flag=64,width=None, **common) + #dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64) + #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #------------- + entities.append(dxfPOLYFACE) + elif '3DFACEs'==c: + if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + for f in faces: + #print 'deb: face=', f #--------- + points = [allpoints[key] for key in f] + #points = [p.co[:3] for p in points] + #print 'deb: pointsXX=\n', points #--------- + dxfFACE = DXF.Face(points, **common) + entities.append(dxfFACE) + + return entities + +#----------------------------------------------------- +def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True): + #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #--------- + ob = Object.New("Mesh",name) + me = Mesh.New(name) + #print 'deb: vertList=\n', vertList #--------- + #print 'deb: edgeList=\n', edgeList #--------- + #print 'deb: faceList=\n', faceList #--------- + me.verts.extend(vertList) + if edgeList: me.edges.extend(edgeList) + if faceList: me.faces.extend(faceList) + if flatten: + for v in me.verts: v.co.z = 0.0 + ob.link(me) + if link: + sce = Scene.getCurrent() + sce.objects.link(ob) + #me.triangleToQuad() + if AT_CUR: + cur_loc = Window.GetCursorPos() + ob.setLocation(cur_loc) + Blender.Redraw() + #return ob + +#----------------------------------------------------- +def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True): + #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #--------- + ob = Object.New("Curve",name) + cu = Curve.New(name) + #print 'deb: vertList=\n', vertList #--------- + curve = cu.appendNurb(BezTriple.New(vertList[0])) + for p in vertList[1:]: + curve.append(BezTriple.New(p)) + for point in curve: + #point.handleTypes = [VECT, VECT] + point.handleTypes = [FREE, FREE] + point.radius = 1.0 + curve.flagU = closed # 0 sets the curve not cyclic=open + cu.setResolu(6) + cu.update() #important for handles calculation + if flatten: + for v in cu.verts: v.co.z = 0.0 + ob.link(cu) + if link: + sce = Scene.getCurrent() + sce.objects.link(ob) + #me.triangleToQuad() + if AT_CUR: + cur_loc = Window.GetCursorPos() + ob.setLocation(cur_loc) + elif org_point: + cur_loc=org_point + ob.setLocation(cur_loc) + Blender.Redraw() + #return ob + + +#----------------------------------------------------- +def exportEmpty(ob, mx, mw, _common=None): + entities = [] + + if GUI_A['empty_as'].val==1: # export Empty as POINT + p = ob.loc + dxfPOINT = Point(p) + entities.append(dxfPOINT) return entities #----------------------------------------------------- -def exportCurve(ob, mx): +def exportCurve(ob, mx, mw, _common=None): entities = [] curve = ob.getData() + + """ if not PROJECTION: + Extrusion, Rotation, Elevation = getExtrusion(mx) + else: + Extrusion = None + """ + for cur in curve: - #print 'deb: START cur=', cur #-------------- - if 1: #not cur.isNurb(): - #print 'deb: START points' #-------------- - points = [] - org_point = [0.0,0.0,0.0] + print 'deb: START cur=', cur #-------------- + org_point = [0.0,0.0,0.0] + points = [] + if cur.isNurb(): for point in cur: - #print 'deb: point=', point #--------- - if cur.isNurb(): - vec = point[0:3] - else: - point = point.getTriple() - #print 'deb: point=', point #--------- - vec = point[1] + #print 'deb:isNurb point=', point #--------- + vec = point[0:3] #print 'deb: vec=', vec #--------- - pkt = Mathutils.Vector(vec) * mx + pkt = Mathutils.Vector(vec) #print 'deb: pkt=', pkt #--------- - #pkt *= SCALE_FACTOR - if 0: #FLATTEN: - pkt = projected_co(pkt, mw) points.append(pkt) + else: + for point in cur: + #point = point.getTriple() + #print 'deb:isBezier point=', point #--------- + vec = point.getTriple()[1] + #print 'deb: vec=', vec #--------- + pkt = Mathutils.Vector(vec) + #print 'deb: pkt=', pkt #--------- + points.append(pkt) + if len(points)>1: + #print 'deb: points', points #-------------- + points = projected_co(points, mx) if cur.isCyclic(): closed = 1 else: closed = 0 - if len(points)>1: - #print 'deb: points', points #-------------- - if POLYLINES: dxfPLINE = PolyLine(points,org_point,closed) - else: dxfPLINE = LineList(points,org_point,closed) + if DEBUG: curve_drawBlender(points,org_point,closed) #deb: draw to scene + if GUI_A['curve_as'].val==2: # export Curve as POLYLINE + dxfPLINE = DXF.PolyLine(points,org_point,closed,**common) entities.append(dxfPLINE) + elif GUI_A['curve_as'].val==1: # export Curve as multiple LINEs + dxfPLINE = DXF.LineList(points,org_point,closed,**common) + entities.append(dxfPLINE) + elif GUI_A['curve_as'].val==5: # export Curve as multiple POINTs + for p in points: + dxfPOINT = DXF.Point(p,**common) + entities.append(dxfPOINT) return entities +#----------------------------------------------------- +def getClipBox(camera): + sce = Scene.GetCurrent() + context = sce.getRenderingContext() + #print 'deb: context=\n', context #------------------ + #print 'deb: context=\n', dir(context) #------------------ + sizeX = context.sizeX + sizeY = context.sizeY + ratioXY = sizeX/float(sizeY) + #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------ + + clip1_Z = - camera.clipStart + clip2_Z = - camera.clipEnd + #print 'deb: clip Start=', camera.clipStart #------------------ + #print 'deb: clip End=', camera.clipEnd #------------------ + + if camera.type=='ortho': + scale = camera.scale + #print 'deb: camscale=', scale #------------------ + clip1shiftX = clip2shiftX = camera.shiftX * scale + clip1shiftY = clip2shiftY = camera.shiftY * scale + clip1_X = scale * 0.5 + clip1_Y = scale * 0.5 + if ratioXY > 1.0: clip1_Y /= ratioXY + else: clip1_X *= ratioXY + clip2_X = clip1_X + clip2_Y = clip1_Y + + near = clip1_Z + far = clip2_Z + right, left = clip1_X, -clip1_X + top, bottom = clip1_Y, -clip1_Y + + scaleX = 2.0/float(right - left) + x3 = -float(right + left)/float(right - left) + scaleY = 2.0/float(top - bottom) + y3 = -float(top + bottom)/float(top - bottom) + scaleZ = 1.0/float(far - near) + z3 = -float(near)/float(far - near) + + matr = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3], + [0.0, scaleY, 0.0, y3], + [0.0, 0.0, scaleZ, z3], + [0.0, 0.0, 0.0, 1.0]) + + elif camera.type=='persp': + #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe + #lens = camera.lens + angle = camera.angle + #print 'deb: cam angle=', angle #------------------ + shiftX = camera.shiftX + shiftY = camera.shiftY + fov_coef = atan(angle * d2r) + fov_coef *= 1.3 #incl. passpartou + clip1_k = clip1_Z * fov_coef + clip2_k = clip2_Z * fov_coef + clip1shiftX = - camera.shiftX * clip1_k + clip2shiftX = - camera.shiftX * clip2_k + clip1shiftY = - camera.shiftY * clip1_k + clip2shiftY = - camera.shiftY * clip2_k + clip1_X = clip1_Y = clip1_k * 0.5 + clip2_X = clip2_Y = clip2_k * 0.5 + if ratioXY > 1.0: + clip1_Y /= ratioXY + clip2_Y /= ratioXY + else: + clip1_X *= ratioXY + clip2_X *= ratioXY + + near = clip1_Z + far = clip2_Z + right, left = clip1_X, -clip1_X + top, bottom = clip1_Y, -clip1_Y + #return Matrix( [scaleX, 0.0, x2, 0.0], + #[0.0, scaleY, y2, 0.0], + #[0.0, 0.0, scaleZ, wZ], + #[0.0, 0.0, -1.0, 0.0]) + matr = Mathutils.Matrix( [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0], + [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0], + [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)], + [0.0, 0.0, -1.0, 0.0]) + + + clip_box = [ + -clip1_X + clip1shiftX, clip1_X + clip1shiftX, + -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY, + -clip2_X + clip2shiftX, clip2_X + clip2shiftX, + -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY, + clip1_Z, clip2_Z] + #print 'deb: clip_box=\n', clip_box #------------------ + #drawClipBox(clip_box) + return clip_box, matr + + +#----------------------------------------------------- +def drawClipBox(clip_box): + min_X1, max_X1, min_Y1, max_Y1,\ + min_X2, max_X2, min_Y2, max_Y2,\ + min_Z, max_Z = clip_box + verts = [] + verts.append([min_X1, min_Y1, min_Z]) + verts.append([max_X1, min_Y1, min_Z]) + verts.append([max_X1, max_Y1, min_Z]) + verts.append([min_X1, max_Y1, min_Z]) + verts.append([min_X2, min_Y2, max_Z]) + verts.append([max_X2, min_Y2, max_Z]) + verts.append([max_X2, max_Y2, max_Z]) + verts.append([min_X2, max_Y2, max_Z]) + faces = [[0,1,2,3],[4,5,6,7]] + nme = Mesh.New() + nme.verts.extend(verts) + nme.faces.extend(faces) + + plan = Object.New('Mesh','clip_box') + plan.link(nme) + sce = Scene.GetCurrent() + sce.objects.link(plan) + plan.setMatrix(sce.objects.camera.matrix) + + +#------------------------------------------------- +def getCommons(ob): + #set up common attributes for output style: + # color=None + # extrusion=None + # layer='0', + # lineType=None + # lineTypeScale=None + # lineWeight=None + # thickness=None + # parent=None + + layers = ob.layers #gives a list e.g.[1,5,19] + if layers: ob_layer_nr = layers[0] + #print 'ob_layer_nr=', ob_layer_nr #-------------- + + materials = ob.getMaterials() + if materials: + ob_material = materials[0] + ob_mat_color = ob_material.rgbCol + else: ob_mat_color, ob_material = None, None + #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #-------------- + + data = ob.getData() + data_materials = ob.getMaterials() + if data_materials: + data_material = data_materials[0] + data_mat_color = data_material.rgbCol + else: data_mat_color, data_material = None, None + #print 'data_mat_color, data_material=', data_mat_color, data_material #-------------- + + entitylayer = ENTITYLAYER_DEF + c = entitylayer_from_list[GUI_A['entitylayer_from'].val] + #["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"] + if c=="default_LAYER": + entitylayer = LAYERNAME_DEF + elif c=="obj.layer" and ob_layer_nr: + entitylayer = 'LAYER'+ str(ob_layer_nr) + elif c=="obj.material" and ob_material: + entitylayer = ob_material.name + elif c=="obj.name": + entitylayer = ob.name + elif c=="obj.data.material" and ob_material: + entitylayer = data_material.name + elif c=="obj.data.name": + entitylayer = data.name + entitylayer = validDXFr12name(PREFIX+entitylayer) + if entitylayer=="": entitylayer = "BF_0" + + entitycolor = ENTITYCOLOR_DEF + c = entitycolor_from_list[GUI_A['entitycolor_from'].val] + if c=="default_COLOR": + entitycolor = LAYERCOLOR_DEF + elif c=="BYLAYER": + entitycolor = BYLAYER + elif c=="BYBLOCK": + entitycolor = BYBLOCK + elif c=="obj.layer" and ob_layer_nr: + entitycolor = ob_layer_nr + elif c=="obj.color" and ob.color: + entitycolor = col2DXF(ob.color) + elif c=="obj.material" and ob_mat_color: + entitycolor = col2DXF(ob_mat_color) + elif c=="obj.data.material" and data_mat_color: + entitycolor = col2DXF(data_mat_color) + #if entitycolor!=None: layercolor = entitycolor + + entityltype = ENTITYLTYPE_DEF + c = entityltype_from_list[GUI_A['entityltype_from'].val] + if c=="default_LTYPE": + entityltype = LAYERLTYPE_DEF + elif c=="BYLAYER": + entityltype = BYLAYER + elif c=="BYBLOCK": + entityltype = BYBLOCK + elif c: + entityltype = c + + return entitylayer,entitycolor,entityltype + + #----------------------------------------------------- def do_export(export_list, filepath): + global PERSPECTIVE Window.WaitCursor(1) - t = sys.time() + t = Blender.sys.time() #init Drawing --------------------- - d=Drawing() + d=DXF.Drawing() #add Tables ----------------- - #d.blocks.append(b) #table blocks - d.styles.append(Style()) #table styles - d.views.append(View('Normal')) #table view - d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem + #d.blocks.append(b) #table blocks + #goes automatic: d.styles.append(DXF.Style()) #table styles + d.views.append(DXF.View('Normal')) #table view + d.views.append(DXF.ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem #add Entities -------------------- - something_ready = False - #ViewVector = Mathutils.Vector(Window.GetViewVector()) - #print 'deb: ViewVector=', ViewVector #------------------ - mw0 = Window.GetViewMatrix() - #mw0 = Window.GetPerspMatrix() #TODO: how get it working? - mw = mw0.copy() - if FLATTEN: - m0 = Mathutils.Matrix() - m0[2][2]=0.0 - mw *= m0 #flatten ViewMatrix + something_ready = 0 + sce = Scene.GetCurrent() - if APPLY_MODIFIERS: - tmp_me = Mesh.New('tmp') - else: - tmp_me = None + mw = Mathutils.Matrix( [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0]) + if PROJECTION: + if CAMERA