BGE Python API

- initialize pythons sys.argv in the blenderplayer
- ignore all arguments after a single " - " in the blenderplayer (like in blender), so args can be passed to the game.
- add a utility function PyOrientationTo() - to take a Py euler, quat or 3x3 matrix and convert into a C++ MT_Matrix3x3.
- add utility function ConvertPythonToMesh to get a RAS_MeshObject from a KX_MeshProxy or a name.
- Added error prefix arguments to ConvertPythonToGameObject, ConvertPythonToMesh and PyOrientationTo so the error messages can include what function they came from.
- deprecated brick.getOwner() for the "owner" attribute.
This commit is contained in:
Campbell Barton
2009-04-20 09:13:59 +00:00
parent 9078ce5da2
commit dee32d0b3f
23 changed files with 215 additions and 171 deletions

View File

@@ -246,8 +246,8 @@ PyParentObject SCA_ILogicBrick::Parents[] = {
PyMethodDef SCA_ILogicBrick::Methods[] = { PyMethodDef SCA_ILogicBrick::Methods[] = {
// --> Deprecated
{"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS}, {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS},
// --> Deprecated
{"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPyGetExecutePriority, METH_NOARGS}, {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPyGetExecutePriority, METH_NOARGS},
{"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS}, {"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
// <-- Deprecated // <-- Deprecated
@@ -255,6 +255,7 @@ PyMethodDef SCA_ILogicBrick::Methods[] = {
}; };
PyAttributeDef SCA_ILogicBrick::Attributes[] = { 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_Ueber_Priority),
{NULL} //Sentinel {NULL} //Sentinel
}; };
@@ -291,6 +292,8 @@ int SCA_ILogicBrick::py_setattro(PyObject *attr, PyObject *value)
PyObject* SCA_ILogicBrick::PyGetOwner() PyObject* SCA_ILogicBrick::PyGetOwner()
{ {
ShowDeprecationWarning("getOwner()", "the owner property");
CValue* parent = GetParent(); CValue* parent = GetParent();
if (parent) if (parent)
{ {
@@ -327,6 +330,19 @@ PyObject* SCA_ILogicBrick::PyGetExecutePriority()
} }
/*Attribute functions */
PyObject* SCA_ILogicBrick::pyattr_get_owner(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
SCA_ILogicBrick* self= static_cast<SCA_ILogicBrick*>(self_v);
CValue* parent = self->GetParent();
if (parent)
return parent->GetProxy();
Py_RETURN_NONE;
}
/* Conversions for making life better. */ /* Conversions for making life better. */
bool SCA_ILogicBrick::PyArgToBool(int boolArg) bool SCA_ILogicBrick::PyArgToBool(int boolArg)
@@ -338,8 +354,6 @@ bool SCA_ILogicBrick::PyArgToBool(int boolArg)
} }
} }
PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg) PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg)
{ {
return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE); return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE);

View File

@@ -90,6 +90,8 @@ public:
KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetOwner); KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetOwner);
KX_PYMETHOD_VARARGS(SCA_ILogicBrick,SetExecutePriority); KX_PYMETHOD_VARARGS(SCA_ILogicBrick,SetExecutePriority);
KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetExecutePriority); KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetExecutePriority);
static PyObject* pyattr_get_owner(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
// check that attribute is a property // check that attribute is a property
static int CheckProperty(void *self, const PyAttributeDef *attrdef); static int CheckProperty(void *self, const PyAttributeDef *attrdef);

View File

@@ -151,7 +151,7 @@ GPG_Application::~GPG_Application(void)
bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene) bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene, int argc, char **argv)
{ {
bool result = false; bool result = false;
@@ -163,6 +163,10 @@ bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene)
m_startScene = scene; m_startScene = scene;
result = true; result = true;
} }
/* Python needs these */
m_argc= argc;
m_argv= argv;
return result; return result;
} }
@@ -681,7 +685,7 @@ bool GPG_Application::startEngine(void)
// some python things // some python things
PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest, m_maggie); PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest, m_maggie, m_argc, m_argv);
m_ketsjiengine->SetPythonDictionary(dictionaryobject); m_ketsjiengine->SetPythonDictionary(dictionaryobject);
initRasterizer(m_rasterizer, m_canvas); initRasterizer(m_rasterizer, m_canvas);
PyObject *gameLogic = initGameLogic(m_ketsjiengine, startscene); PyObject *gameLogic = initGameLogic(m_ketsjiengine, startscene);

