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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2009-05-11 22:26:47 +0400
committerDalai Felinto <dfelinto@gmail.com>2009-05-11 22:26:47 +0400
commitb8ba7c2be521a19ca952f4033d39f8323f494abe (patch)
tree6c3fe995ef593667a6b2d202c72bc7a0220605e0 /source/gameengine/Ketsji/KX_PythonInit.cpp
parentc3fbb17e030c77cf94d1646dabd0e5af4150a02b (diff)
parent0c6ec76a4c7de61e84cc4dddbbda1698b7bf2a4b (diff)
merge -r 19528-HEAD (20156)
starting dome test period again :) (i.e. not over committing in the trunk)
Diffstat (limited to 'source/gameengine/Ketsji/KX_PythonInit.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp785
1 files changed, 692 insertions, 93 deletions
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index f065eb29c44..57f736a6c09 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -49,24 +49,32 @@
#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"
#include "SCA_PropertySensor.h"
#include "SCA_RandomActuator.h"
+#include "SCA_KeyboardSensor.h" /* IsPrintable, ToCharacter */
#include "KX_ConstraintActuator.h"
#include "KX_IpoActuator.h"
#include "KX_SoundActuator.h"
+#include "KX_StateActuator.h"
#include "BL_ActionActuator.h"
#include "RAS_IRasterizer.h"
#include "RAS_ICanvas.h"
#include "RAS_BucketManager.h"
+#include "RAS_2DFilterManager.h"
#include "MT_Vector3.h"
#include "MT_Point3.h"
#include "ListValue.h"
#include "KX_Scene.h"
#include "SND_DeviceManager.h"
+#include "NG_NetworkScene.h" //Needed for sendMessage()
+
#include "BL_Shader.h"
#include "KX_PyMath.h"
@@ -75,8 +83,17 @@
#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 "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 "BGL.h"
+#endif
}
#include "marshal.h" /* python header for loading/saving dicts */
@@ -95,7 +112,7 @@ 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;
@@ -103,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 PyObject *gp_OrigPythonSysPath= NULL;
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
{
@@ -112,9 +130,9 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons
/* Macro for building the keyboard translation */
//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name))
-#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(name))
+#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name)); Py_DECREF(item)
/* For the defines for types from logic bricks, we do stuff explicitly... */
-#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, PyInt_FromLong(name2))
+#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name2)); Py_DECREF(item)
// temporarily python stuff, will be put in another place later !
@@ -157,7 +175,7 @@ static PyObject* gPyExpandPath(PyObject*, PyObject* args)
char expanded[FILE_MAXDIR + FILE_MAXFILE];
char* filename;
- if (!PyArg_ParseTuple(args,"s",&filename))
+ if (!PyArg_ParseTuple(args,"s:ExpandPath",&filename))
return NULL;
BLI_strncpy(expanded, filename, FILE_MAXDIR + FILE_MAXFILE);
@@ -165,6 +183,28 @@ static PyObject* gPyExpandPath(PyObject*, PyObject* args)
return PyString_FromString(expanded);
}
+static char gPySendMessage_doc[] =
+"sendMessage(subject, [body, to, from])\n\
+sends a message in same manner as a message actuator\
+subject = Subject of the message\
+body = Message body\
+to = Name of object to send the message to\
+from = Name of object to sned the string from";
+
+static PyObject* gPySendMessage(PyObject*, PyObject* args)
+{
+ char* subject;
+ char* body = (char *)"";
+ char* to = (char *)"";
+ char* from = (char *)"";
+
+ if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to, &from))
+ return NULL;
+
+ gp_KetsjiScene->GetNetworkScene()->SendMessage(to, from, subject, body);
+
+ Py_RETURN_NONE;
+}
static bool usedsp = false;
@@ -187,13 +227,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));
}
}
@@ -241,7 +281,7 @@ static PyObject* gPyStopDSP(PyObject*, PyObject* args)
static PyObject* gPySetLogicTicRate(PyObject*, PyObject* args)
{
float ticrate;
- if (!PyArg_ParseTuple(args, "f", &ticrate))
+ if (!PyArg_ParseTuple(args, "f:setLogicTicRate", &ticrate))
return NULL;
KX_KetsjiEngine::SetTicRate(ticrate);
@@ -253,10 +293,25 @@ 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;
- if (!PyArg_ParseTuple(args, "f", &ticrate))
+ if (!PyArg_ParseTuple(args, "f:setPhysicsTicRate", &ticrate))
return NULL;
PHY_GetActiveEnvironment()->setFixedTimeStep(true,ticrate);
@@ -266,7 +321,7 @@ static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args)
static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args)
{
int debugMode;
- if (!PyArg_ParseTuple(args, "i", &debugMode))
+ if (!PyArg_ParseTuple(args, "i:setPhysicsDebug", &debugMode))
return NULL;
PHY_GetActiveEnvironment()->setDebugMode(debugMode);
@@ -294,7 +349,7 @@ static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args)
DIR *dp;
struct dirent *dirp;
- if (!PyArg_ParseTuple(args, "|s", &searchpath))
+ if (!PyArg_ParseTuple(args, "|s:getBlendFileList", &searchpath))
return NULL;
list = PyList_New(0);
@@ -330,8 +385,7 @@ static STR_String gPyGetCurrentScene_doc =
"Gets a reference to the current scene.\n";
static PyObject* gPyGetCurrentScene(PyObject* self)
{
- Py_INCREF(gp_KetsjiScene);
- return (PyObject*) gp_KetsjiScene;
+ return gp_KetsjiScene->GetProxy();
}
static STR_String gPyGetSceneList_doc =
@@ -340,7 +394,6 @@ static STR_String gPyGetSceneList_doc =
static PyObject* gPyGetSceneList(PyObject* self)
{
KX_KetsjiEngine* m_engine = KX_GetActiveEngine();
- //CListValue* list = new CListValue();
PyObject* list;
KX_SceneList* scenes = m_engine->CurrentScenes();
int numScenes = scenes->size();
@@ -351,13 +404,10 @@ static PyObject* gPyGetSceneList(PyObject* self)
for (i=0;i<numScenes;i++)
{
KX_Scene* scene = scenes->at(i);
- //list->Add(scene);
- PyList_SET_ITEM(list, i, scene);
- Py_INCREF(scene);
-
+ PyList_SET_ITEM(list, i, scene->GetProxy());
}
- return (PyObject*)list;
+ return list;
}
static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
@@ -434,6 +484,7 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
static struct PyMethodDef game_methods[] = {
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (PY_METHODCHAR)gPyExpandPath_doc},
+ {"sendMessage", (PyCFunction)gPySendMessage, METH_VARARGS, (PY_METHODCHAR)gPySendMessage_doc},
{"getCurrentController",
(PyCFunction) SCA_PythonController::sPyGetCurrentController,
METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::sPyGetCurrentController__doc__},
@@ -448,6 +499,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"},
@@ -459,6 +512,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));
@@ -479,7 +653,7 @@ bool gUseVisibilityTemp = false;
static PyObject* gPyEnableVisibility(PyObject*, PyObject* args)
{
int visible;
- if (!PyArg_ParseTuple(args,"i",&visible))
+ if (!PyArg_ParseTuple(args,"i:enableVisibility",&visible))
return NULL;
gUseVisibilityTemp = (visible != 0);
@@ -491,7 +665,7 @@ static PyObject* gPyEnableVisibility(PyObject*, PyObject* args)
static PyObject* gPyShowMouse(PyObject*, PyObject* args)
{
int visible;
- if (!PyArg_ParseTuple(args,"i",&visible))
+ if (!PyArg_ParseTuple(args,"i:showMouse",&visible))
return NULL;
if (visible)
@@ -512,7 +686,7 @@ static PyObject* gPyShowMouse(PyObject*, PyObject* args)
static PyObject* gPySetMousePosition(PyObject*, PyObject* args)
{
int x,y;
- if (!PyArg_ParseTuple(args,"ii",&x,&y))
+ if (!PyArg_ParseTuple(args,"ii:setMousePosition",&x,&y))
return NULL;
if (gp_Canvas)
@@ -524,11 +698,11 @@ static PyObject* gPySetMousePosition(PyObject*, PyObject* args)
static PyObject* gPySetEyeSeparation(PyObject*, PyObject* args)
{
float sep;
- if (!PyArg_ParseTuple(args, "f", &sep))
+ if (!PyArg_ParseTuple(args, "f:setEyeSeparation", &sep))
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setEyeSeparation(float), Rasterizer not available");
return NULL;
}
@@ -537,10 +711,10 @@ static PyObject* gPySetEyeSeparation(PyObject*, PyObject* args)
Py_RETURN_NONE;
}
-static PyObject* gPyGetEyeSeparation(PyObject*, PyObject*, PyObject*)
+static PyObject* gPyGetEyeSeparation(PyObject*)
{
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.getEyeSeparation(), Rasterizer not available");
return NULL;
}
@@ -550,11 +724,11 @@ static PyObject* gPyGetEyeSeparation(PyObject*, PyObject*, PyObject*)
static PyObject* gPySetFocalLength(PyObject*, PyObject* args)
{
float focus;
- if (!PyArg_ParseTuple(args, "f", &focus))
+ if (!PyArg_ParseTuple(args, "f:setFocalLength", &focus))
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setFocalLength(float), Rasterizer not available");
return NULL;
}
@@ -566,7 +740,7 @@ static PyObject* gPySetFocalLength(PyObject*, PyObject* args)
static PyObject* gPyGetFocalLength(PyObject*, PyObject*, PyObject*)
{
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.getFocalLength(), Rasterizer not available");
return NULL;
}
@@ -599,7 +773,7 @@ static PyObject* gPySetMistColor(PyObject*, PyObject* value)
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
return NULL;
}
gp_Rasterizer->SetFogColor(vec[0], vec[1], vec[2]);
@@ -607,17 +781,28 @@ 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)
{
float miststart;
- if (!PyArg_ParseTuple(args,"f",&miststart))
+ if (!PyArg_ParseTuple(args,"f:setMistStart",&miststart))
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistStart(float), Rasterizer not available");
return NULL;
}
@@ -632,11 +817,11 @@ static PyObject* gPySetMistEnd(PyObject*, PyObject* args)
{
float mistend;
- if (!PyArg_ParseTuple(args,"f",&mistend))
+ if (!PyArg_ParseTuple(args,"f:setMistEnd",&mistend))
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistEnd(float), Rasterizer not available");
return NULL;
}
@@ -654,7 +839,7 @@ static PyObject* gPySetAmbientColor(PyObject*, PyObject* value)
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setAmbientColor(color), Rasterizer not available");
return NULL;
}
gp_Rasterizer->SetAmbientColor(vec[0], vec[1], vec[2]);
@@ -668,7 +853,7 @@ static PyObject* gPySetAmbientColor(PyObject*, PyObject* value)
static PyObject* gPyMakeScreenshot(PyObject*, PyObject* args)
{
char* filename;
- if (!PyArg_ParseTuple(args,"s",&filename))
+ if (!PyArg_ParseTuple(args,"s:makeScreenshot",&filename))
return NULL;
if (gp_Canvas)
@@ -682,11 +867,11 @@ static PyObject* gPyMakeScreenshot(PyObject*, PyObject* args)
static PyObject* gPyEnableMotionBlur(PyObject*, PyObject* args)
{
float motionblurvalue;
- if (!PyArg_ParseTuple(args,"f",&motionblurvalue))
+ if (!PyArg_ParseTuple(args,"f:enableMotionBlur",&motionblurvalue))
return NULL;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.enableMotionBlur(float), Rasterizer not available");
return NULL;
}
@@ -695,10 +880,10 @@ 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 not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.disableMotionBlur(), Rasterizer not available");
return NULL;
}
@@ -732,13 +917,13 @@ static PyObject* gPySetGLSLMaterialSetting(PyObject*,
char *setting;
int enable, flag, fileflags;
- if (!PyArg_ParseTuple(args,"si",&setting,&enable))
+ if (!PyArg_ParseTuple(args,"si:setGLSLMaterialSetting",&setting,&enable))
return NULL;
flag = getGLSLSettingFlag(setting);
if (flag==-1) {
- PyErr_SetString(PyExc_ValueError, "glsl setting is not known");
+ PyErr_SetString(PyExc_ValueError, "Rasterizer.setGLSLMaterialSetting(string): glsl setting is not known");
return NULL;
}
@@ -751,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;
@@ -773,13 +959,13 @@ static PyObject* gPyGetGLSLMaterialSetting(PyObject*,
char *setting;
int enabled = 0, flag;
- if (!PyArg_ParseTuple(args,"s",&setting))
+ if (!PyArg_ParseTuple(args,"s:getGLSLMaterialSetting",&setting))
return NULL;
flag = getGLSLSettingFlag(setting);
if (flag==-1) {
- PyErr_SetString(PyExc_ValueError, "glsl setting is not known");
+ PyErr_SetString(PyExc_ValueError, "Rasterizer.getGLSLMaterialSetting(string): glsl setting is not known");
return NULL;
}
@@ -797,7 +983,7 @@ static PyObject* gPySetMaterialType(PyObject*,
{
int flag, type;
- if (!PyArg_ParseTuple(args,"i",&type))
+ if (!PyArg_ParseTuple(args,"i:setMaterialType",&type))
return NULL;
if(type == KX_BLENDER_GLSL_MATERIAL)
@@ -807,7 +993,7 @@ static PyObject* gPySetMaterialType(PyObject*,
else if(type == KX_TEXFACE_MATERIAL)
flag = 0;
else {
- PyErr_SetString(PyExc_ValueError, "material type is not known");
+ PyErr_SetString(PyExc_ValueError, "Rasterizer.setMaterialType(int): material type is not known");
return NULL;
}
@@ -821,7 +1007,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;
@@ -838,11 +1024,11 @@ static PyObject* gPyDrawLine(PyObject*, PyObject* args)
PyObject* ob_color;
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.drawLine(obFrom, obTo, color): Rasterizer not available");
return NULL;
}
- if (!PyArg_ParseTuple(args,"OOO",&ob_from,&ob_to,&ob_color))
+ if (!PyArg_ParseTuple(args,"OOO:drawLine",&ob_from,&ob_to,&ob_color))
return NULL;
MT_Vector3 from;
@@ -861,6 +1047,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,
@@ -875,15 +1067,16 @@ 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)"},
{"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"},
- {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_VARARGS, "get the eye separation for stereo mode"},
+ {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_NOARGS, "get the eye separation for stereo mode"},
{"setFocalLength", (PyCFunction) gPySetFocalLength, METH_VARARGS, "set the focal length for stereo mode"},
{"getFocalLength", (PyCFunction) gPyGetFocalLength, METH_VARARGS, "get the focal length for stereo mode"},
{"setMaterialMode",(PyCFunction) gPySetMaterialType,
@@ -909,32 +1102,64 @@ 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
{
PyObject* m;
PyObject* d;
-
+ PyObject* item; /* temp PyObject* storage */
+
gp_KetsjiEngine = engine;
gp_KetsjiScene = scene;
gUseVisibilityTemp=false;
-
- // Create the module and add the functions
- m = Py_InitModule4("GameLogic", game_methods,
- GameLogic_module_documentation,
- (PyObject*)NULL,PYTHON_API_VERSION);
-
+
+ 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 */
+ 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);
// can be overwritten later for gameEngine instances that can load new blend files and re-initialize this module
// for now its safe to make sure it exists for other areas such as the web plugin
- PyDict_SetItemString(d, "globalDict", PyDict_New());
+
+ PyDict_SetItemString(d, "globalDict", item=PyDict_New()); Py_DECREF(item);
ErrorObject = PyString_FromString("GameLogic.error");
PyDict_SetItemString(d, "error", ErrorObject);
+ Py_DECREF(ErrorObject);
// XXXX Add constants here
/* To use logic bricks, we need some sort of constants. Here, we associate */
@@ -967,6 +1192,12 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHPX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHPZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHNX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHNZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ);
/* 4. Ipo actuator, simple part */
KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY, KX_IpoActuator::KX_ACT_IPO_PLAY);
@@ -1089,6 +1320,73 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_DYN_DISABLE_RIGID_BODY, KX_SCA_DynamicActuator::KX_DYN_DISABLE_RIGID_BODY);
KX_MACRO_addTypesToDict(d, KX_DYN_SET_MASS, KX_SCA_DynamicActuator::KX_DYN_SET_MASS);
+ /* Input & Mouse Sensor */
+ KX_MACRO_addTypesToDict(d, KX_INPUT_NONE, SCA_InputEvent::KX_NO_INPUTSTATUS);
+ KX_MACRO_addTypesToDict(d, KX_INPUT_JUST_ACTIVATED, SCA_InputEvent::KX_JUSTACTIVATED);
+ KX_MACRO_addTypesToDict(d, KX_INPUT_ACTIVE, SCA_InputEvent::KX_ACTIVE);
+ KX_MACRO_addTypesToDict(d, KX_INPUT_JUST_RELEASED, SCA_InputEvent::KX_JUSTRELEASED);
+
+ KX_MACRO_addTypesToDict(d, KX_MOUSE_BUT_LEFT, SCA_IInputDevice::KX_LEFTMOUSE);
+ KX_MACRO_addTypesToDict(d, KX_MOUSE_BUT_MIDDLE, SCA_IInputDevice::KX_MIDDLEMOUSE);
+ KX_MACRO_addTypesToDict(d, KX_MOUSE_BUT_RIGHT, SCA_IInputDevice::KX_RIGHTMOUSE);
+
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_ENABLED, RAS_2DFilterManager::RAS_2DFILTER_ENABLED);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_DISABLED, RAS_2DFilterManager::RAS_2DFILTER_DISABLED);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_NOFILTER, RAS_2DFilterManager::RAS_2DFILTER_NOFILTER);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_MOTIONBLUR, RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_BLUR, RAS_2DFilterManager::RAS_2DFILTER_BLUR);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_SHARPEN, RAS_2DFilterManager::RAS_2DFILTER_SHARPEN);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_DILATION, RAS_2DFilterManager::RAS_2DFILTER_DILATION);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_EROSION, RAS_2DFilterManager::RAS_2DFILTER_EROSION);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_LAPLACIAN, RAS_2DFilterManager::RAS_2DFILTER_LAPLACIAN);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_SOBEL, RAS_2DFilterManager::RAS_2DFILTER_SOBEL);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_PREWITT, RAS_2DFilterManager::RAS_2DFILTER_PREWITT);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_GRAYSCALE, RAS_2DFilterManager::RAS_2DFILTER_GRAYSCALE);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_SEPIA, RAS_2DFilterManager::RAS_2DFILTER_SEPIA);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_INVERT, RAS_2DFilterManager::RAS_2DFILTER_INVERT);
+ KX_MACRO_addTypesToDict(d, RAS_2DFILTER_CUSTOMFILTER, RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER);
+
+ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYSTOP, KX_SoundActuator::KX_SOUNDACT_PLAYSTOP);
+ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_PLAYEND, KX_SoundActuator::KX_SOUNDACT_PLAYEND);
+ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPSTOP, KX_SoundActuator::KX_SOUNDACT_LOOPSTOP);
+ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPEND, KX_SoundActuator:: KX_SOUNDACT_LOOPEND);
+ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL, KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL);
+ KX_MACRO_addTypesToDict(d, KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP, KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP);
+
+ KX_MACRO_addTypesToDict(d, KX_STATE_OP_CPY, KX_StateActuator::OP_CPY);
+ KX_MACRO_addTypesToDict(d, KX_STATE_OP_SET, KX_StateActuator::OP_SET);
+ KX_MACRO_addTypesToDict(d, KX_STATE_OP_CLR, KX_StateActuator::OP_CLR);
+ KX_MACRO_addTypesToDict(d, KX_STATE_OP_NEG, KX_StateActuator::OP_NEG);
+
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_NORMAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_NORMAL);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_MATERIAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_MATERIAL);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_PERMANENT, KX_ConstraintActuator::KX_ACT_CONSTRAINT_PERMANENT);
+ KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_DISTANCE, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DISTANCE);
+ 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())
{
@@ -1107,11 +1405,6 @@ PyObject *KXpy_open(PyObject *self, PyObject *args) {
return NULL;
}
-PyObject *KXpy_reload(PyObject *self, PyObject *args) {
- PyErr_SetString(PyExc_RuntimeError, "Sandbox: reload() function disabled!\nGame Scripts should not use this function.");
- return NULL;
-}
-
PyObject *KXpy_file(PyObject *self, PyObject *args) {
PyErr_SetString(PyExc_RuntimeError, "Sandbox: file() function disabled!\nGame Scripts should not use this function.");
return NULL;
@@ -1130,6 +1423,7 @@ PyObject *KXpy_compile(PyObject *self, PyObject *args) {
PyObject *KXpy_import(PyObject *self, PyObject *args)
{
char *name;
+ int found;
PyObject *globals = NULL;
PyObject *locals = NULL;
PyObject *fromlist = NULL;
@@ -1159,14 +1453,45 @@ 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, "Rasterizer") || !strcmp(name, "Mathutils") || !strcmp(name, "BGL") || !strcmp(name, "Geometry")) {
return PyImport_ImportModuleEx(name, globals, locals, fromlist);
}
-
- PyErr_Format(PyExc_ImportError,
- "Import of external Module %.20s not allowed.", name);
+
+ /* Import blender texts as python modules */
+ m= bpy_text_import(name, &found);
+ if (m)
+ return m;
+
+ if(found==0) /* if its found but could not import then it has its own error */
+ PyErr_Format(PyExc_ImportError, "Import of external Module %.20s not allowed.", name);
+
+ return NULL;
+
+}
+
+PyObject *KXpy_reload(PyObject *self, PyObject *args) {
+
+ /* Used to be sandboxed, bettet to allow importing of internal text only */
+#if 0
+ PyErr_SetString(PyExc_RuntimeError, "Sandbox: reload() function disabled!\nGame Scripts should not use this function.");
return NULL;
+#endif
+ int found;
+ PyObject *module = NULL;
+ PyObject *newmodule = NULL;
+ /* check for a module arg */
+ if( !PyArg_ParseTuple( args, "O:bpy_reload_meth", &module ) )
+ return NULL;
+
+ newmodule= bpy_text_reimport( module, &found );
+ if (newmodule)
+ return newmodule;
+
+ if (found==0) /* if its found but could not import then it has its own error */
+ PyErr_SetString(PyExc_ImportError, "reload(module): failed to reload from blenders internal text");
+
+ return newmodule;
}
/* override python file type functions */
@@ -1201,18 +1526,18 @@ void setSandbox(TPythonSecurityLevel level)
{
PyObject *m = PyImport_AddModule("__builtin__");
PyObject *d = PyModule_GetDict(m);
-
+ PyObject *item;
switch (level) {
case psl_Highest:
//if (!g_security) {
//g_oldopen = PyDict_GetItemString(d, "open");
// functions we cant trust
- PyDict_SetItemString(d, "open", PyCFunction_New(meth_open, NULL));
- PyDict_SetItemString(d, "reload", PyCFunction_New(meth_reload, NULL));
- PyDict_SetItemString(d, "file", PyCFunction_New(meth_file, NULL));
- PyDict_SetItemString(d, "execfile", PyCFunction_New(meth_execfile, NULL));
- PyDict_SetItemString(d, "compile", PyCFunction_New(meth_compile, NULL));
+ PyDict_SetItemString(d, "open", item=PyCFunction_New(meth_open, NULL)); Py_DECREF(item);
+ PyDict_SetItemString(d, "reload", item=PyCFunction_New(meth_reload, NULL)); Py_DECREF(item);
+ PyDict_SetItemString(d, "file", item=PyCFunction_New(meth_file, NULL)); Py_DECREF(item);
+ PyDict_SetItemString(d, "execfile", item=PyCFunction_New(meth_execfile, NULL)); Py_DECREF(item);
+ PyDict_SetItemString(d, "compile", item=PyCFunction_New(meth_compile, NULL)); Py_DECREF(item);
// our own import
PyDict_SetItemString(d, "__import__", PyCFunction_New(meth_import, NULL));
@@ -1241,59 +1566,246 @@ void setSandbox(TPythonSecurityLevel level)
}
*/
default:
+ /* Allow importing internal text, from bpy_internal_import.py */
+ PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item);
+ PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item);
break;
}
}
+/* 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 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
+ *
+ * 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);
+
+ 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)
+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());
+#endif
Py_NoSiteFlag=1;
Py_FrozenFlag=1;
Py_Initialize();
-
+
+#if (PY_VERSION_HEX < 0x03000000)
+ if(argv && first_time) /* browser plugins dont currently set this */
+ PySys_SetArgv(argc, argv);
+#endif
//importBlenderModules()
setSandbox(level);
initPyTypes();
-
+
+ bpy_import_main_set(maggie);
+
+ initPySysPath(maggie);
+
+ first_time = false;
+
+ PyObjectPlus::ClearDeprecationWarning();
+
PyObject* moduleobj = PyImport_AddModule("__main__");
return PyModule_GetDict(moduleobj);
}
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);
+ PyObjectPlus::ClearDeprecationWarning();
}
+
+
/**
* Python is already initialized.
*/
-PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level)
+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;
setSandbox(level);
initPyTypes();
+
+ bpy_import_main_set(maggie);
+
+ initPySysPath(maggie);
+
+ /* clear user defined modules that may contain data from the last run */
+ clearGameModules();
+ PyObjectPlus::NullDeprecationWarning();
+
PyObject* moduleobj = PyImport_AddModule("__main__");
return PyModule_GetDict(moduleobj);
}
-
-
-void exitGamePythonScripting()
+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 */
+ bpy_import_main_set(NULL);
+ PyObjectPlus::ClearDeprecationWarning();
+}
+
+
+#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)
{
@@ -1303,16 +1815,33 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
PyObject* m;
PyObject* d;
-
- // Create the module and add the functions
- m = Py_InitModule4("Rasterizer", rasterizer_methods,
+ PyObject* item;
+
+ /* 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);
+#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);
ErrorObject = PyString_FromString("Rasterizer.error");
PyDict_SetItemString(d, "error", ErrorObject);
+ Py_DECREF(ErrorObject);
/* needed for get/setMaterialType */
KX_MACRO_addTypesToDict(d, KX_TEXFACE_MATERIAL, KX_TEXFACE_MATERIAL);
@@ -1341,7 +1870,7 @@ static char GameKeys_module_documentation[] =
;
static char gPyEventToString_doc[] =
-"Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
+"EventToString(event) - Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
;
static PyObject* gPyEventToString(PyObject*, PyObject* value)
@@ -1356,7 +1885,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;
}
@@ -1364,28 +1898,78 @@ static PyObject* gPyEventToString(PyObject*, PyObject* value)
PyErr_Clear(); // incase there was an error clearing
Py_DECREF(mod);
- if (!ret) PyErr_SetString(PyExc_ValueError, "expected a valid int keyboard event");
+ if (!ret) PyErr_SetString(PyExc_ValueError, "GameKeys.EventToString(int): expected a valid int keyboard event");
else Py_INCREF(ret);
return ret;
}
+static char gPyEventToCharacter_doc[] =
+"EventToCharacter(event, is_shift) - Take a valid event from the GameKeys module or Keyboard Sensor and return a character"
+;
+
+static PyObject* gPyEventToCharacter(PyObject*, PyObject* args)
+{
+ int event, shift;
+ if (!PyArg_ParseTuple(args,"ii:EventToCharacter", &event, &shift))
+ return NULL;
+
+ if(IsPrintable(event)) {
+ char ch[2] = {'\0', '\0'};
+ ch[0] = ToCharacter(event, (bool)shift);
+ return PyString_FromString(ch);
+ }
+ else {
+ return PyString_FromString("");
+ }
+}
+
+
static struct PyMethodDef gamekeys_methods[] = {
+ {"EventToCharacter", (PyCFunction)gPyEventToCharacter, METH_VARARGS, (PY_METHODCHAR)gPyEventToCharacter_doc},
{"EventToString", (PyCFunction)gPyEventToString, METH_O, (PY_METHODCHAR)gPyEventToString_doc},
{ NULL, (PyCFunction) NULL, 0, NULL }
};
+#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()
{
PyObject* m;
PyObject* d;
-
- // Create the module and add the functions
- m = Py_InitModule4("GameKeys", gamekeys_methods,
+ PyObject* item;
+
+ /* 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);
+#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);
@@ -1505,7 +2089,6 @@ PyObject* initGameKeys()
KX_MACRO_addTypesToDict(d, PAGEDOWNKEY, SCA_IInputDevice::KX_PAGEDOWNKEY);
KX_MACRO_addTypesToDict(d, ENDKEY, SCA_IInputDevice::KX_ENDKEY);
-
// Check for errors
if (PyErr_Occurred())
{
@@ -1515,11 +2098,27 @@ PyObject* initGameKeys()
return d;
}
+#if PY_VERSION_HEX < 0x03000000
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
+}
+#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)
{
gp_KetsjiScene = scene;