View File

@@ -58,7 +58,7 @@ public:
GPG_Application(GHOST_ISystem* system); GPG_Application(GHOST_ISystem* system);
~GPG_Application(void); ~GPG_Application(void);
bool SetGameEngineData(struct Main* maggie, struct Scene* scene); bool SetGameEngineData(struct Main* maggie, struct Scene* scene, int argc, char** argv);
bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight, bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight,
const bool stereoVisual, const int stereoMode); const bool stereoVisual, const int stereoMode);
bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode); bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode);
@@ -154,5 +154,9 @@ protected:
*/ */
char* m_pyGlobalDictString; char* m_pyGlobalDictString;
int m_pyGlobalDictString_Length; int m_pyGlobalDictString_Length;
/* argc and argv need to be passed on to python */
int m_argc;
char** m_argv;
}; };

View File

@@ -206,6 +206,8 @@ void usage(const char* program)
printf(" blender_material 0 Enable material settings\n"); printf(" blender_material 0 Enable material settings\n");
printf(" ignore_deprecation_warnings 1 Ignore deprecation warnings\n"); printf(" ignore_deprecation_warnings 1 Ignore deprecation warnings\n");
printf("\n"); printf("\n");
printf(" - : all arguments after this are ignored, allowing python to access them from sys.argv\n");
printf("\n");
printf("example: %s -w 320 200 10 10 -g noaudio c:\\loadtest.blend\n", program); printf("example: %s -w 320 200 10 10 -g noaudio c:\\loadtest.blend\n", program);
printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program); printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program);
} }
@@ -293,6 +295,7 @@ static BlendFileData *load_game_data(char *progname, char *filename = NULL, char
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int i; int i;
int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
bool error = false; bool error = false;
SYS_SystemHandle syshandle = SYS_GetSystem(); SYS_SystemHandle syshandle = SYS_GetSystem();
bool fullScreen = false; bool fullScreen = false;
@@ -393,6 +396,12 @@ int main(int argc, char** argv)
#endif #endif
if (argv[i][0] == '-') if (argv[i][0] == '-')
{ {
/* ignore all args after " - ", allow python to have own args */
if (argv[i][1]=='\0') {
argc_py_clamped= i;
break;
}
switch (argv[i][1]) switch (argv[i][1])
{ {
case 'g': case 'g':
@@ -596,7 +605,7 @@ int main(int argc, char** argv)
char pathname[FILE_MAXDIR + FILE_MAXFILE]; char pathname[FILE_MAXDIR + FILE_MAXFILE];
char *titlename; char *titlename;
get_filename(argc, argv, filename); get_filename(argc_py_clamped, argv, filename);
if(filename[0]) if(filename[0])
BLI_convertstringcwd(filename); BLI_convertstringcwd(filename);
@@ -691,7 +700,7 @@ int main(int argc, char** argv)
} }
// GPG_Application app (system, maggie, startscenename); // GPG_Application app (system, maggie, startscenename);
app.SetGameEngineData(maggie, scene); app.SetGameEngineData(maggie, scene, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
BLI_strncpy(pathname, maggie->name, sizeof(pathname)); BLI_strncpy(pathname, maggie->name, sizeof(pathname));
BLI_strncpy(G.sce, maggie->name, sizeof(G.sce)); BLI_strncpy(G.sce, maggie->name, sizeof(G.sce));

View File

@@ -462,7 +462,7 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* value)
ShowDeprecationWarning("setObject()", "the object property"); ShowDeprecationWarning("setObject()", "the object property");
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_CameraActuator"))
return NULL; // ConvertPythonToGameObject sets the error return NULL; // ConvertPythonToGameObject sets the error
if (m_ob != NULL) if (m_ob != NULL)
@@ -589,7 +589,7 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF
KX_CameraActuator* self= static_cast<KX_CameraActuator*>(self_v); KX_CameraActuator* self= static_cast<KX_CameraActuator*>(self_v);
KX_GameObject *gameobj; KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_CameraActuator"))
return 1; // ConvertPythonToGameObject sets the error return 1; // ConvertPythonToGameObject sets the error
if (self->m_ob) if (self->m_ob)

View File

@@ -1182,22 +1182,12 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
PyObject* KX_GameObject::PyReplaceMesh(PyObject* value) PyObject* KX_GameObject::PyReplaceMesh(PyObject* value)
{ {
KX_Scene *scene = KX_GetActiveScene(); KX_Scene *scene = KX_GetActiveScene();
char* meshname; RAS_MeshObject* new_mesh;
void* mesh_pt;
meshname = PyString_AsString(value);
if (meshname==NULL) {
PyErr_SetString(PyExc_ValueError, "gameOb.replaceMesh(value): KX_GameObject, expected a mesh name");
return NULL;
}
mesh_pt = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname));
if (mesh_pt==NULL) { if (!ConvertPythonToMesh(value, &new_mesh, false, "gameOb.replaceMesh(value): KX_GameObject"))
PyErr_SetString(PyExc_ValueError, "gameOb.replaceMesh(value): KX_GameObject, the mesh name given does not exist");
return NULL; return NULL;
}
scene->ReplaceMesh(this, (class RAS_MeshObject*)mesh_pt);
scene->ReplaceMesh(this, new_mesh);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@@ -1568,49 +1558,15 @@ PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYAT
int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{ {
KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
if (!PySequence_Check(value)) {
PyErr_SetString(PyExc_AttributeError, "gameOb.orientation = [...]: KX_GameObject, expected a sequence"); /* if value is not a sequence PyOrientationTo makes an error */
return 1;
}
MT_Matrix3x3 rot; MT_Matrix3x3 rot;
if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, "))
return NULL;
if (PyMatTo(value, rot)) self->NodeSetLocalOrientation(rot);
{ self->NodeUpdateGS(0.f);
self->NodeSetLocalOrientation(rot); return 0;
self->NodeUpdateGS(0.f);
return 0;
}
PyErr_Clear();
if (PySequence_Size(value) == 4)
{
MT_Quaternion qrot;
if (PyVecTo(value, qrot))
{
rot.setRotation(qrot);
self->NodeSetLocalOrientation(rot);
self->NodeUpdateGS(0.f);
return 0;
}
return 1;
}
if (PySequence_Size(value) == 3)
{
MT_Vector3 erot;
if (PyVecTo(value, erot))
{
rot.setEuler(erot);
self->NodeSetLocalOrientation(rot);
self->NodeUpdateGS(0.f);
return 0;
}
return 1;
}
PyErr_SetString(PyExc_AttributeError, "gameOb.orientation = [...]: KX_GameObject, could not set the orientation from a 3x3 matrix, quaternion or euler sequence");
return 1;
} }
PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -2127,7 +2083,7 @@ PyObject* KX_GameObject::PyGetParent()
PyObject* KX_GameObject::PySetParent(PyObject* value) PyObject* KX_GameObject::PySetParent(PyObject* value)
{ {
KX_GameObject *obj; KX_GameObject *obj;
if (!ConvertPythonToGameObject(value, &obj, false)) if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject"))
return NULL; return NULL;
this->SetParent(KX_GetActiveScene(), obj); this->SetParent(KX_GetActiveScene(), obj);
@@ -2362,7 +2318,7 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getDistanceTo,
PyErr_Clear(); PyErr_Clear();
KX_GameObject *other; KX_GameObject *other;
if (ConvertPythonToGameObject(value, &other, false)) if (ConvertPythonToGameObject(value, &other, false, "gameOb.getDistanceTo(value): KX_GameObject"))
{ {
return PyFloat_FromDouble(NodeGetWorldPosition().distance(other->NodeGetWorldPosition())); return PyFloat_FromDouble(NodeGetWorldPosition().distance(other->NodeGetWorldPosition()));
} }
@@ -2385,7 +2341,7 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo,
PyErr_Clear(); PyErr_Clear();
KX_GameObject *other; KX_GameObject *other;
if (ConvertPythonToGameObject(value, &other, false)) if (ConvertPythonToGameObject(value, &other, false, "")) /* error will be overwritten */
{ {
toPoint = other->NodeGetWorldPosition(); toPoint = other->NodeGetWorldPosition();
} else } else
@@ -2479,7 +2435,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
KX_GameObject *other; KX_GameObject *other;
PyErr_Clear(); PyErr_Clear();
if (ConvertPythonToGameObject(pyarg, &other, false)) if (ConvertPythonToGameObject(pyarg, &other, false, "")) /* error will be overwritten */
{ {
toPoint = other->NodeGetWorldPosition(); toPoint = other->NodeGetWorldPosition();
} else } else
@@ -2555,7 +2511,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
{ {
PyErr_Clear(); PyErr_Clear();
if (ConvertPythonToGameObject(pyto, &other, false)) if (ConvertPythonToGameObject(pyto, &other, false, "")) /* error will be overwritten */
{ {
toPoint = other->NodeGetWorldPosition(); toPoint = other->NodeGetWorldPosition();
} else } else
@@ -2572,7 +2528,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
{ {
PyErr_Clear(); PyErr_Clear();
if (ConvertPythonToGameObject(pyfrom, &other, false)) if (ConvertPythonToGameObject(pyfrom, &other, false, "")) /* error will be overwritten */
{ {
fromPoint = other->NodeGetWorldPosition(); fromPoint = other->NodeGetWorldPosition();
} else } else
@@ -2685,10 +2641,10 @@ void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
} }
} }
bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok) bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix)
{ {
if (value==NULL) { if (value==NULL) {
PyErr_SetString(PyExc_TypeError, "Error in ConvertPythonToGameObject, python pointer NULL, should never happen"); PyErr_Format(PyExc_TypeError, "%s, python pointer NULL, should never happen", error_prefix);
*object = NULL; *object = NULL;
return false; return false;
} }
@@ -2699,7 +2655,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
if (py_none_ok) { if (py_none_ok) {
return true; return true;
} else { } else {
PyErr_SetString(PyExc_TypeError, "Expected KX_GameObject or a string for a name of a KX_GameObject, None is invalid"); PyErr_Format(PyExc_TypeError, "%s, expected KX_GameObject or a KX_GameObject name, None is invalid", error_prefix);
return false; return false;
} }
} }
@@ -2710,7 +2666,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
if (*object) { if (*object) {
return true; return true;
} else { } else {
PyErr_SetString(PyExc_ValueError, "Requested name did not match any KX_GameObject"); PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_GameObject in this scene", error_prefix, PyString_AsString(value));
return false; return false;
} }
} }
@@ -2720,7 +2676,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
/* sets the error */ /* sets the error */
if (*object==NULL) { if (*object==NULL) {
PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
return false; return false;
} }
@@ -2730,9 +2686,9 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
*object = NULL; *object = NULL;
if (py_none_ok) { if (py_none_ok) {
PyErr_SetString(PyExc_TypeError, "Expect a KX_GameObject, a string or None"); PyErr_Format(PyExc_TypeError, "%s, expect a KX_GameObject, a string or None", error_prefix);
} else { } else {
PyErr_SetString(PyExc_TypeError, "Expect a KX_GameObject or a string"); PyErr_Format(PyExc_TypeError, "%s, expect a KX_GameObject or a string", error_prefix);
} }
return false; return false;

View File

@@ -61,7 +61,7 @@ class PHY_IPhysicsEnvironment;
struct Object; struct Object;
/* utility conversion function */ /* utility conversion function */
bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok); bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix);
/** /**
* KX_GameObject is the main class for dynamic objects. * KX_GameObject is the main class for dynamic objects.

View File

@@ -304,3 +304,58 @@ PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBU
KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv); KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv);
return PyInt_FromLong(self->m_meshobj->NumPolygons()); return PyInt_FromLong(self->m_meshobj->NumPolygons());
} }
/* a close copy of ConvertPythonToGameObject but for meshes */
bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **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_MeshProxy or a KX_MeshProxy name, None is invalid", error_prefix);
return false;
}
}
if (PyString_Check(value)) {
*object = (RAS_MeshObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String( PyString_AsString(value) ));
if (*object) {
return true;
} else {
PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_MeshProxy in this scene", error_prefix, PyString_AsString(value));
return false;
}
}
if (PyObject_TypeCheck(value, &KX_MeshProxy::Type)) {
KX_MeshProxy *kx_mesh = static_cast<KX_MeshProxy*>BGE_PROXY_REF(value);
/* sets the error */
if (*object==NULL) {
PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
return false;
}
*object = kx_mesh->GetMesh();
return true;
}
*object = NULL;
if (py_none_ok) {
PyErr_Format(PyExc_TypeError, "%s, expect a KX_MeshProxy, a string or None", error_prefix);
} else {
PyErr_Format(PyExc_TypeError, "%s, expect a KX_MeshProxy or a string", error_prefix);
}
return false;
}

View File

@@ -31,6 +31,9 @@
#include "SCA_IObject.h" #include "SCA_IObject.h"
/* 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 SCA_IObject
{ {
Py_Header; Py_Header;

View File

@@ -192,7 +192,7 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE
KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self); KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
KX_GameObject *gameobj; KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator"))
return 1; // ConvertPythonToGameObject sets the error return 1; // ConvertPythonToGameObject sets the error
if (actuator->m_ob != NULL) if (actuator->m_ob != NULL)
@@ -226,7 +226,7 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* value) {
ShowDeprecationWarning("setObject()", "the object property"); ShowDeprecationWarning("setObject()", "the object property");
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_ParentActuator"))
return NULL; // ConvertPythonToGameObject sets the error return NULL; // ConvertPythonToGameObject sets the error
if (m_ob != NULL) if (m_ob != NULL)

View File

@@ -44,6 +44,7 @@
#include "ListValue.h" #include "ListValue.h"
#include "KX_Python.h" #include "KX_Python.h"
#include "KX_PyMath.h"
bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
{ {
@@ -74,6 +75,39 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
return false; return false;
} }
bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix)
{
MT_Matrix3x3 rot;
int size= PySequence_Size(pyval);
if (size == 4)
{
MT_Quaternion qrot;
if (PyVecTo(pyval, qrot))
{
rot.setRotation(qrot);
return true;
}
}
else if (size == 3) {
/* 3x3 matrix or euler */
MT_Vector3 erot;
if (PyVecTo(pyval, erot))
{
rot.setEuler(erot);
return true;
}
PyErr_Clear();
if (PyMatTo(pyval, rot))
{
return true;
}
}
PyErr_Format(PyExc_TypeError, "%s, could not set the orientation from a 3x3 matrix, quaternion or euler sequence", error_prefix);
return false;
}
PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) PyObject* PyObjectFrom(const MT_Matrix4x4 &mat)
{ {

View File

@@ -145,6 +145,8 @@ bool PyVecTo(PyObject* pyval, T& vec)
return false; return false;
} }
bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix);
/** /**
* Converts an MT_Matrix4x4 to a python object. * Converts an MT_Matrix4x4 to a python object.
*/ */

View File

@@ -1357,14 +1357,17 @@ void setSandbox(TPythonSecurityLevel level)
/** /**
* Python is not initialised. * Python is not initialised.
*/ */
PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie) PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv)
{ {
STR_String pname = progname; STR_String pname = progname;
Py_SetProgramName(pname.Ptr()); Py_SetProgramName(pname.Ptr());
Py_NoSiteFlag=1; Py_NoSiteFlag=1;
Py_FrozenFlag=1; Py_FrozenFlag=1;
Py_Initialize(); Py_Initialize();
if(argv) /* browser plugins dont currently set this */
PySys_SetArgv(argc, argv);
//importBlenderModules() //importBlenderModules()
setSandbox(level); setSandbox(level);

View File

@@ -43,7 +43,7 @@ extern bool gUseVisibilityTemp;
PyObject* initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene* ketsjiscene); PyObject* initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene* ketsjiscene);
PyObject* initGameKeys(); PyObject* initGameKeys();
PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas); PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie); PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie, int argc, char** argv);
PyObject* initMathutils(); PyObject* initMathutils();
PyObject* initBGL(); PyObject* initBGL();
PyObject* initVideoTexture(void); PyObject* initVideoTexture(void);

View File

@@ -231,7 +231,7 @@ int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYAT
KX_SCA_AddObjectActuator* actuator = static_cast<KX_SCA_AddObjectActuator*>(self); KX_SCA_AddObjectActuator* actuator = static_cast<KX_SCA_AddObjectActuator*>(self);
KX_GameObject *gameobj; KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SCA_AddObjectActuator"))
return 1; // ConvertPythonToGameObject sets the error return 1; // ConvertPythonToGameObject sets the error
if (actuator->m_OriginalObject != NULL) if (actuator->m_OriginalObject != NULL)
@@ -277,7 +277,7 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* value)
ShowDeprecationWarning("setObject()", "the object property"); ShowDeprecationWarning("setObject()", "the object property");
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_SCA_AddObjectActuator"))
return NULL; // ConvertPythonToGameObject sets the error return NULL; // ConvertPythonToGameObject sets the error
if (m_OriginalObject != NULL) if (m_OriginalObject != NULL)

View File

@@ -116,22 +116,12 @@ PyObject* KX_SCA_ReplaceMeshActuator::pyattr_get_mesh(void *self, const struct K
int KX_SCA_ReplaceMeshActuator::pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) int KX_SCA_ReplaceMeshActuator::pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{ {
KX_SCA_ReplaceMeshActuator* actuator = static_cast<KX_SCA_ReplaceMeshActuator*>(self); KX_SCA_ReplaceMeshActuator* actuator = static_cast<KX_SCA_ReplaceMeshActuator*>(self);
if (value == Py_None) { RAS_MeshObject* new_mesh;
actuator->m_mesh = NULL;
} else if (PyString_Check(value)) { if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator"))
void* mesh = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(PyString_AsString(value)));
if (mesh==NULL) {
PyErr_SetString(PyExc_ValueError, "actuator.mesh = string: Replace Mesh Actuator, mesh name given does not exist");
return 1;
}
actuator->m_mesh= (class RAS_MeshObject*)mesh;
} else if PyObject_TypeCheck(value, &KX_MeshProxy::Type) {
KX_MeshProxy* proxy = (KX_MeshProxy*)value;
actuator->m_mesh= proxy->GetMesh();
} else {
PyErr_SetString(PyExc_ValueError, "actuator.mesh = value: Replace Mesh Actuator, expected the mesh name, a KX_MeshProxy or None");
return 1; return 1;
}
actuator->m_mesh = new_mesh;
return 0; return 0;
} }
@@ -144,23 +134,12 @@ const char KX_SCA_ReplaceMeshActuator::SetMesh_doc[] =
PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* value) PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* value)
{ {
ShowDeprecationWarning("setMesh()", "the mesh property"); ShowDeprecationWarning("setMesh()", "the mesh property");
if (value == Py_None) { RAS_MeshObject* new_mesh;
m_mesh = NULL;
} else {
char* meshname = PyString_AsString(value);
if (!meshname) {
PyErr_SetString(PyExc_ValueError, "Expected the name of a mesh or None");
return NULL;
}
void* mesh = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname));
if (mesh==NULL) {
PyErr_SetString(PyExc_ValueError, "The mesh name given does not exist");
return NULL;
}
m_mesh= (class RAS_MeshObject*)mesh;
}
if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator"))
return NULL;
m_mesh = new_mesh;
Py_RETURN_NONE; Py_RETURN_NONE;
} }

View File

@@ -1747,8 +1747,8 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject,
if (!PyArg_ParseTuple(args, "OO|i:addObject", &pyob, &pyother, &time)) if (!PyArg_ParseTuple(args, "OO|i:addObject", &pyob, &pyother, &time))
return NULL; return NULL;
if (!ConvertPythonToGameObject(pyob, &ob, false) if ( !ConvertPythonToGameObject(pyob, &ob, false, "scene.addObject(object, other, time): KX_Scene (first argument)") ||
|| !ConvertPythonToGameObject(pyother, &other, false)) !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") )
return NULL; return NULL;

View File

@@ -540,50 +540,16 @@ int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRI
MT_Matrix3x3 rot; MT_Matrix3x3 rot;
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self); KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
if (!PySequence_Check(value)) { /* if value is not a sequence PyOrientationTo makes an error */
PyErr_SetString(PyExc_AttributeError, "value = actuator.orientation: KX_SoundActuator, expected a sequence"); if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator"))
return 1; return NULL;
}
if (!actuator->m_soundObject) if (!actuator->m_soundObject)
return 0; /* Since not having m_soundObject didn't do anything in the old version, return 0; /* Since not having m_soundObject didn't do anything in the old version,
* it probably should be kept that way */ * it probably should be kept that way */
if (PyMatTo(value, rot)) actuator->m_soundObject->SetOrientation(rot);
{ return 0;
actuator->m_soundObject->SetOrientation(rot);
return 0;
}
PyErr_Clear();
if (PySequence_Size(value) == 4)
{
MT_Quaternion qrot;
if (PyVecTo(value, qrot))
{
rot.setRotation(qrot);
actuator->m_soundObject->SetOrientation(rot);
return 0;
}
return 1;
}
if (PySequence_Size(value) == 3)
{
MT_Vector3 erot;
if (PyVecTo(value, erot))
{
rot.setEuler(erot);
actuator->m_soundObject->SetOrientation(rot);
return 0;
}
return 1;
}
PyErr_SetString(PyExc_AttributeError, "could not set the orientation from a 3x3 matrix, quaternion or euler sequence");
return 1;
} }
// Deprecated -----> // Deprecated ----->

View File

@@ -489,7 +489,7 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT
KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self); KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self);
KX_GameObject *gameobj; KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_TrackToActuator"))
return 1; // ConvertPythonToGameObject sets the error return 1; // ConvertPythonToGameObject sets the error
if (actuator->m_object != NULL) if (actuator->m_object != NULL)
@@ -525,7 +525,7 @@ PyObject* KX_TrackToActuator::PySetObject(PyObject* value)
ShowDeprecationWarning("setObject()", "the object property"); ShowDeprecationWarning("setObject()", "the object property");
if (!ConvertPythonToGameObject(value, &gameobj, true)) if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_TrackToActuator"))
return NULL; // ConvertPythonToGameObject sets the error return NULL; // ConvertPythonToGameObject sets the error
if (m_object != NULL) if (m_object != NULL)

View File

@@ -47,14 +47,15 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* args)
if (PyArg_ParseTuple(args,"OOOOffi:addWheel",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering)) if (PyArg_ParseTuple(args,"OOOOffi:addWheel",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering))
{ {
KX_GameObject *gameOb; KX_GameObject *gameOb;
if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false)) if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false, "vehicle.addWheel(...): KX_VehicleWrapper (first argument)"))
return NULL; return NULL;
if (gameOb->GetSGNode()) if (gameOb->GetSGNode())
{ {
PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode()); PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
/* TODO - no error checking here! - bad juju */
MT_Vector3 attachPos,attachDir,attachAxle; MT_Vector3 attachPos,attachDir,attachAxle;
PyVecTo(pylistPos,attachPos); PyVecTo(pylistPos,attachPos);
PyVecTo(pylistDir,attachDir); PyVecTo(pylistDir,attachDir);

View File

@@ -5,15 +5,23 @@ class KX_VehicleWrapper: # (PyObjectPlus)
All placeholders have a __ prefix All placeholders have a __ prefix
""" """
def __addWheel(val): def addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering):
""" """
TODO - Description TODO - Description
@param val: the starting frame of the animation @param wheel: The object to use as a wheel.
@type val: float @type wheel: L{KX_GameObject<KX_GameObject.KX_GameObject>} or a KX_GameObject name
@param attachPos: The position that this wheel will attach to.
@rtype: integer @type attachPos: vector of 3 floats
@return: TODO Description @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(val): def __applyBraking(val):

View File

@@ -8,13 +8,17 @@ class SCA_ILogicBrick:
@ivar executePriority: This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first). @ivar executePriority: This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first).
@type executePriority: int @type executePriority: int
@ivar owner: The game object this logic brick is attached to (read only).
@type owner: L{KX_GameObject<KX_GameObject.KX_GameObject>} or None in exceptional cases.
""" """
def getOwner(): def getOwner():
""" """
Gets the game object associated with this logic brick. Gets the game object associated with this logic brick.
@rtype: L{KX_GameObject} Deprecated: Use the "owner" property instead.
@rtype: L{KX_GameObject<KX_GameObject.KX_GameObject>}
""" """
#--The following methods are deprecated-- #--The following methods are deprecated--