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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-04-20 19:06:46 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-04-20 19:06:46 +0400
commit874c29cea8e6f9bc411fccf2d6f4cb07e94328d0 (patch)
tree5971e577cf7c02e05a1e37b5ad058c71a6744877 /source/gameengine/Ketsji
parent7555bfa793a2b0fc187c6211c56986f35b2d7b09 (diff)
parentc5bc4e4fb1a33eda8c31f2ea02e91f32f74c8fa5 (diff)
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323:HEAD
Notes: * blenderbuttons and ICON_SNAP_PEEL_OBJECT were not merged.
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp2
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp276
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h3
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt4
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp56
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h7
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp79
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h5
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp38
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h7
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.cpp113
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.h23
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp298
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h41
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp137
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h23
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp198
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h29
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.cpp37
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.h4
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp29
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp1819
-rw-r--r--source/gameengine/Ketsji/KX_Dome.h183
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp53
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.h6
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp1253
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h156
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h7
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp135
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.h24
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp191
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h9
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp146
-rw-r--r--source/gameengine/Ketsji/KX_Light.h5
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp223
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.h18
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.cpp18
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.h1
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp245
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h28
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp51
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h4
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp110
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h24
-rw-r--r--source/gameengine/Ketsji/KX_OdePhysicsController.h4
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp91
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.h14
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp54
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h12
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.cpp78
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.h4
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp270
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h17
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.cpp36
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.h33
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp347
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h5
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp233
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.h35
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp45
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.h4
-rw-r--r--source/gameengine/Ketsji/KX_RayCast.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp113
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h28
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp157
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h15
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp37
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.h13
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp22
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp82
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h7
-rw-r--r--source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h3
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp52
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.h9
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp274
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h45
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp158
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h18
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp382
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h65
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.cpp47
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.h13
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h5
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp83
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp107
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.h18
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp121
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.h34
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp171
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h6
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.cpp51
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.h12
-rw-r--r--source/gameengine/Ketsji/SConscript13
100 files changed, 7121 insertions, 2524 deletions
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 8ec463be6ff..3df483b0598 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -52,7 +52,7 @@ void BL_BlenderShader::SetProg(bool enable, double time)
{
if(VerifyShader()) {
if(enable)
- GPU_material_bind(GPU_material_from_blender(mBlenderScene, mMat), mLightLayer, ~0, time);
+ GPU_material_bind(GPU_material_from_blender(mBlenderScene, mMat), mLightLayer, mBlenderScene->lay, time);
else
GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat));
}
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index 60cb288436a..88d920043e0 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -729,9 +729,9 @@ void BL_Shader::SetUniform(int uniform, const int* val, int len)
}
-PyObject* BL_Shader::_getattr(const char *attr)
+PyObject* BL_Shader::py_getattro(PyObject *attr)
{
- _getattr_up(PyObjectPlus);
+ py_getattro_up(PyObjectPlus);
}
@@ -772,24 +772,28 @@ PyAttributeDef BL_Shader::Attributes[] = {
};
PyTypeObject BL_Shader::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"BL_Shader",
- sizeof(BL_Shader),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
0,
- __repr,
- 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 BL_Shader::Parents[] = {
- &PyObjectPlus::Type,
&BL_Shader::Type,
+ &PyObjectPlus::Type,
NULL
};
@@ -803,7 +807,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg
}
char *v,*f;
int apply=0;
- if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) )
+ if( PyArg_ParseTuple(args, "ssi:setSource", &v, &f, &apply) )
{
vertProg = v;
fragProg = f;
@@ -854,7 +858,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
Py_RETURN_NONE;
}
if(mShader==0) {
- PyErr_Format(PyExc_TypeError, "invalid shader object");
+ PyErr_SetString(PyExc_TypeError, "shader.validate(): BL_Shader, invalid shader object");
return NULL;
}
int stat = 0;
@@ -886,7 +890,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
const char *uniform="";
int index=-1;
- if(PyArg_ParseTuple(args, "si", &uniform, &index))
+ if(PyArg_ParseTuple(args, "si:setSampler", &uniform, &index))
{
int loc = GetUniformLocation(uniform);
if(loc != -1) {
@@ -911,7 +915,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" )
{
int pass = 1;
- if(!PyArg_ParseTuple(args, "i", &pass))
+ if(!PyArg_ParseTuple(args, "i:setNumberOfPasses", &pass))
return NULL;
mPass = 1;
@@ -927,7 +931,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
const char *uniform="";
float value=0;
- if(PyArg_ParseTuple(args, "sf", &uniform, &value ))
+ if(PyArg_ParseTuple(args, "sf:setUniform1f", &uniform, &value ))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -951,7 +955,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
}
const char *uniform="";
float array[2]={ 0,0 };
- if(PyArg_ParseTuple(args, "sff", &uniform, &array[0],&array[1] ))
+ if(PyArg_ParseTuple(args, "sff:setUniform2f", &uniform, &array[0],&array[1] ))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -975,7 +979,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
}
const char *uniform="";
float array[3]={0,0,0};
- if(PyArg_ParseTuple(args, "sfff", &uniform, &array[0],&array[1],&array[2]))
+ if(PyArg_ParseTuple(args, "sfff:setUniform3f", &uniform, &array[0],&array[1],&array[2]))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1000,7 +1004,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) "
}
const char *uniform="";
float array[4]={0,0,0,0};
- if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3]))
+ if(PyArg_ParseTuple(args, "sffff:setUniform4f", &uniform, &array[0],&array[1],&array[2], &array[3]))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1024,7 +1028,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
}
const char *uniform="";
int value=0;
- if(PyArg_ParseTuple(args, "si", &uniform, &value ))
+ if(PyArg_ParseTuple(args, "si:setUniform1i", &uniform, &value ))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1048,7 +1052,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
}
const char *uniform="";
int array[2]={ 0,0 };
- if(PyArg_ParseTuple(args, "sii", &uniform, &array[0],&array[1] ))
+ if(PyArg_ParseTuple(args, "sii:setUniform2i", &uniform, &array[0],&array[1] ))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1073,7 +1077,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
const char *uniform="";
int array[3]={0,0,0};
- if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2]))
+ if(PyArg_ParseTuple(args, "siii:setUniform3i", &uniform, &array[0],&array[1],&array[2]))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1096,7 +1100,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) "
}
const char *uniform="";
int array[4]={0,0,0, 0};
- if(PyArg_ParseTuple(args, "siiii", &uniform, &array[0],&array[1],&array[2], &array[3] ))
+ if(PyArg_ParseTuple(args, "siiii:setUniform4i", &uniform, &array[0],&array[1],&array[2], &array[3] ))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1121,7 +1125,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
PyObject *listPtr =0;
float array_data[4] = {0.f,0.f,0.f,0.f};
- if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
+ if(PyArg_ParseTuple(args, "sO:setUniformfv", &uniform, &listPtr))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
@@ -1171,7 +1175,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
}break;
default:
{
- PyErr_Format(PyExc_TypeError, "Invalid list size");
+ PyErr_SetString(PyExc_TypeError, "shader.setUniform4i(name, ix,iy,iz, iw): BL_Shader. invalid list size");
return NULL;
}break;
}
@@ -1181,7 +1185,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
return NULL;
}
-KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 or list4) )")
+KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( uniform_name, (list2 or list3 or list4) )")
{
if(mError) {
Py_RETURN_NONE;
@@ -1190,70 +1194,84 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3
PyObject *listPtr =0;
int array_data[4] = {0,0,0,0};
- if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
+ if(!PyArg_ParseTuple(args, "sO:setUniformiv", &uniform, &listPtr))
+ return NULL;
+
+ int loc = GetUniformLocation(uniform);
+
+ if(loc == -1) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, first string argument is not a valid uniform value");
+ return NULL;
+ }
+
+ if(!PySequence_Check(listPtr)) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, second argument is not a sequence");
+ return NULL;
+ }
+
+ unsigned int list_size = PySequence_Size(listPtr);
+
+ for(unsigned int i=0; (i<list_size && i<4); i++)
{
- int loc = GetUniformLocation(uniform);
- if(loc != -1)
+ PyObject *item = PySequence_GetItem(listPtr, i);
+ array_data[i] = PyInt_AsLong(item);
+ Py_DECREF(item);
+ }
+
+ if(PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, one or more values in the list is not an int");
+ return NULL;
+ }
+
+ /* Sanity checks done! */
+
+ switch(list_size)
+ {
+ case 2:
{
- if(PySequence_Check(listPtr))
- {
- unsigned int list_size = PySequence_Size(listPtr);
-
- for(unsigned int i=0; (i<list_size && i<4); i++)
- {
- PyObject *item = PySequence_GetItem(listPtr, i);
- array_data[i] = PyInt_AsLong(item);
- Py_DECREF(item);
- }
- switch(list_size)
- {
- case 2:
- {
- int array2[2] = { array_data[0],array_data[1]};
+ int array2[2] = { array_data[0],array_data[1]};
#ifdef SORT_UNIFORMS
- SetUniformiv(loc, BL_Uniform::UNI_INT2, array2, sizeof(int)*2);
+ SetUniformiv(loc, BL_Uniform::UNI_INT2, array2, sizeof(int)*2);
#else
- SetUniform(loc, array2, 2);
+ SetUniform(loc, array2, 2);
#endif
- Py_RETURN_NONE;
- } break;
- case 3:
- {
- int array3[3] = { array_data[0],array_data[1],array_data[2] };
+ Py_RETURN_NONE;
+ } break;
+ case 3:
+ {
+ int array3[3] = { array_data[0],array_data[1],array_data[2] };
#ifdef SORT_UNIFORMS
- SetUniformiv(loc, BL_Uniform::UNI_INT3, array3, sizeof(int)*3);
-
+ SetUniformiv(loc, BL_Uniform::UNI_INT3, array3, sizeof(int)*3);
+
#else
- SetUniform(loc, array3, 3);
+ SetUniform(loc, array3, 3);
#endif
- Py_RETURN_NONE;
- }break;
- case 4:
- {
- int array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] };
+ Py_RETURN_NONE;
+ }break;
+ case 4:
+ {
+ int array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] };
#ifdef SORT_UNIFORMS
- SetUniformiv(loc, BL_Uniform::UNI_INT4, array4, sizeof(int)*4);
-
+ SetUniformiv(loc, BL_Uniform::UNI_INT4, array4, sizeof(int)*4);
+
#else
- SetUniform(loc, array4, 4);
+ SetUniform(loc, array4, 4);
#endif
- Py_RETURN_NONE;
- }break;
- default:
- {
- PyErr_Format(PyExc_TypeError, "Invalid list size");
- return NULL;
- }break;
- }
- }
- }
+ Py_RETURN_NONE;
+ }break;
+ default:
+ {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformiv(...): BL_Shader, second argument, invalid list size, expected an int list between 2 and 4");
+ return NULL;
+ }break;
}
- return NULL;
+
+ Py_RETURN_NONE;
}
KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4,
-"setUniformMatrix4(uniform-name, mat-4x4, transpose(row-major=true, col-major=false)" )
+"setUniformMatrix4(uniform_name, mat-4x4, transpose(row-major=true, col-major=false)" )
{
if(mError) {
Py_RETURN_NONE;
@@ -1269,33 +1287,38 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4,
const char *uniform="";
PyObject *matrix=0;
int transp=1; // MT_ is row major so transpose by default....
- if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
- {
- int loc = GetUniformLocation(uniform);
- if(loc != -1)
- {
- if (PyObject_IsMT_Matrix(matrix, 4))
- {
- MT_Matrix4x4 mat;
- if (PyMatTo(matrix, mat))
- {
+
+ if(!PyArg_ParseTuple(args, "sO|i:setUniformMatrix4",&uniform, &matrix,&transp))
+ return NULL;
+
+ int loc = GetUniformLocation(uniform);
+
+ if(loc == -1) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix4(...): BL_Shader, first string argument is not a valid uniform value");
+ return NULL;
+ }
+
+ MT_Matrix4x4 mat;
+
+ if (!PyMatTo(matrix, mat)) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix4(...): BL_Shader, second argument cannot be converted into a 4x4 matrix");
+ return NULL;
+ }
+
+ /* Sanity checks done! */
+
#ifdef SORT_UNIFORMS
- mat.getValue(matr);
- SetUniformfv(loc, BL_Uniform::UNI_MAT4, matr, (sizeof(float)*16), (transp!=0) );
+ mat.getValue(matr);
+ SetUniformfv(loc, BL_Uniform::UNI_MAT4, matr, (sizeof(float)*16), (transp!=0) );
#else
- SetUniform(loc,mat,(transp!=0));
+ SetUniform(loc,mat,(transp!=0));
#endif
- Py_RETURN_NONE;
- }
- }
- }
- }
- return NULL;
+ Py_RETURN_NONE;
}
KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
-"setUniformMatrix3(uniform-name, list[3x3], transpose(row-major=true, col-major=false)" )
+"setUniformMatrix3(uniform_name, list[3x3], transpose(row-major=true, col-major=false)" )
{
if(mError) {
Py_RETURN_NONE;
@@ -1310,29 +1333,32 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
const char *uniform="";
PyObject *matrix=0;
int transp=1; // MT_ is row major so transpose by default....
- if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp))
- {
- int loc = GetUniformLocation(uniform);
- if(loc != -1)
- {
- if (PyObject_IsMT_Matrix(matrix, 3))
- {
- MT_Matrix3x3 mat;
- if (PyMatTo(matrix, mat))
- {
+ if(!PyArg_ParseTuple(args, "sO|i:setUniformMatrix3",&uniform, &matrix,&transp))
+ return NULL;
+
+ int loc = GetUniformLocation(uniform);
+
+ if(loc == -1) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix3(...): BL_Shader, first string argument is not a valid uniform value");
+ return NULL;
+ }
+
+
+ MT_Matrix3x3 mat;
+
+ if (!PyMatTo(matrix, mat)) {
+ PyErr_SetString(PyExc_TypeError, "shader.setUniformMatrix3(...): BL_Shader, second argument cannot be converted into a 3x3 matrix");
+ return NULL;
+ }
+
+
#ifdef SORT_UNIFORMS
- mat.getValue(matr);
- SetUniformfv(loc, BL_Uniform::UNI_MAT3, matr, (sizeof(float)*9), (transp!=0) );
+ mat.getValue(matr);
+ SetUniformfv(loc, BL_Uniform::UNI_MAT3, matr, (sizeof(float)*9), (transp!=0) );
#else
- SetUniform(loc,mat,(transp!=0));
+ SetUniform(loc,mat,(transp!=0));
#endif
- Py_RETURN_NONE;
-
- }
- }
- }
- }
- return NULL;
+ Py_RETURN_NONE;
}
KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" )
@@ -1340,18 +1366,20 @@ KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" )
if(mError) {
Py_RETURN_NONE;
}
+
int attr=0;
- if(PyArg_ParseTuple(args, "i", &attr )) {
- if(mShader==0) {
- PyErr_Format(PyExc_ValueError, "invalid shader object");
- return NULL;
- }
- mAttr=SHD_TANGENT;
- glUseProgramObjectARB(mShader);
- glBindAttribLocationARB(mShader, mAttr, "Tangent");
- Py_RETURN_NONE;
+
+ if(!PyArg_ParseTuple(args, "i:setAttrib", &attr ))
+ return NULL;
+
+ if(mShader==0) {
+ PyErr_SetString(PyExc_ValueError, "shader.setAttrib() BL_Shader, invalid shader object");
+ return NULL;
}
- return NULL;
+ mAttr=SHD_TANGENT; /* What the heck is going on here - attr is just ignored??? - Campbell */
+ glUseProgramObjectARB(mShader);
+ glBindAttribLocationARB(mShader, mAttr, "Tangent");
+ Py_RETURN_NONE;
}
@@ -1363,7 +1391,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
const char *uniform="";
int nloc=0;
- if(PyArg_ParseTuple(args, "si",&uniform, &nloc))
+ if(PyArg_ParseTuple(args, "si:setUniformDef",&uniform, &nloc))
{
int loc = GetUniformLocation(uniform);
if(loc != -1)
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index 76acd5513ef..08cad5071fd 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -202,7 +202,8 @@ public:
void SetUniform(int uniform, const int val);
// Python interface
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_repr(void) { return PyString_FromFormat("BL_Shader\n\tvertex shader:%s\n\n\tfragment shader%s\n\n", vertProg, fragProg); }
// -----------------------------------
KX_PYMETHOD_DOC( BL_Shader, setSource );
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index d054894589f..73d7191ffde 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -37,6 +37,8 @@ FILE(GLOB SRC *.cpp)
# ../../../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
+# ../../../source/blender/python/api2_2x/BGL.c
#)
SET(INC
@@ -68,7 +70,7 @@ SET(INC
../../../source/gameengine/Physics/Sumo
../../../source/gameengine/Physics/Sumo/Fuzzics/include
../../../source/gameengine/Network/LoopBackNetwork
- ../../../intern/SoundSystem
+ ../../../intern/SoundSystem
../../../source/blender/misc
../../../source/blender/blenloader
../../../source/blender/gpu
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
index 4e5f27df2da..2483a6bfb39 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
@@ -47,7 +47,7 @@ KX_NetworkMessageActuator::KX_NetworkMessageActuator(
m_networkscene(networkscene),
m_toPropName(toPropName),
m_subject(subject),
- m_bodyType(bodyType),
+ m_bPropBody(bodyType),
m_body(body)
{
}
@@ -69,7 +69,7 @@ bool KX_NetworkMessageActuator::Update()
}
//printf("messageactuator true event\n");
- if (m_bodyType == 1) // ACT_MESG_PROP in DNA_actuator_types.h
+ if (m_bPropBody) // ACT_MESG_PROP in DNA_actuator_types.h
{
m_networkscene->SendMessage(
m_toPropName,
@@ -105,22 +105,22 @@ CValue* KX_NetworkMessageActuator::GetReplica()
/* Integration hooks -------------------------------------------------- */
PyTypeObject KX_NetworkMessageActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_NetworkMessageActuator",
- sizeof(KX_NetworkMessageActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_NetworkMessageActuator::Parents[] = {
@@ -132,6 +132,7 @@ PyParentObject KX_NetworkMessageActuator::Parents[] = {
};
PyMethodDef KX_NetworkMessageActuator::Methods[] = {
+ // Deprecated ----->
{"setToPropName", (PyCFunction)
KX_NetworkMessageActuator::sPySetToPropName, METH_VARARGS},
{"setSubject", (PyCFunction)
@@ -140,26 +141,36 @@ PyMethodDef KX_NetworkMessageActuator::Methods[] = {
KX_NetworkMessageActuator::sPySetBodyType, METH_VARARGS},
{"setBody", (PyCFunction)
KX_NetworkMessageActuator::sPySetBody, METH_VARARGS},
+ // <-----
{NULL,NULL} // Sentinel
};
PyAttributeDef KX_NetworkMessageActuator::Attributes[] = {
+ KX_PYATTRIBUTE_STRING_RW("propName", 0, 100, false, KX_NetworkMessageActuator, m_toPropName),
+ KX_PYATTRIBUTE_STRING_RW("subject", 0, 100, false, KX_NetworkMessageActuator, m_subject),
+ KX_PYATTRIBUTE_BOOL_RW("usePropBody", KX_NetworkMessageActuator, m_bPropBody),
+ KX_PYATTRIBUTE_STRING_RW("body", 0, 100, false, KX_NetworkMessageActuator, m_body),
{ NULL } //Sentinel
};
-PyObject* KX_NetworkMessageActuator::_getattr(const char *attr) {
- _getattr_up(SCA_IActuator);
+PyObject* KX_NetworkMessageActuator::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_IActuator);
}
+int KX_NetworkMessageActuator::py_setattro(PyObject *attr, PyObject *value) {
+ py_setattro_up(SCA_IActuator);
+}
+
+// Deprecated ----->
// 1. SetToPropName
PyObject* KX_NetworkMessageActuator::PySetToPropName(
- PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("setToProp()", "the propName property");
char* ToPropName;
- if (PyArg_ParseTuple(args, "s", &ToPropName)) {
+ if (PyArg_ParseTuple(args, "s:setToPropName", &ToPropName)) {
m_toPropName = ToPropName;
}
else {
@@ -171,13 +182,13 @@ PyObject* KX_NetworkMessageActuator::PySetToPropName(
// 2. SetSubject
PyObject* KX_NetworkMessageActuator::PySetSubject(
- PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("setSubject()", "the subject property");
char* Subject;
- if (PyArg_ParseTuple(args, "s", &Subject)) {
+ if (PyArg_ParseTuple(args, "s:setSubject", &Subject)) {
m_subject = Subject;
}
else {
@@ -189,14 +200,14 @@ PyObject* KX_NetworkMessageActuator::PySetSubject(
// 3. SetBodyType
PyObject* KX_NetworkMessageActuator::PySetBodyType(
- PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("setBodyType()", "the usePropBody property");
int BodyType;
- if (PyArg_ParseTuple(args, "i", &BodyType)) {
- m_bodyType = BodyType;
+ if (PyArg_ParseTuple(args, "i:setBodyType", &BodyType)) {
+ m_bPropBody = (BodyType != 0);
}
else {
return NULL;
@@ -207,13 +218,13 @@ PyObject* KX_NetworkMessageActuator::PySetBodyType(
// 4. SetBody
PyObject* KX_NetworkMessageActuator::PySetBody(
- PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("setBody()", "the body property");
char* Body;
- if (PyArg_ParseTuple(args, "s", &Body)) {
+ if (PyArg_ParseTuple(args, "s:setBody", &Body)) {
m_body = Body;
}
else {
@@ -223,3 +234,4 @@ PyObject* KX_NetworkMessageActuator::PySetBody(
Py_RETURN_NONE;
}
+// <----- Deprecated \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
index 96b55ef839b..850f825b8f3 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
@@ -41,7 +41,7 @@ class KX_NetworkMessageActuator : public SCA_IActuator
class NG_NetworkScene* m_networkscene; // needed for replication
STR_String m_toPropName;
STR_String m_subject;
- int m_bodyType;
+ bool m_bPropBody;
STR_String m_body;
public:
KX_NetworkMessageActuator(
@@ -61,12 +61,15 @@ public:
/* Python interface ------------------------------------------- */
/* ------------------------------------------------------------ */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+ // Deprecated ----->
KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName);
KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject);
KX_PYMETHOD(KX_NetworkMessageActuator, SetBodyType);
KX_PYMETHOD(KX_NetworkMessageActuator, SetBody);
+ // <-----
};
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index ac89d8b0716..7782567943e 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -168,22 +168,22 @@ bool KX_NetworkMessageSensor::IsPositiveTrigger()
/* Integration hooks --------------------------------------------------- */
PyTypeObject KX_NetworkMessageSensor::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_NetworkMessageSensor",
- sizeof(KX_NetworkMessageSensor),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_NetworkMessageSensor::Parents[] = {
@@ -195,6 +195,7 @@ PyParentObject KX_NetworkMessageSensor::Parents[] = {
};
PyMethodDef KX_NetworkMessageSensor::Methods[] = {
+ // Deprecated ----->
{"setSubjectFilterText", (PyCFunction)
KX_NetworkMessageSensor::sPySetSubjectFilterText, METH_O,
(PY_METHODCHAR)SetSubjectFilterText_doc},
@@ -210,27 +211,58 @@ PyMethodDef KX_NetworkMessageSensor::Methods[] = {
{"getSubjects", (PyCFunction)
KX_NetworkMessageSensor::sPyGetSubjects, METH_NOARGS,
(PY_METHODCHAR)GetSubjects_doc},
+ // <-----
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_NetworkMessageSensor::Attributes[] = {
+ KX_PYATTRIBUTE_STRING_RW("subject", 0, 100, false, KX_NetworkMessageSensor, m_subject),
+ KX_PYATTRIBUTE_INT_RO("frameMessageCount", KX_NetworkMessageSensor, m_frame_message_count),
+ KX_PYATTRIBUTE_RO_FUNCTION("bodies", KX_NetworkMessageSensor, pyattr_get_bodies),
+ KX_PYATTRIBUTE_RO_FUNCTION("subjects", KX_NetworkMessageSensor, pyattr_get_subjects),
{ NULL } //Sentinel
};
-PyObject* KX_NetworkMessageSensor::_getattr(const char *attr) {
- _getattr_up(SCA_ISensor); // implicit return!
+PyObject* KX_NetworkMessageSensor::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_ISensor);
}
+int KX_NetworkMessageSensor::py_setattro(PyObject *attr, PyObject *value) {
+ return SCA_ISensor::py_setattro(attr, value);
+}
+
+PyObject* KX_NetworkMessageSensor::pyattr_get_bodies(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v);
+ if (self->m_BodyList) {
+ return self->m_BodyList->GetProxy();
+ } else {
+ return (new CListValue())->NewProxy(true);
+ }
+}
+
+PyObject* KX_NetworkMessageSensor::pyattr_get_subjects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v);
+ if (self->m_SubjectList) {
+ return self->m_SubjectList->GetProxy();
+ } else {
+ return (new CListValue())->NewProxy(true);
+ }
+}
+
+// Deprecated ----->
// 1. Set the message subject that this sensor listens for
const char KX_NetworkMessageSensor::SetSubjectFilterText_doc[] =
"\tsetSubjectFilterText(value)\n"
"\tChange the message subject text that this sensor is listening to.\n";
-PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText( PyObject* self, PyObject* value)
+PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText(PyObject* value)
{
+ ShowDeprecationWarning("setSubjectFilterText()", "subject");
char* Subject = PyString_AsString(value);
if (Subject==NULL) {
- PyErr_SetString(PyExc_TypeError, "expected a string message");
+ PyErr_SetString(PyExc_TypeError, "sensor.tsetSubjectFilterText(string): KX_NetworkMessageSensor, expected a string message");
return NULL;
}
@@ -243,8 +275,9 @@ const char KX_NetworkMessageSensor::GetFrameMessageCount_doc[] =
"\tgetFrameMessageCount()\n"
"\tGet the number of messages received since the last frame.\n";
-PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount( PyObject* )
+PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount()
{
+ ShowDeprecationWarning("getFrameMessageCount()", "frameMessageCount");
return PyInt_FromLong(long(m_frame_message_count));
}
@@ -253,12 +286,13 @@ const char KX_NetworkMessageSensor::GetBodies_doc[] =
"\tgetBodies()\n"
"\tGet the list of message bodies.\n";
-PyObject* KX_NetworkMessageSensor::PyGetBodies( PyObject* )
+PyObject* KX_NetworkMessageSensor::PyGetBodies()
{
+ ShowDeprecationWarning("getBodies()", "bodies");
if (m_BodyList) {
- return ((PyObject*) m_BodyList->AddRef());
+ return m_BodyList->GetProxy();
} else {
- return ((PyObject*) new CListValue());
+ return (new CListValue())->NewProxy(true);
}
}
@@ -267,8 +301,9 @@ const char KX_NetworkMessageSensor::GetSubject_doc[] =
"\tgetSubject()\n"
"\tGet the subject: field of the message sensor.\n";
-PyObject* KX_NetworkMessageSensor::PyGetSubject( PyObject* )
+PyObject* KX_NetworkMessageSensor::PyGetSubject()
{
+ ShowDeprecationWarning("getSubject()", "subject");
return PyString_FromString(m_subject ? m_subject : "");
}
@@ -277,11 +312,13 @@ const char KX_NetworkMessageSensor::GetSubjects_doc[] =
"\tgetSubjects()\n"
"\tGet list of message subjects.\n";
-PyObject* KX_NetworkMessageSensor::PyGetSubjects( PyObject* )
+PyObject* KX_NetworkMessageSensor::PyGetSubjects()
{
+ ShowDeprecationWarning("getSubjects()", "subjects");
if (m_SubjectList) {
- return ((PyObject*) m_SubjectList->AddRef());
+ return m_SubjectList->GetProxy();
} else {
- return ((PyObject*) new CListValue());
+ return (new CListValue())->NewProxy(true);
}
}
+// <----- Deprecated \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index 26adbc9945a..ac0e880d25c 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -72,14 +72,20 @@ public:
/* Python interface -------------------------------------------- */
/* ------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+ // Deprecated ----->
KX_PYMETHOD_DOC_O(KX_NetworkMessageSensor, SetSubjectFilterText);
KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetFrameMessageCount);
KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetBodies);
KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetSubject);
KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetSubjects);
+ // <-----
+ /* attributes */
+ static PyObject* pyattr_get_bodies(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_subjects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
};
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index b9bd7647f89..849332008ce 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -753,36 +753,40 @@ PyAttributeDef KX_BlenderMaterial::Attributes[] = {
};
PyTypeObject KX_BlenderMaterial::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_BlenderMaterial",
- sizeof(KX_BlenderMaterial),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
0,
- __repr,
- 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 KX_BlenderMaterial::Parents[] = {
- &PyObjectPlus::Type,
&KX_BlenderMaterial::Type,
+ &PyObjectPlus::Type,
NULL
};
-PyObject* KX_BlenderMaterial::_getattr(const char *attr)
+PyObject* KX_BlenderMaterial::py_getattro(PyObject *attr)
{
- _getattr_up(PyObjectPlus);
+ py_getattro_up(PyObjectPlus);
}
-int KX_BlenderMaterial::_setattr(const char *attr, PyObject *pyvalue)
+int KX_BlenderMaterial::py_setattro(PyObject *attr, PyObject *pyvalue)
{
- return PyObjectPlus::_setattr(attr, pyvalue);
+ return PyObjectPlus::py_setattro(attr, pyvalue);
}
@@ -823,8 +827,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
m_flag &= ~RAS_BLENDERGLSL;
mMaterial->SetSharedMaterial(true);
mScene->GetBucketManager()->ReleaseDisplayLists(this);
- Py_INCREF(mShader);
- return mShader;
+ return mShader->GetProxy();
}else
{
// decref all references to the object
@@ -832,18 +835,13 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
// We will then go back to fixed functionality
// for this material
if(mShader) {
- if(mShader->ob_refcnt > 1) {
- Py_DECREF(mShader);
- }
- else {
- delete mShader;
- mShader=0;
- }
+ delete mShader; /* will handle python de-referencing */
+ mShader=0;
}
}
Py_RETURN_NONE;
}
- PyErr_Format(PyExc_ValueError, "GLSL Error");
+ PyErr_SetString(PyExc_ValueError, "material.getShader(): KX_BlenderMaterial, GLSL Error");
return NULL;
}
@@ -893,7 +891,7 @@ static unsigned int GL_array[11] = {
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.src, GameLogic.dest)")
{
unsigned int b[2];
- if(PyArg_ParseTuple(args, "ii", &b[0], &b[1]))
+ if(PyArg_ParseTuple(args, "ii:setBlending", &b[0], &b[1]))
{
bool value_found[2] = {false, false};
for(int i=0; i<11; i++)
@@ -909,7 +907,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.sr
if(value_found[0] && value_found[1]) break;
}
if(!value_found[0] || !value_found[1]) {
- PyErr_Format(PyExc_ValueError, "invalid enum.");
+ PyErr_SetString(PyExc_ValueError, "material.setBlending(int, int): KX_BlenderMaterial, invalid enum.");
return NULL;
}
mUserDefBlend = true;
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 2cf623dbd85..48d4730ab07 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -82,8 +82,9 @@ public:
);
// --------------------------------
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *pyvalue);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
+ virtual PyObject* py_repr(void) { return PyString_FromString(mMaterial->matname.ReadPtr()); }
KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader );
KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex );
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 062e9f7df50..831f9241fec 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -59,6 +59,24 @@ void KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_
}
+float KX_BulletPhysicsController::GetLinVelocityMin()
+{
+ return (float)CcdPhysicsController::GetLinVelocityMin();
+}
+void KX_BulletPhysicsController::SetLinVelocityMin(float val)
+{
+ CcdPhysicsController::SetLinVelocityMin(val);
+}
+
+float KX_BulletPhysicsController::GetLinVelocityMax()
+{
+ return (float)CcdPhysicsController::GetLinVelocityMax();
+}
+void KX_BulletPhysicsController::SetLinVelocityMax(float val)
+{
+ CcdPhysicsController::SetLinVelocityMax(val);
+}
+
void KX_BulletPhysicsController::SetObject (SG_IObject* object)
{
SG_Controller::SetObject(object);
@@ -73,6 +91,10 @@ void KX_BulletPhysicsController::SetObject (SG_IObject* object)
}
+MT_Scalar KX_BulletPhysicsController::GetRadius()
+{
+ return MT_Scalar(CcdPhysicsController::GetRadius());
+}
void KX_BulletPhysicsController::setMargin (float collisionMargin)
{
@@ -162,9 +184,18 @@ MT_Scalar KX_BulletPhysicsController::GetMass()
}
-MT_Scalar KX_BulletPhysicsController::GetRadius()
+MT_Vector3 KX_BulletPhysicsController::GetLocalInertia()
{
- return MT_Scalar(CcdPhysicsController::GetRadius());
+ MT_Vector3 inertia(0.f, 0.f, 0.f);
+ btVector3 inv_inertia;
+ if (GetRigidBody()) {
+ inv_inertia = GetRigidBody()->getInvInertiaDiagLocal();
+ if (!btFuzzyZero(inv_inertia.getX()) &&
+ !btFuzzyZero(inv_inertia.getY()) &&
+ !btFuzzyZero(inv_inertia.getZ()))
+ inertia = MT_Vector3(1.f/inv_inertia.getX(), 1.f/inv_inertia.getY(), 1.f/inv_inertia.getZ());
+ }
+ return inertia;
}
MT_Vector3 KX_BulletPhysicsController::getReactionForce()
@@ -417,13 +448,14 @@ void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly)
{
if (!nondynaonly)
{
+ /*
btTransform worldTrans;
if (GetRigidBody())
{
GetRigidBody()->getMotionState()->getWorldTransform(worldTrans);
GetRigidBody()->setCenterOfMassTransform(worldTrans);
}
-
+ */
/*
scaling?
if (m_bDyna)
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index 44fbde7054e..b39098206f7 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -42,6 +42,7 @@ public:
virtual void setScaling(const MT_Vector3& scaling);
virtual MT_Scalar GetMass();
virtual void SetMass(MT_Scalar newmass);
+ virtual MT_Vector3 GetLocalInertia();
virtual MT_Vector3 getReactionForce();
virtual void setRigidBody(bool rigid);
virtual void AddCompoundChild(KX_IPhysicsController* child);
@@ -55,7 +56,11 @@ public:
virtual SG_Controller* GetReplica(class SG_Node* destnode);
virtual MT_Scalar GetRadius();
-
+
+ virtual float GetLinVelocityMin();
+ virtual void SetLinVelocityMin(float val);
+ virtual float GetLinVelocityMax();
+ virtual void SetLinVelocityMax(float val);
virtual void SetSumoTransform(bool nondynaonly);
// todo: remove next line !
diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp
index ef7883910fd..121d4512265 100644
--- a/source/gameengine/Ketsji/KX_CDActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CDActuator.cpp
@@ -98,7 +98,7 @@ bool KX_CDActuator::Update()
SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
SND_CDObject::Instance()->SetTrack(1);
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
- result = true;
+ //result = true;
break;
}
case KX_CDACT_PLAY_TRACK:
@@ -106,7 +106,7 @@ bool KX_CDActuator::Update()
SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK);
SND_CDObject::Instance()->SetTrack(m_track);
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
- result = true;
+ //result = true;
break;
}
case KX_CDACT_LOOP_TRACK:
@@ -114,7 +114,7 @@ bool KX_CDActuator::Update()
SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
SND_CDObject::Instance()->SetTrack(m_track);
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
- result = true;
+ //result = true;
break;
}
case KX_CDACT_STOP:
@@ -125,19 +125,19 @@ bool KX_CDActuator::Update()
case KX_CDACT_PAUSE:
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
- result = true;
+ //result = true;
break;
}
case KX_CDACT_RESUME:
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_RESUME);
- result = true;
+ //result = true;
break;
}
case KX_CDACT_VOLUME:
{
SND_CDObject::Instance()->SetGain(m_gain);
- result = true;
+ //result = true;
break;
}
default:
@@ -158,22 +158,22 @@ bool KX_CDActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_CDActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SoundActuator",
- sizeof(KX_CDActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -189,54 +189,111 @@ PyParentObject KX_CDActuator::Parents[] = {
PyMethodDef KX_CDActuator::Methods[] = {
- {"startCD",(PyCFunction) KX_CDActuator::sPyStartCD,METH_VARARGS,NULL},
- {"pauseCD",(PyCFunction) KX_CDActuator::sPyPauseCD,METH_VARARGS,NULL},
- {"stopCD",(PyCFunction) KX_CDActuator::sPyStopCD,METH_VARARGS,NULL},
+ // Deprecated ----->
{"setGain",(PyCFunction) KX_CDActuator::sPySetGain,METH_VARARGS,NULL},
{"getGain",(PyCFunction) KX_CDActuator::sPyGetGain,METH_VARARGS,NULL},
+ // <-----
+ KX_PYMETHODTABLE_NOARGS(KX_CDActuator, startCD),
+ KX_PYMETHODTABLE_NOARGS(KX_CDActuator, pauseCD),
+ KX_PYMETHODTABLE_NOARGS(KX_CDActuator, resumeCD),
+ KX_PYMETHODTABLE_NOARGS(KX_CDActuator, stopCD),
+ KX_PYMETHODTABLE_NOARGS(KX_CDActuator, playAll),
+ KX_PYMETHODTABLE_O(KX_CDActuator, playTrack),
{NULL,NULL,NULL,NULL} //Sentinel
};
PyAttributeDef KX_CDActuator::Attributes[] = {
+ KX_PYATTRIBUTE_FLOAT_RW_CHECK("volume", 0.0, 1.0, KX_CDActuator, m_gain,pyattr_setGain),
+ KX_PYATTRIBUTE_INT_RW("track", 1, 99, false, KX_CDActuator, m_track),
{ NULL } //Sentinel
};
-PyObject* KX_CDActuator::_getattr(const char *attr)
+int KX_CDActuator::pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
- _getattr_up(SCA_IActuator);
+ KX_CDActuator* act = static_cast<KX_CDActuator*>(self);
+ SND_CDObject::Instance()->SetGain(act->m_gain);
+ return 0;
}
+PyObject* KX_CDActuator::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_IActuator);
+}
+
+int KX_CDActuator::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(SCA_IActuator);
+}
-PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwds)
+KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, startCD,
+"startCD()\n"
+"\tStarts the CD playing.\n")
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
Py_RETURN_NONE;
}
-
-PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwds)
+KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, pauseCD,
+"pauseCD()\n"
+"\tPauses the CD playing.\n")
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
Py_RETURN_NONE;
}
+KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, resumeCD,
+"resumeCD()\n"
+"\tResumes the CD playing.\n")
+{
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_RESUME);
+ Py_RETURN_NONE;
+}
+
-PyObject* KX_CDActuator::PyStopCD(PyObject* self, PyObject* args, PyObject* kwds)
+KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, stopCD,
+"stopCD()\n"
+"\tStops the CD playing.\n")
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP);
Py_RETURN_NONE;
}
+KX_PYMETHODDEF_DOC_O(KX_CDActuator, playTrack,
+"playTrack(trackNumber)\n"
+"\tPlays the track selected.\n")
+{
+ if (PyInt_Check(value)) {
+ int track = PyInt_AsLong(value);
+ SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK);
+ SND_CDObject::Instance()->SetTrack(track);
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
+ }
+ Py_RETURN_NONE;
+}
+
+
+
+KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, playAll,
+"playAll()\n"
+"\tPlays the CD from the beginning.\n")
+{
+ SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
+ SND_CDObject::Instance()->SetTrack(1);
+ SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
+ Py_RETURN_NONE;
+}
-PyObject* KX_CDActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds)
+// Deprecated ----->
+PyObject* KX_CDActuator::PySetGain(PyObject* args)
{
float gain = 1.0;
- if (!PyArg_ParseTuple(args, "f", &gain))
+ ShowDeprecationWarning("setGain()", "the volume property");
+ if (!PyArg_ParseTuple(args, "f:setGain", &gain))
return NULL;
SND_CDObject::Instance()->SetGain(gain);
@@ -246,10 +303,12 @@ PyObject* KX_CDActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwd
-PyObject* KX_CDActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_CDActuator::PyGetGain(PyObject* args)
{
float gain = SND_CDObject::Instance()->GetGain();
+ ShowDeprecationWarning("getGain()", "the volume property");
PyObject* result = PyFloat_FromDouble(gain);
return result;
}
+// <-----
diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h
index 393c49083f9..b674755e59f 100644
--- a/source/gameengine/Ketsji/KX_CDActuator.h
+++ b/source/gameengine/Ketsji/KX_CDActuator.h
@@ -81,13 +81,24 @@ public:
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+
+ // Deprecated ----->
+ KX_PYMETHOD_VARARGS(KX_CDActuator,SetGain);
+ KX_PYMETHOD_VARARGS(KX_CDActuator,GetGain);
+ // <-----
+
+ KX_PYMETHOD_DOC_NOARGS(KX_CDActuator, startCD);
+ KX_PYMETHOD_DOC_NOARGS(KX_CDActuator, pauseCD);
+ KX_PYMETHOD_DOC_NOARGS(KX_CDActuator, resumeCD);
+ KX_PYMETHOD_DOC_NOARGS(KX_CDActuator, stopCD);
+ KX_PYMETHOD_DOC_NOARGS(KX_CDActuator, playAll);
+ KX_PYMETHOD_DOC_O(KX_CDActuator, playTrack);
+
+ static int pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+
- KX_PYMETHOD(KX_CDActuator,StartCD);
- KX_PYMETHOD(KX_CDActuator,PauseCD);
- KX_PYMETHOD(KX_CDActuator,StopCD);
- KX_PYMETHOD(KX_CDActuator,SetGain);
- KX_PYMETHOD(KX_CDActuator,GetGain);
};
#endif //__KX_CDACTUATOR
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 5caac2fc670..c8575424751 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -484,56 +484,53 @@ PyMethodDef KX_Camera::Methods[] = {
};
PyAttributeDef KX_Camera::Attributes[] = {
+
+ KX_PYATTRIBUTE_BOOL_RW("frustum_culling", KX_Camera, m_frustum_culling),
+ KX_PYATTRIBUTE_RW_FUNCTION("perspective", KX_Camera, pyattr_get_perspective, pyattr_set_perspective),
+
+ KX_PYATTRIBUTE_RW_FUNCTION("lens", KX_Camera, pyattr_get_lens, pyattr_set_lens),
+ 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_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),
+ KX_PYATTRIBUTE_RO_FUNCTION("world_to_camera", KX_Camera, pyattr_get_world_to_camera),
+
+ /* Grrr, functions for constants? */
+ KX_PYATTRIBUTE_RO_FUNCTION("INSIDE", KX_Camera, pyattr_get_INSIDE),
+ KX_PYATTRIBUTE_RO_FUNCTION("OUTSIDE", KX_Camera, pyattr_get_OUTSIDE),
+ KX_PYATTRIBUTE_RO_FUNCTION("INTERSECT", KX_Camera, pyattr_get_INTERSECT),
+
{ NULL } //Sentinel
};
-char KX_Camera::doc[] = "Module KX_Camera\n\n"
-"Constants:\n"
-"\tINSIDE\n"
-"\tINTERSECT\n"
-"\tOUTSIDE\n"
-"Attributes:\n"
-"\tlens -> float\n"
-"\t\tThe camera's lens value\n"
-"\tnear -> float\n"
-"\t\tThe camera's near clip distance\n"
-"\tfar -> float\n"
-"\t\tThe camera's far clip distance\n"
-"\tfrustum_culling -> bool\n"
-"\t\tNon zero if this camera is frustum culling.\n"
-"\tprojection_matrix -> [[float]]\n"
-"\t\tThis camera's projection matrix.\n"
-"\tmodelview_matrix -> [[float]] (read only)\n"
-"\t\tThis camera's model view matrix.\n"
-"\t\tRegenerated every frame from the camera's position and orientation.\n"
-"\tcamera_to_world -> [[float]] (read only)\n"
-"\t\tThis camera's camera to world transform.\n"
-"\t\tRegenerated every frame from the camera's position and orientation.\n"
-"\tworld_to_camera -> [[float]] (read only)\n"
-"\t\tThis camera's world to camera transform.\n"
-"\t\tRegenerated every frame from the camera's position and orientation.\n"
-"\t\tThis is camera_to_world inverted.\n";
-
PyTypeObject KX_Camera::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_Camera",
- sizeof(KX_Camera),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
0,
0,
0,
- 0, 0, 0, 0, 0, 0,
- doc
+ py_base_repr,
+ 0,0,
+ &KX_GameObject::Mapping,
+ 0,0,0,
+ py_base_getattro,
+ py_base_setattro,
+ 0,0,0,0,0,0,0,0,0,
+ Methods
};
+
+
+
+
+
PyParentObject KX_Camera::Parents[] = {
&KX_Camera::Type,
&KX_GameObject::Type,
@@ -542,90 +539,14 @@ PyParentObject KX_Camera::Parents[] = {
NULL
};
-PyObject* KX_Camera::_getattr(const char *attr)
-{
- if (!strcmp(attr, "INSIDE"))
- return PyInt_FromLong(INSIDE); /* new ref */
- if (!strcmp(attr, "OUTSIDE"))
- return PyInt_FromLong(OUTSIDE); /* new ref */
- if (!strcmp(attr, "INTERSECT"))
- return PyInt_FromLong(INTERSECT); /* new ref */
-
- if (!strcmp(attr, "lens"))
- return PyFloat_FromDouble(GetLens()); /* new ref */
- if (!strcmp(attr, "near"))
- return PyFloat_FromDouble(GetCameraNear()); /* new ref */
- if (!strcmp(attr, "far"))
- return PyFloat_FromDouble(GetCameraFar()); /* new ref */
- if (!strcmp(attr, "frustum_culling"))
- return PyInt_FromLong(m_frustum_culling); /* new ref */
- if (!strcmp(attr, "perspective"))
- return PyInt_FromLong(m_camdata.m_perspective); /* new ref */
- if (!strcmp(attr, "projection_matrix"))
- return PyObjectFrom(GetProjectionMatrix()); /* new ref */
- if (!strcmp(attr, "modelview_matrix"))
- return PyObjectFrom(GetModelviewMatrix()); /* new ref */
- if (!strcmp(attr, "camera_to_world"))
- return PyObjectFrom(GetCameraToWorld()); /* new ref */
- if (!strcmp(attr, "world_to_camera"))
- return PyObjectFrom(GetWorldToCamera()); /* new ref */
-
- _getattr_up(KX_GameObject);
-}
-
-int KX_Camera::_setattr(const char *attr, PyObject *pyvalue)
-{
- if (PyInt_Check(pyvalue))
- {
- if (!strcmp(attr, "frustum_culling"))
- {
- m_frustum_culling = PyInt_AsLong(pyvalue);
- return 0;
- }
-
- if (!strcmp(attr, "perspective"))
- {
- m_camdata.m_perspective = PyInt_AsLong(pyvalue);
- return 0;
- }
- }
-
- if (PyFloat_Check(pyvalue))
- {
- if (!strcmp(attr, "lens"))
- {
- m_camdata.m_lens = PyFloat_AsDouble(pyvalue);
- m_set_projection_matrix = false;
- return 0;
- }
- if (!strcmp(attr, "near"))
- {
- m_camdata.m_clipstart = PyFloat_AsDouble(pyvalue);
- m_set_projection_matrix = false;
- return 0;
- }
- if (!strcmp(attr, "far"))
- {
- m_camdata.m_clipend = PyFloat_AsDouble(pyvalue);
- m_set_projection_matrix = false;
- return 0;
- }
- }
-
- if (PyObject_IsMT_Matrix(pyvalue, 4))
- {
- if (!strcmp(attr, "projection_matrix"))
- {
- MT_Matrix4x4 mat;
- if (PyMatTo(pyvalue, mat))
- {
- SetProjectionMatrix(mat);
- return 0;
- }
- return 1;
- }
- }
- return KX_GameObject::_setattr(attr, pyvalue);
+PyObject* KX_Camera::py_getattro(PyObject *attr)
+{
+ py_getattro_up(KX_GameObject);
+}
+
+int KX_Camera::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(KX_GameObject);
}
KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum,
@@ -648,7 +569,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum,
{
PyObject *pycenter;
float radius;
- if (PyArg_ParseTuple(args, "Of", &pycenter, &radius))
+ if (PyArg_ParseTuple(args, "Of:sphereInsideFrustum", &pycenter, &radius))
{
MT_Point3 center;
if (PyVecTo(pycenter, center))
@@ -657,7 +578,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum,
}
}
- PyErr_SetString(PyExc_TypeError, "sphereInsideFrustum: Expected arguments: (center, radius)");
+ PyErr_SetString(PyExc_TypeError, "camera.sphereInsideFrustum(center, radius): KX_Camera, expected arguments: (center, radius)");
return NULL;
}
@@ -690,7 +611,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, boxInsideFrustum,
unsigned int num_points = PySequence_Size(value);
if (num_points != 8)
{
- PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points);
+ PyErr_Format(PyExc_TypeError, "camera.boxInsideFrustum(box): KX_Camera, expected eight (8) points, got %d", num_points);
return NULL;
}
@@ -729,7 +650,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum,
return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */
}
- PyErr_SetString(PyExc_TypeError, "pointInsideFrustum: Expected point argument.");
+ PyErr_SetString(PyExc_TypeError, "camera.pointInsideFrustum(point): KX_Camera, expected point argument.");
return NULL;
}
@@ -805,7 +726,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, setProjectionMatrix,
MT_Matrix4x4 mat;
if (!PyMatTo(value, mat))
{
- PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument.");
+ PyErr_SetString(PyExc_TypeError, "camera.setProjectionMatrix(matrix): KX_Camera, expected 4x4 list as matrix argument.");
return NULL;
}
@@ -821,7 +742,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport,
int viewport = PyObject_IsTrue(value);
if (viewport == -1) {
- PyErr_SetString(PyExc_ValueError, "expected True/False or 0/1");
+ PyErr_SetString(PyExc_ValueError, "camera.enableViewport(bool): KX_Camera, expected True/False or 0/1");
return NULL;
}
@@ -856,3 +777,126 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, setOnTop,
scene->SetCameraOnTop(this);
Py_RETURN_NONE;
}
+
+PyObject* KX_Camera::pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyBool_FromLong(self->m_camdata.m_perspective);
+}
+
+int KX_Camera::pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ 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;
+ }
+
+ self->m_camdata.m_perspective= param;
+ return 0;
+}
+
+PyObject* KX_Camera::pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyFloat_FromDouble(self->m_camdata.m_lens);
+}
+
+int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ 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;
+ }
+
+ self->m_camdata.m_lens= param;
+ self->m_set_projection_matrix = false;
+ return 0;
+}
+
+PyObject* KX_Camera::pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyFloat_FromDouble(self->m_camdata.m_clipstart);
+}
+
+int KX_Camera::pyattr_set_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ 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;
+ }
+
+ self->m_camdata.m_clipstart= param;
+ self->m_set_projection_matrix = false;
+ return 0;
+}
+
+PyObject* KX_Camera::pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyFloat_FromDouble(self->m_camdata.m_clipend);
+}
+
+int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ 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;
+ }
+
+ self->m_camdata.m_clipend= param;
+ self->m_set_projection_matrix = false;
+ return 0;
+}
+
+PyObject* KX_Camera::pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyObjectFrom(self->GetProjectionMatrix());
+}
+
+int KX_Camera::pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ MT_Matrix4x4 mat;
+ if (!PyMatTo(value, mat))
+ return -1;
+
+ self->SetProjectionMatrix(mat);
+ return 0;
+}
+
+PyObject* KX_Camera::pyattr_get_modelview_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyObjectFrom(self->GetModelviewMatrix());
+}
+
+PyObject* KX_Camera::pyattr_get_camera_to_world(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyObjectFrom(self->GetCameraToWorld());
+}
+
+PyObject* KX_Camera::pyattr_get_world_to_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyObjectFrom(self->GetWorldToCamera());
+}
+
+
+PyObject* KX_Camera::pyattr_get_INSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{ return PyInt_FromLong(INSIDE); }
+PyObject* KX_Camera::pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{ return PyInt_FromLong(OUTSIDE); }
+PyObject* KX_Camera::pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{ return PyInt_FromLong(INTERSECT); }
+
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index efd18f99390..4accd4bc2f1 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -45,6 +45,7 @@ class KX_Camera : public KX_GameObject
{
Py_Header;
protected:
+ friend class KX_Scene;
/** Camera parameters (clips distances, focal lenght). These
* params are closely tied to Blender. In the gameengine, only the
* projection and modelview matrices are relevant. There's a
@@ -67,6 +68,7 @@ protected:
* Storage for the projection matrix that is passed to the
* rasterizer. */
MT_Matrix4x4 m_projection_matrix;
+ //MT_Matrix4x4 m_projection_matrix1;
/**
* Storage for the modelview matrix that is passed to the
@@ -108,11 +110,6 @@ protected:
bool m_set_frustum_center;
/**
- * Python module doc string.
- */
- static char doc[];
-
- /**
* Extracts the camera clip frames from the projection and world-to-camera matrices.
*/
void ExtractClipPlanes();
@@ -124,6 +121,16 @@ protected:
* Extracts the bound sphere of the view frustum.
*/
void ExtractFrustumSphere();
+ /**
+ * return the clip plane
+ */
+ MT_Vector4 *GetNormalizedClipPlanes()
+ {
+ ExtractClipPlanes();
+ NormalizeClipPlanes();
+ return m_planes;
+ }
+
public:
enum { INSIDE, INTERSECT, OUTSIDE } ;
@@ -270,9 +277,29 @@ public:
KX_PYMETHOD_DOC_VARARGS(KX_Camera, setViewport);
KX_PYMETHOD_DOC_NOARGS(KX_Camera, setOnTop);
- virtual PyObject* _getattr(const char *attr); /* lens, near, far, projection_matrix */
- virtual int _setattr(const char *attr, PyObject *pyvalue);
+ virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */
+ virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
+
+ static PyObject* pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ 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_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);
+
+ static PyObject* pyattr_get_modelview_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_camera_to_world(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_world_to_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
+ static PyObject* pyattr_get_INSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
};
#endif //__KX_CAMERA
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 30ecc5ad441..8ef9f318142 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -371,22 +371,22 @@ bool KX_CameraActuator::string2axischoice(const char *axisString)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_CameraActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_CameraActuator",
- sizeof(KX_CameraActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_CameraActuator::Parents[] = {
@@ -408,7 +408,7 @@ PyMethodDef KX_CameraActuator::Methods[] = {
{"setHeight",(PyCFunction) KX_CameraActuator::sPySetHeight, METH_VARARGS, (PY_METHODCHAR)SetHeight_doc},
{"getHeight",(PyCFunction) KX_CameraActuator::sPyGetHeight, METH_NOARGS, (PY_METHODCHAR)GetHeight_doc},
{"setXY" ,(PyCFunction) KX_CameraActuator::sPySetXY, METH_VARARGS, (PY_METHODCHAR)SetXY_doc},
- {"getXY" ,(PyCFunction) KX_CameraActuator::sPyGetXY, METH_VARARGS, (PY_METHODCHAR)GetXY_doc},
+ {"getXY" ,(PyCFunction) KX_CameraActuator::sPyGetXY, METH_NOARGS, (PY_METHODCHAR)GetXY_doc},
{NULL,NULL,NULL,NULL} //Sentinel
};
@@ -417,47 +417,16 @@ PyAttributeDef KX_CameraActuator::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_maxHeight),
KX_PYATTRIBUTE_FLOAT_RW("height",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_height),
KX_PYATTRIBUTE_BOOL_RW("xy",KX_CameraActuator,m_x),
+ KX_PYATTRIBUTE_RW_FUNCTION("object", KX_CameraActuator, pyattr_get_object, pyattr_set_object),
{NULL}
};
-PyObject* KX_CameraActuator::_getattr(const char *attr) {
- PyObject* object;
-
- if (!strcmp(attr, "object")) {
- if (!m_ob) Py_RETURN_NONE;
- else return m_ob->AddRef();
- }
-
- object = _getattr_self(Attributes, this, attr);
- if (object != NULL)
- return object;
- _getattr_up(SCA_IActuator);
+PyObject* KX_CameraActuator::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_IActuator);
}
-int KX_CameraActuator::_setattr(const char *attr, PyObject* value) {
- int ret;
-
- if (!strcmp(attr, "object")) {
- KX_GameObject *gameobj;
-
- if (!ConvertPythonToGameObject(value, &gameobj, true))
- return 1; // ConvertPythonToGameObject sets the error
-
- if (m_ob != NULL)
- m_ob->UnregisterActuator(this);
-
- m_ob = (SCA_IObject*)gameobj;
-
- if (m_ob)
- m_ob->RegisterActuator(this);
-
- return 0;
- }
-
- ret = _setattr_self(Attributes, this, attr, value);
- if (ret >= 0)
- return ret;
- return SCA_IActuator::_setattr(attr, value);
+int KX_CameraActuator::py_setattro(PyObject *attr, PyObject* value) {
+ py_setattro_up(SCA_IActuator);
}
/* get obj ---------------------------------------------------------- */
@@ -465,13 +434,13 @@ const char KX_CameraActuator::GetObject_doc[] =
"getObject(name_only = 1)\n"
"name_only - optional arg, when true will return the KX_GameObject rather then its name\n"
"\tReturns the object this sensor reacts to.\n";
-PyObject* KX_CameraActuator::PyGetObject(PyObject* self, PyObject* args)
+PyObject* KX_CameraActuator::PyGetObject(PyObject* args)
{
int ret_name_only = 1;
ShowDeprecationWarning("getObject()", "the object property");
- if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
+ if (!PyArg_ParseTuple(args, "|i:getObject", &ret_name_only))
return NULL;
if (!m_ob)
@@ -480,20 +449,20 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* self, PyObject* args)
if (ret_name_only)
return PyString_FromString(m_ob->GetName());
else
- return m_ob->AddRef();
+ return m_ob->GetProxy();
}
/* set obj ---------------------------------------------------------- */
const char KX_CameraActuator::SetObject_doc[] =
"setObject(object)\n"
"\t- object: KX_GameObject, string or None\n"
"\tSets the object this sensor reacts to.\n";
-PyObject* KX_CameraActuator::PySetObject(PyObject* self, PyObject* value)
+PyObject* KX_CameraActuator::PySetObject(PyObject* value)
{
KX_GameObject *gameobj;
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
if (m_ob != NULL)
@@ -510,9 +479,7 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self, PyObject* value)
const char KX_CameraActuator::GetMin_doc[] =
"getMin\n"
"\tReturns the minimum value set in the Min: field.\n";
-PyObject* KX_CameraActuator::PyGetMin(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PyGetMin()
{
ShowDeprecationWarning("getMin()", "the min property");
return PyFloat_FromDouble(m_minHeight);
@@ -521,13 +488,11 @@ PyObject* KX_CameraActuator::PyGetMin(PyObject* self,
const char KX_CameraActuator::SetMin_doc[] =
"setMin\n"
"\tSets the minimum value.\n";
-PyObject* KX_CameraActuator::PySetMin(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PySetMin(PyObject* args)
{
ShowDeprecationWarning("setMin()", "the min property");
float min;
- if(PyArg_ParseTuple(args,"f", &min))
+ if(PyArg_ParseTuple(args,"f:setMin", &min))
{
m_minHeight = min;
Py_RETURN_NONE;
@@ -538,9 +503,7 @@ PyObject* KX_CameraActuator::PySetMin(PyObject* self,
const char KX_CameraActuator::GetMax_doc[] =
"getMax\n"
"\tReturns the maximum value set in the Max: field.\n";
-PyObject* KX_CameraActuator::PyGetMax(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PyGetMax()
{
ShowDeprecationWarning("getMax()", "the max property");
return PyFloat_FromDouble(m_maxHeight);
@@ -549,13 +512,11 @@ PyObject* KX_CameraActuator::PyGetMax(PyObject* self,
const char KX_CameraActuator::SetMax_doc[] =
"setMax\n"
"\tSets the maximum value.\n";
-PyObject* KX_CameraActuator::PySetMax(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PySetMax(PyObject* args)
{
ShowDeprecationWarning("getMax()", "the max property");
float max;
- if(PyArg_ParseTuple(args,"f", &max))
+ if(PyArg_ParseTuple(args,"f:setMax", &max))
{
m_maxHeight = max;
Py_RETURN_NONE;
@@ -566,9 +527,7 @@ PyObject* KX_CameraActuator::PySetMax(PyObject* self,
const char KX_CameraActuator::GetHeight_doc[] =
"getHeight\n"
"\tReturns the height value set in the height: field.\n";
-PyObject* KX_CameraActuator::PyGetHeight(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PyGetHeight()
{
ShowDeprecationWarning("getHeight()", "the height property");
return PyFloat_FromDouble(m_height);
@@ -577,13 +536,11 @@ PyObject* KX_CameraActuator::PyGetHeight(PyObject* self,
const char KX_CameraActuator::SetHeight_doc[] =
"setHeight\n"
"\tSets the height value.\n";
-PyObject* KX_CameraActuator::PySetHeight(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PySetHeight(PyObject* args)
{
ShowDeprecationWarning("getHeight()", "the height property");
float height;
- if(PyArg_ParseTuple(args,"f", &height))
+ if(PyArg_ParseTuple(args,"f:setHeight", &height))
{
m_height = height;
Py_RETURN_NONE;
@@ -595,13 +552,11 @@ const char KX_CameraActuator::SetXY_doc[] =
"setXY\n"
"\tSets axis the camera tries to get behind.\n"
"\t1=x, 0=y\n";
-PyObject* KX_CameraActuator::PySetXY(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PySetXY(PyObject* args)
{
ShowDeprecationWarning("setXY()", "the xy property");
int value;
- if(PyArg_ParseTuple(args,"i", &value))
+ if(PyArg_ParseTuple(args,"i:setXY", &value))
{
m_x = value != 0;
Py_RETURN_NONE;
@@ -614,12 +569,36 @@ const char KX_CameraActuator::GetXY_doc[] =
"getXY\n"
"\tGets the axis the camera tries to get behind.\n"
"\tTrue = X, False = Y\n";
-PyObject* KX_CameraActuator::PyGetXY(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_CameraActuator::PyGetXY()
{
ShowDeprecationWarning("getXY()", "the xy property");
return PyInt_FromLong(m_x);
}
+PyObject* KX_CameraActuator::pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_CameraActuator* self= static_cast<KX_CameraActuator*>(self_v);
+ if (self->m_ob==NULL)
+ Py_RETURN_NONE;
+ else
+ return self->m_ob->GetProxy();
+}
+
+int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_CameraActuator* self= static_cast<KX_CameraActuator*>(self_v);
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_CameraActuator"))
+ return 1; // ConvertPythonToGameObject sets the error
+
+ if (self->m_ob)
+ self->m_ob->UnregisterActuator(self);
+
+ if ((self->m_ob = (SCA_IObject*)gameobj))
+ self->m_ob->RegisterActuator(self);
+
+ return 0;
+}
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
index 3b08536fc21..9298e1e868d 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.h
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -120,21 +120,24 @@ private :
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject* value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
/* set object to look at */
KX_PYMETHOD_DOC_O(KX_CameraActuator,SetObject);
/* get current object */
KX_PYMETHOD_DOC_VARARGS(KX_CameraActuator,GetObject);
- KX_PYMETHOD_DOC(KX_CameraActuator,SetMin);
- KX_PYMETHOD_DOC(KX_CameraActuator,GetMin);
- KX_PYMETHOD_DOC(KX_CameraActuator,SetMax);
- KX_PYMETHOD_DOC(KX_CameraActuator,GetMax);
- KX_PYMETHOD_DOC(KX_CameraActuator,SetHeight);
- KX_PYMETHOD_DOC(KX_CameraActuator,GetHeight);
- KX_PYMETHOD_DOC(KX_CameraActuator,SetXY);
- KX_PYMETHOD_DOC(KX_CameraActuator,GetXY);
+ KX_PYMETHOD_DOC_VARARGS(KX_CameraActuator,SetMin);
+ KX_PYMETHOD_DOC_NOARGS(KX_CameraActuator,GetMin);
+ KX_PYMETHOD_DOC_VARARGS(KX_CameraActuator,SetMax);
+ KX_PYMETHOD_DOC_NOARGS(KX_CameraActuator,GetMax);
+ KX_PYMETHOD_DOC_VARARGS(KX_CameraActuator,SetHeight);
+ KX_PYMETHOD_DOC_NOARGS(KX_CameraActuator,GetHeight);
+ KX_PYMETHOD_DOC_VARARGS(KX_CameraActuator,SetXY);
+ KX_PYMETHOD_DOC_NOARGS(KX_CameraActuator,GetXY);
+
+ static PyObject* pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
};
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index fba9544d702..c2b4db2de8e 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -57,19 +57,21 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
char *property,
PyTypeObject* T) :
SCA_IActuator(gameobj, T),
- m_refDirection(refDir),
+ m_refDirVector(refDir),
m_currentTime(0)
{
+ m_refDirection[0] = refDir[0];
+ m_refDirection[1] = refDir[1];
+ m_refDirection[2] = refDir[2];
m_posDampTime = posDampTime;
m_rotDampTime = rotDampTime;
m_locrot = locrotxyz;
m_option = option;
m_activeTime = time;
if (property) {
- strncpy(m_property, property, sizeof(m_property));
- m_property[sizeof(m_property)-1] = 0;
+ m_property = property;
} else {
- m_property[0] = 0;
+ m_property = "";
}
/* The units of bounds are determined by the type of constraint. To */
/* make the constraint application easier and more transparent later on, */
@@ -80,13 +82,16 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
case KX_ACT_CONSTRAINT_ORIY:
case KX_ACT_CONSTRAINT_ORIZ:
{
- MT_Scalar len = m_refDirection.length();
+ MT_Scalar len = m_refDirVector.length();
if (MT_fuzzyZero(len)) {
// missing a valid direction
std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no valid reference direction!" << std::endl;
m_locrot = KX_ACT_CONSTRAINT_NODEF;
} else {
- m_refDirection /= len;
+ m_refDirection[0] /= len;
+ m_refDirection[1] /= len;
+ m_refDirection[2] /= len;
+ m_refDirVector /= len;
}
m_minimumBound = cos(minBound);
m_maximumBound = cos(maxBound);
@@ -116,7 +121,7 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, KX_RayCast* resu
bool bFound = false;
- if (m_property[0] == 0)
+ if (m_property.IsEmpty())
{
bFound = true;
}
@@ -126,7 +131,7 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, KX_RayCast* resu
{
if (client->m_auxilary_info)
{
- bFound = !strcmp(m_property, ((char*)client->m_auxilary_info));
+ bFound = !strcmp(m_property.Ptr(), ((char*)client->m_auxilary_info));
}
}
else
@@ -209,7 +214,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
if ((m_maximumBound < (1.0f-FLT_EPSILON)) || (m_minimumBound < (1.0f-FLT_EPSILON))) {
// reference direction needs to be evaluated
// 1. get the cosine between current direction and target
- cosangle = direction.dot(m_refDirection);
+ cosangle = direction.dot(m_refDirVector);
if (cosangle >= (m_maximumBound-FLT_EPSILON) && cosangle <= (m_minimumBound+FLT_EPSILON)) {
// no change to do
result = true;
@@ -218,27 +223,27 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
// 2. define a new reference direction
// compute local axis with reference direction as X and
// Y in direction X refDirection plane
- MT_Vector3 zaxis = m_refDirection.cross(direction);
+ MT_Vector3 zaxis = m_refDirVector.cross(direction);
if (MT_fuzzyZero2(zaxis.length2())) {
// direction and refDirection are identical,
// choose any other direction to define plane
if (direction[0] < 0.9999)
- zaxis = m_refDirection.cross(MT_Vector3(1.0,0.0,0.0));
+ zaxis = m_refDirVector.cross(MT_Vector3(1.0,0.0,0.0));
else
- zaxis = m_refDirection.cross(MT_Vector3(0.0,1.0,0.0));
+ zaxis = m_refDirVector.cross(MT_Vector3(0.0,1.0,0.0));
}
- MT_Vector3 yaxis = zaxis.cross(m_refDirection);
+ MT_Vector3 yaxis = zaxis.cross(m_refDirVector);
yaxis.normalize();
if (cosangle > m_minimumBound) {
// angle is too close to reference direction,
// choose a new reference that is exactly at minimum angle
- refDirection = m_minimumBound * m_refDirection + m_minimumSine * yaxis;
+ refDirection = m_minimumBound * m_refDirVector + m_minimumSine * yaxis;
} else {
// angle is too large, choose new reference direction at maximum angle
- refDirection = m_maximumBound * m_refDirection + m_maximumSine * yaxis;
+ refDirection = m_maximumBound * m_refDirVector + m_maximumSine * yaxis;
}
} else {
- refDirection = m_refDirection;
+ refDirection = m_refDirVector;
}
// apply damping on the direction
direction = filter*direction + (1.0-filter)*refDirection;
@@ -470,7 +475,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
// Fh force is stored in m_maximum
MT_Scalar springForce = springExtent * m_maximumBound;
// damping is stored in m_refDirection [0] = damping, [1] = rot damping
- MT_Scalar springDamp = relativeVelocityRay * m_refDirection[0];
+ MT_Scalar springDamp = relativeVelocityRay * m_refDirVector[0];
MT_Vector3 newVelocity = spc->GetLinearVelocity()-(springForce+springDamp)*direction;
if (m_option & KX_ACT_CONSTRAINT_NORMAL)
{
@@ -483,7 +488,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
MT_Vector3 angVelocity = spc->GetAngularVelocity();
// remove component that is parallel to normal
angVelocity -= angVelocity.dot(newnormal)*newnormal;
- MT_Vector3 angDamp = angVelocity * ((m_refDirection[1]>MT_EPSILON)?m_refDirection[1]:m_refDirection[0]);
+ MT_Vector3 angDamp = angVelocity * ((m_refDirVector[1]>MT_EPSILON)?m_refDirVector[1]:m_refDirVector[0]);
spc->SetAngularVelocity(spc->GetAngularVelocity()+(angSpring-angDamp), false);
}
} else if (m_option & KX_ACT_CONSTRAINT_PERMANENT) {
@@ -560,22 +565,22 @@ bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_ConstraintActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_ConstraintActuator",
- sizeof(KX_ConstraintActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_ConstraintActuator::Parents[] = {
@@ -587,6 +592,7 @@ PyParentObject KX_ConstraintActuator::Parents[] = {
};
PyMethodDef KX_ConstraintActuator::Methods[] = {
+ // Deprecated -->
{"setDamp", (PyCFunction) KX_ConstraintActuator::sPySetDamp, METH_VARARGS, (PY_METHODCHAR)SetDamp_doc},
{"getDamp", (PyCFunction) KX_ConstraintActuator::sPyGetDamp, METH_NOARGS, (PY_METHODCHAR)GetDamp_doc},
{"setRotDamp", (PyCFunction) KX_ConstraintActuator::sPySetRotDamp, METH_VARARGS, (PY_METHODCHAR)SetRotDamp_doc},
@@ -609,15 +615,47 @@ PyMethodDef KX_ConstraintActuator::Methods[] = {
{"getRayLength", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_NOARGS, (PY_METHODCHAR)GetRayLength_doc},
{"setLimit", (PyCFunction) KX_ConstraintActuator::sPySetLimit, METH_VARARGS, (PY_METHODCHAR)SetLimit_doc},
{"getLimit", (PyCFunction) KX_ConstraintActuator::sPyGetLimit, METH_NOARGS, (PY_METHODCHAR)GetLimit_doc},
+ // <--
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_ConstraintActuator::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RW("damp",0,100,true,KX_ConstraintActuator,m_posDampTime),
+ KX_PYATTRIBUTE_INT_RW("rotDamp",0,100,true,KX_ConstraintActuator,m_rotDampTime),
+ KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK("direction",-FLT_MAX,FLT_MAX,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_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_minimumBound),
+ KX_PYATTRIBUTE_FLOAT_RW("distance",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_minimumBound),
+ KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_maximumBound),
+ KX_PYATTRIBUTE_FLOAT_RW("rayLength",0,2000.f,KX_ConstraintActuator,m_maximumBound),
+ KX_PYATTRIBUTE_INT_RW("limit",KX_ConstraintActuator::KX_ACT_CONSTRAINT_NODEF+1,KX_ConstraintActuator::KX_ACT_CONSTRAINT_MAX-1,false,KX_ConstraintActuator,m_locrot),
{ NULL } //Sentinel
};
-PyObject* KX_ConstraintActuator::_getattr(const char *attr) {
- _getattr_up(SCA_IActuator);
+PyObject* KX_ConstraintActuator::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_IActuator);
+}
+
+int KX_ConstraintActuator::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IActuator);
+}
+
+
+int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ConstraintActuator* act = static_cast<KX_ConstraintActuator*>(self);
+ MT_Vector3 dir(act->m_refDirection);
+ MT_Scalar len = dir.length();
+ if (MT_fuzzyZero(len)) {
+ PyErr_SetString(PyExc_ValueError, "actuator.direction = vec: KX_ConstraintActuator, invalid direction");
+ return 1;
+ }
+ act->m_refDirVector = dir/len;
+ return 0;
}
/* 2. setDamp */
@@ -626,11 +664,10 @@ const char KX_ConstraintActuator::SetDamp_doc[] =
"\t- duration: integer\n"
"\tSets the time constant of the orientation and distance constraint.\n"
"\tIf the duration is negative, it is set to 0.\n";
-PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetDamp(PyObject* args) {
+ ShowDeprecationWarning("setDamp()", "the damp property");
int dampArg;
- if(!PyArg_ParseTuple(args, "i", &dampArg)) {
+ if(!PyArg_ParseTuple(args, "i:setDamp", &dampArg)) {
return NULL;
}
@@ -643,7 +680,8 @@ PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
const char KX_ConstraintActuator::GetDamp_doc[] =
"getDamp()\n"
"\tReturns the damping parameter.\n";
-PyObject* KX_ConstraintActuator::PyGetDamp(PyObject* self){
+PyObject* KX_ConstraintActuator::PyGetDamp(){
+ ShowDeprecationWarning("getDamp()", "the damp property");
return PyInt_FromLong(m_posDampTime);
}
@@ -653,11 +691,10 @@ const char KX_ConstraintActuator::SetRotDamp_doc[] =
"\t- duration: integer\n"
"\tSets the time constant of the orientation constraint.\n"
"\tIf the duration is negative, it is set to 0.\n";
-PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* args) {
+ ShowDeprecationWarning("setRotDamp()", "the rotDamp property");
int dampArg;
- if(!PyArg_ParseTuple(args, "i", &dampArg)) {
+ if(!PyArg_ParseTuple(args, "i:setRotDamp", &dampArg)) {
return NULL;
}
@@ -670,7 +707,8 @@ PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self,
const char KX_ConstraintActuator::GetRotDamp_doc[] =
"getRotDamp()\n"
"\tReturns the damping time for application of the constraint.\n";
-PyObject* KX_ConstraintActuator::PyGetRotDamp(PyObject* self){
+PyObject* KX_ConstraintActuator::PyGetRotDamp(){
+ ShowDeprecationWarning("getRotDamp()", "the rotDamp property");
return PyInt_FromLong(m_rotDampTime);
}
@@ -679,14 +717,13 @@ const char KX_ConstraintActuator::SetDirection_doc[] =
"setDirection(vector)\n"
"\t- vector: 3-tuple\n"
"\tSets the reference direction in world coordinate for the orientation constraint.\n";
-PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetDirection(PyObject* args) {
+ ShowDeprecationWarning("setDirection()", "the direction property");
float x, y, z;
MT_Scalar len;
MT_Vector3 dir;
- if(!PyArg_ParseTuple(args, "(fff)", &x, &y, &z)) {
+ if(!PyArg_ParseTuple(args, "(fff):setDirection", &x, &y, &z)) {
return NULL;
}
dir[0] = x;
@@ -697,7 +734,10 @@ PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
std::cout << "Invalid direction" << std::endl;
return NULL;
}
- m_refDirection = dir/len;
+ m_refDirVector = dir/len;
+ m_refDirection[0] = x/len;
+ m_refDirection[1] = y/len;
+ m_refDirection[2] = z/len;
Py_RETURN_NONE;
}
@@ -705,7 +745,8 @@ PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
const char KX_ConstraintActuator::GetDirection_doc[] =
"getDirection()\n"
"\tReturns the reference direction of the orientation constraint as a 3-tuple.\n";
-PyObject* KX_ConstraintActuator::PyGetDirection(PyObject* self){
+PyObject* KX_ConstraintActuator::PyGetDirection(){
+ ShowDeprecationWarning("getDirection()", "the direction property");
PyObject *retVal = PyList_New(3);
PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_refDirection[0]));
@@ -724,11 +765,10 @@ const char KX_ConstraintActuator::SetOption_doc[] =
"\t\t128 : Detect material rather than property\n"
"\t\t256 : No deactivation if ray does not hit target\n"
"\t\t512 : Activate distance control\n";
-PyObject* KX_ConstraintActuator::PySetOption(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetOption(PyObject* args) {
+ ShowDeprecationWarning("setOption()", "the option property");
int option;
- if(!PyArg_ParseTuple(args, "i", &option)) {
+ if(!PyArg_ParseTuple(args, "i:setOption", &option)) {
return NULL;
}
@@ -740,7 +780,8 @@ PyObject* KX_ConstraintActuator::PySetOption(PyObject* self,
const char KX_ConstraintActuator::GetOption_doc[] =
"getOption()\n"
"\tReturns the option parameter.\n";
-PyObject* KX_ConstraintActuator::PyGetOption(PyObject* self){
+PyObject* KX_ConstraintActuator::PyGetOption(){
+ ShowDeprecationWarning("getOption()", "the option property");
return PyInt_FromLong(m_option);
}
@@ -751,11 +792,10 @@ const char KX_ConstraintActuator::SetTime_doc[] =
"\tSets the activation time of the actuator.\n"
"\tThe actuator disables itself after this many frame.\n"
"\tIf set to 0 or negative, the actuator is not limited in time.\n";
-PyObject* KX_ConstraintActuator::PySetTime(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetTime(PyObject* args) {
+ ShowDeprecationWarning("setTime()", "the time property");
int t;
- if(!PyArg_ParseTuple(args, "i", &t)) {
+ if(!PyArg_ParseTuple(args, "i:setTime", &t)) {
return NULL;
}
@@ -769,7 +809,8 @@ PyObject* KX_ConstraintActuator::PySetTime(PyObject* self,
const char KX_ConstraintActuator::GetTime_doc[] =
"getTime()\n"
"\tReturns the time parameter.\n";
-PyObject* KX_ConstraintActuator::PyGetTime(PyObject* self){
+PyObject* KX_ConstraintActuator::PyGetTime(){
+ ShowDeprecationWarning("getTime()", "the time property");
return PyInt_FromLong(m_activeTime);
}
@@ -779,18 +820,16 @@ const char KX_ConstraintActuator::SetProperty_doc[] =
"\t- property: string\n"
"\tSets the name of the property or material for the ray detection of the distance constraint.\n"
"\tIf empty, the ray will detect any collisioning object.\n";
-PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetProperty(PyObject* args) {
+ ShowDeprecationWarning("setProperty()", "the 'property' property");
char *property;
- if (!PyArg_ParseTuple(args, "s", &property)) {
+ if (!PyArg_ParseTuple(args, "s:setProperty", &property)) {
return NULL;
}
if (property == NULL) {
- m_property[0] = 0;
+ m_property = "";
} else {
- strncpy(m_property, property, sizeof(m_property));
- m_property[sizeof(m_property)-1] = 0;
+ m_property = property;
}
Py_RETURN_NONE;
@@ -799,8 +838,9 @@ PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self,
const char KX_ConstraintActuator::GetProperty_doc[] =
"getProperty()\n"
"\tReturns the property parameter.\n";
-PyObject* KX_ConstraintActuator::PyGetProperty(PyObject* self){
- return PyString_FromString(m_property);
+PyObject* KX_ConstraintActuator::PyGetProperty(){
+ ShowDeprecationWarning("getProperty()", "the 'property' property");
+ return PyString_FromString(m_property.Ptr());
}
/* 4. setDistance */
@@ -814,11 +854,10 @@ const char KX_ConstraintActuator::SetMin_doc[] =
"\t- lower_bound: float\n"
"\tSets the lower value of the interval to which the value\n"
"\tis clipped.\n";
-PyObject* KX_ConstraintActuator::PySetMin(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetMin(PyObject* args) {
+ ShowDeprecationWarning("setMin() or setDistance()", "the min or distance property");
float minArg;
- if(!PyArg_ParseTuple(args, "f", &minArg)) {
+ if(!PyArg_ParseTuple(args, "f:setMin", &minArg)) {
return NULL;
}
@@ -844,7 +883,8 @@ const char KX_ConstraintActuator::GetMin_doc[] =
"getMin()\n"
"\tReturns the lower value of the interval to which the value\n"
"\tis clipped.\n";
-PyObject* KX_ConstraintActuator::PyGetMin(PyObject* self) {
+PyObject* KX_ConstraintActuator::PyGetMin() {
+ ShowDeprecationWarning("getMin() or getDistance()", "the min or distance property");
return PyFloat_FromDouble(m_minimumBound);
}
@@ -859,11 +899,10 @@ const char KX_ConstraintActuator::SetMax_doc[] =
"\t- upper_bound: float\n"
"\tSets the upper value of the interval to which the value\n"
"\tis clipped.\n";
-PyObject* KX_ConstraintActuator::PySetMax(PyObject* self,
- PyObject* args,
- PyObject* kwds){
+PyObject* KX_ConstraintActuator::PySetMax(PyObject* args){
+ ShowDeprecationWarning("setMax() or setRayLength()", "the max or rayLength property");
float maxArg;
- if(!PyArg_ParseTuple(args, "f", &maxArg)) {
+ if(!PyArg_ParseTuple(args, "f:setMax", &maxArg)) {
return NULL;
}
@@ -889,7 +928,8 @@ const char KX_ConstraintActuator::GetMax_doc[] =
"getMax()\n"
"\tReturns the upper value of the interval to which the value\n"
"\tis clipped.\n";
-PyObject* KX_ConstraintActuator::PyGetMax(PyObject* self) {
+PyObject* KX_ConstraintActuator::PyGetMax() {
+ ShowDeprecationWarning("getMax() or getRayLength()", "the max or rayLength property");
return PyFloat_FromDouble(m_maximumBound);
}
@@ -912,11 +952,10 @@ const char KX_ConstraintActuator::SetLimit_doc[] =
"\t 14 : Align Y axis\n"
"\t 15 : Align Z axis\n"
"\tSets the type of constraint.\n";
-PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ConstraintActuator::PySetLimit(PyObject* args) {
+ ShowDeprecationWarning("setLimit()", "the limit property");
int locrotArg;
- if(!PyArg_ParseTuple(args, "i", &locrotArg)) {
+ if(!PyArg_ParseTuple(args, "i:setLimit", &locrotArg)) {
return NULL;
}
@@ -928,7 +967,8 @@ PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
const char KX_ConstraintActuator::GetLimit_doc[] =
"getLimit()\n"
"\tReturns the type of constraint.\n";
-PyObject* KX_ConstraintActuator::PyGetLimit(PyObject* self) {
+PyObject* KX_ConstraintActuator::PyGetLimit() {
+ ShowDeprecationWarning("setLimit()", "the limit property");
return PyInt_FromLong(m_locrot);
}
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index 132b8a7328a..98f6fcd7906 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -56,7 +56,8 @@ protected:
// sinus of maximum angle
float m_maximumSine;
// reference direction
- MT_Vector3 m_refDirection;
+ float m_refDirection[3];
+ MT_Vector3 m_refDirVector; // same as m_refDirection
// locrotxyz choice (pick one): only one choice allowed at a time!
int m_locrot;
// active time of actuator
@@ -65,7 +66,7 @@ protected:
// option
int m_option;
// property to check
- char m_property[32];
+ STR_String m_property;
// hit object
KX_GameObject* m_hitObject;
@@ -142,29 +143,33 @@ protected:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp);
+ static int pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_check_min(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetDamp);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetDamp);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetRotDamp);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetRotDamp);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetRotDamp);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDirection);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetDirection);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetDirection);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetOption);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetOption);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetOption);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetTime);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetTime);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetTime);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetProperty);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetProperty);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetProperty);
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMin);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetMin);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetMin);
static const char SetDistance_doc[];
static const char GetDistance_doc[];
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMax);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetMax);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetMax);
static const char SetRayLength_doc[];
static const char GetRayLength_doc[];
- KX_PYMETHOD_DOC(KX_ConstraintActuator,SetLimit);
+ KX_PYMETHOD_DOC_VARARGS(KX_ConstraintActuator,SetLimit);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetLimit);
};
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
index f014c1896fe..7c3abb49159 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
@@ -49,17 +49,12 @@ KX_ConstraintWrapper::~KX_ConstraintWrapper()
{
}
//python integration methods
-PyObject* KX_ConstraintWrapper::PyTestMethod(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ConstraintWrapper::PyTestMethod(PyObject* args, PyObject* kwds)
{
-
Py_RETURN_NONE;
}
-PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds)
{
return PyInt_FromLong(m_constraintId);
}
@@ -69,22 +64,22 @@ PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* self,
//python specific stuff
PyTypeObject KX_ConstraintWrapper::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_ConstraintWrapper",
- sizeof(KX_ConstraintWrapper),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_ConstraintWrapper::Parents[] = {
@@ -92,16 +87,16 @@ PyParentObject KX_ConstraintWrapper::Parents[] = {
NULL
};
-PyObject* KX_ConstraintWrapper::_getattr(const char *attr)
+PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr)
{
//here you can search for existing data members (like mass,friction etc.)
- _getattr_up(PyObjectPlus);
+ py_getattro_up(PyObjectPlus);
}
-int KX_ConstraintWrapper::_setattr(const char *attr,PyObject* pyobj)
+int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* pyobj)
{
int result = 1;
-
+ /* what the heck is this supposed to do?, needs attention */
if (PyList_Check(pyobj))
{
result = 0;
@@ -120,7 +115,7 @@ int KX_ConstraintWrapper::_setattr(const char *attr,PyObject* pyobj)
result = 0;
}
if (result)
- result = PyObjectPlus::_setattr(attr,pyobj);
+ result = PyObjectPlus::py_setattro(attr,pyobj);
return result;
};
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
index 36606d2d67b..6e67d842cb6 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
@@ -35,8 +35,8 @@
class KX_ConstraintWrapper : public PyObjectPlus
{
Py_Header;
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
public:
KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
virtual ~KX_ConstraintWrapper ();
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 602486e0017..08e2ea30414 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -801,6 +801,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_gravity = btVector3(0,0,0);
ci.m_localInertiaTensor =btVector3(0,0,0);
ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
+ ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
+ ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
ci.m_margin = objprop->m_margin;
shapeInfo->m_radius = objprop->m_radius;
isbulletdyna = objprop->m_dyna;
@@ -881,8 +883,10 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
{
shapeInfo->SetMesh(meshobj, false,false);
}
+
+ // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
if (objprop->m_softbody)
- shapeInfo->setVertexWeldingThreshold(0.01f); //todo: expose this to the UI
+ shapeInfo->setVertexWeldingThreshold1(0.01f); //todo: expose this to the UI
bm = shapeInfo->CreateBulletShape();
//no moving concave meshes, so don't bother calculating inertia
@@ -1103,16 +1107,19 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
if (rbody)
{
- btVector3 linearFactor(
- objprop->m_lockXaxis? 0 : 1,
- objprop->m_lockYaxis? 0 : 1,
- objprop->m_lockZaxis? 0 : 1);
- btVector3 angularFactor(
- objprop->m_lockXRotaxis? 0 : 1,
- objprop->m_lockYRotaxis? 0 : 1,
- objprop->m_lockZRotaxis? 0 : 1);
- rbody->setLinearFactor(linearFactor);
- rbody->setAngularFactor(angularFactor);
+ if (objprop->m_angular_rigidbody)
+ {
+ btVector3 linearFactor(
+ objprop->m_lockXaxis? 0 : 1,
+ objprop->m_lockYaxis? 0 : 1,
+ objprop->m_lockZaxis? 0 : 1);
+ btVector3 angularFactor(
+ objprop->m_lockXRotaxis? 0 : 1,
+ objprop->m_lockYRotaxis? 0 : 1,
+ objprop->m_lockZRotaxis? 0 : 1);
+ rbody->setLinearFactor(linearFactor);
+ rbody->setAngularFactor(angularFactor);
+ }
if (rbody && objprop->m_disableSleeping)
{
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
new file mode 100644
index 00000000000..321370f9f3f
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -0,0 +1,1819 @@
+/* $Id$
+-----------------------------------------------------------------------------
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser 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, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+
+Contributor(s): Dalai Felinto
+
+This code is originally inspired on some of the ideas and codes from Paul Bourke.
+Developed as part of a Research and Development project for SAT - La Société des arts technologiques.
+-----------------------------------------------------------------------------
+*/
+
+#include "KX_Dome.h"
+
+#include <structmember.h>
+#include <float.h>
+#include <math.h>
+
+#include "DNA_scene_types.h"
+#include "RAS_CameraData.h"
+#include "BLI_arithb.h"
+
+#include "GL/glew.h"
+
+// constructor
+KX_Dome::KX_Dome (
+ RAS_ICanvas* canvas,
+ /// rasterizer
+ RAS_IRasterizer* rasterizer,
+ /// render tools
+ 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
+ struct Text* warptext
+
+):
+ m_canvas(canvas),
+ m_rasterizer(rasterizer),
+ m_rendertools(rendertools),
+ m_engine(engine),
+ 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)
+{
+ warp.usemesh = false;
+
+ if (mode >= DOME_NUM_MODES)
+ m_mode = DOME_FISHEYE;
+
+ if (warptext) // it there is a text data try to warp it
+ {
+ char *buf;
+ buf = txt_to_buf(warptext);
+ if (buf)
+ {
+ warp.usemesh = ParseWarpMesh(STR_String(buf));
+ MEM_freeN(buf);
+ }
+ }
+
+ //setting the viewport size
+ GLuint viewport[4]={0};
+ glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
+
+ SetViewPort(viewport);
+
+ switch(m_mode){
+ case DOME_FISHEYE:
+ if (m_angle <= 180){
+ cubetop.resize(1);
+ cubebottom.resize(1);
+ cubeleft.resize(2);
+ cuberight.resize(2);
+
+ 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;
+ case DOME_TRUNCATED:
+ cubetop.resize(1);
+ cubebottom.resize(1);
+ cubeleft.resize(2);
+ cuberight.resize(2);
+
+ m_angle = 180;
+ CreateMeshDome180();
+ m_numfaces = 4;
+ break;
+ case DOME_PANORAM_SPH:
+ cubeleft.resize(2);
+ cubeleftback.resize(2);
+ cuberight.resize(2);
+ cuberightback.resize(2);
+ cubetop.resize(2);
+ cubebottom.resize(2);
+
+ m_angle = 360;
+ CreateMeshPanorama();
+ m_numfaces = 6;
+ break;
+ }
+
+ m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces);
+
+ CalculateCameraOrientation();
+
+ CreateGLImages();
+
+ dlistSupported = CreateDL();
+}
+
+// destructor
+KX_Dome::~KX_Dome (void)
+{
+ GLuint m_numimages = m_numfaces;
+
+ ClearGLImages();
+
+ if(dlistSupported)
+ glDeleteLists(dlistId, (GLsizei) m_numimages);
+}
+
+void KX_Dome::SetViewPort(GLuint viewport[4])
+{
+ if(canvaswidth != m_canvas->GetWidth() || canvasheight != m_canvas->GetHeight())
+ {
+ m_viewport.SetLeft(viewport[0]);
+ m_viewport.SetBottom(viewport[1]);
+ m_viewport.SetRight(viewport[2]);
+ m_viewport.SetTop(viewport[3]);
+
+ CalculateImageSize();
+ }
+}
+
+void KX_Dome::CreateGLImages(void)
+{
+ glGenTextures(m_numimages, (GLuint*)&domefacesId);
+
+ for (int j=0;j<m_numfaces;j++){
+ glBindTexture(GL_TEXTURE_2D, domefacesId[j]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_imagesize, m_imagesize, 0, GL_RGB8,
+ GL_UNSIGNED_BYTE, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, m_imagesize, m_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);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+ if(warp.usemesh){
+ glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagewidth, warp.imageheight, 0, GL_RGB8,
+ GL_UNSIGNED_BYTE, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagewidth, warp.imageheight, 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);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+}
+
+void KX_Dome::ClearGLImages(void)
+{
+ glDeleteTextures(m_numimages, (GLuint*)&domefacesId);
+/*
+ for (int i=0;i<m_numimages;i++)
+ if(glIsTexture(domefacesId[i]))
+ glDeleteTextures(1, (GLuint*)&domefacesId[i]);
+*/
+}
+
+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
+*/
+
+ canvaswidth = m_canvas->GetWidth();
+ canvasheight = m_canvas->GetHeight();
+
+ m_buffersize = (canvaswidth > canvasheight?canvasheight:canvaswidth);
+ m_buffersize *= m_resbuffer; //reduce buffer size for better performance
+
+ int i = 0;
+ while ((1 << i) <= m_buffersize)
+ i++;
+ m_imagesize = (1 << i);
+
+ if (warp.usemesh){
+ 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);
+ }
+}
+
+bool KX_Dome::CreateDL(){
+ int i,j;
+
+ dlistId = glGenLists((GLsizei) m_numimages);
+ if (dlistId != 0) {
+ if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED){
+ glNewList(dlistId, GL_COMPILE);
+ GLDrawTriangles(cubetop, nfacestop);
+ glEndList();
+
+ glNewList(dlistId+1, GL_COMPILE);
+ GLDrawTriangles(cubebottom, nfacesbottom);
+ glEndList();
+
+ glNewList(dlistId+2, GL_COMPILE);
+ GLDrawTriangles(cubeleft, nfacesleft);
+ glEndList();
+
+ glNewList(dlistId+3, GL_COMPILE);
+ GLDrawTriangles(cuberight, nfacesright);
+ glEndList();
+
+ if (m_angle > 180){
+ glNewList(dlistId+4, GL_COMPILE);
+ GLDrawTriangles(cubefront, nfacesfront);
+ glEndList();
+ }
+ }
+ else if (m_mode == DOME_PANORAM_SPH)
+ {
+ glNewList(dlistId, GL_COMPILE);
+ GLDrawTriangles(cubetop, nfacestop);
+ glEndList();
+
+ glNewList(dlistId+1, GL_COMPILE);
+ GLDrawTriangles(cubebottom, nfacesbottom);
+ glEndList();
+
+ glNewList(dlistId+2, GL_COMPILE);
+ GLDrawTriangles(cubeleft, nfacesleft);
+ glEndList();
+
+ glNewList(dlistId+3, GL_COMPILE);
+ GLDrawTriangles(cuberight, nfacesright);
+ glEndList();
+
+ glNewList(dlistId+4, GL_COMPILE);
+ GLDrawTriangles(cubeleftback, nfacesleftback);
+ glEndList();
+
+ glNewList(dlistId+5, GL_COMPILE);
+ GLDrawTriangles(cuberightback, nfacesrightback);
+ glEndList();
+ }
+
+ if(warp.usemesh){
+ glNewList((dlistId + m_numfaces), GL_COMPILE);
+ GLDrawWarpQuads();
+ glEndList();
+ }
+
+ //clearing the vectors
+ cubetop.clear();
+ cubebottom.clear();
+ cuberight.clear();
+ cubeleft.clear();
+ cubefront.clear();
+ cubeleftback.clear();
+ cuberightback.clear();
+ warp.nodes.clear();
+
+ } else // genList failed
+ return false;
+
+ return true;
+}
+
+void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces)
+{
+ int i,j;
+ glBegin(GL_TRIANGLES);
+ for (i=0;i<nfaces;i++) {
+ for (j=0;j<3;j++) {
+ glTexCoord2f(face[i].u[j],face[i].v[j]);
+ glVertex3f((GLfloat)face[i].verts[j][0],(GLfloat)face[i].verts[j][1],(GLfloat)face[i].verts[j][2]);
+ }
+ }
+ glEnd();
+}
+
+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;
+
+ if(warp.mode ==2 ){
+ glBegin(GL_QUADS);
+ for (i=0;i<warp.n_height-1;i++) {
+ for (j=0;j<warp.n_width-1;j++) {
+ if(warp.nodes[i][j].i < 0 || warp.nodes[i+1][j].i < 0 || warp.nodes[i+1][j+1].i < 0 || warp.nodes[i][j+1].i < 0)
+ continue;
+
+ glColor3f(warp.nodes[i][j].i, warp.nodes[i][j].i, warp.nodes[i][j].i);
+ glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height));
+ glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0);
+
+ glColor3f(warp.nodes[i+1][j].i, warp.nodes[i+1][j].i, warp.nodes[i+1][j].i);
+ glTexCoord2f((warp.nodes[i+1][j].u * uv_width), (warp.nodes[i+1][j].v * uv_height));
+ glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0);
+
+ glColor3f(warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i);
+ glTexCoord2f((warp.nodes[i+1][j+1].u * uv_width), (warp.nodes[i+1][j+1].v * uv_height));
+ glVertex3f(warp.nodes[i+1][j+1].x, warp.nodes[i+1][j+1].y,0.0);
+
+ glColor3f(warp.nodes[i][j+1].i, warp.nodes[i][j+1].i, warp.nodes[i][j+1].i);
+ glTexCoord2f((warp.nodes[i][j+1].u * uv_width), (warp.nodes[i][j+1].v * uv_height));
+ glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0);
+ }
+ }
+ glEnd();
+ }
+ else if (warp.mode == 1){
+ glBegin(GL_QUADS);
+ for (i=0;i<warp.n_height-1;i++) {
+ for (j=0;j<warp.n_width-1;j++) {
+ i2 = (i+1) % warp.n_width; // Wrap around, i = warp.n_width = 0
+
+ if (warp.nodes[i][j].i < 0 || warp.nodes[i2][j].i < 0 || warp.nodes[i2][j+1].i < 0 || warp.nodes[i][j+1].i < 0)
+ continue;
+
+ glColor3f(warp.nodes[i][j].i,warp.nodes[i][j].i,warp.nodes[i][j].i);
+ glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height));
+ glVertex3f(warp.nodes[i][j].x,warp.nodes[i][j].y,0.0);
+
+ glColor3f(warp.nodes[i2][j].i,warp.nodes[i2][j].i,warp.nodes[i2][j].i);
+ glTexCoord2f((warp.nodes[i2][j].u * uv_width), (warp.nodes[i2][j].v * uv_height));
+ glVertex3f(warp.nodes[i2][j].x,warp.nodes[i2][j].y,0.0);
+
+ glColor3f(warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i);
+ glTexCoord2f((warp.nodes[i2][j+1].u * uv_width), (warp.nodes[i2][j+1].v * uv_height));
+ glVertex3f(warp.nodes[i2][j+1].x,warp.nodes[i2][j+1].y,0.0);
+
+ glColor3f(warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i);
+ glTexCoord2f((warp.nodes[i2][j+1].u * uv_width), (warp.nodes[i2][j+1].v * uv_height));
+ glVertex3f(warp.nodes[i2][j+1].x,warp.nodes[i2][j+1].y,0.0);
+
+ }
+ }
+ glEnd();
+ } else{
+ printf("Error: Warp Mode unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n");
+ }
+}
+
+
+bool KX_Dome::ParseWarpMesh(STR_String text)
+{
+/*
+//Notes about the supported data format:
+File example::
+ mode
+ width height
+ n0_x n0_y n0_u n0_v n0_i
+ n1_x n1_y n1_u n1_v n1_i
+ n2_x n1_y n2_u n2_v n2_i
+ n3_x n3_y n3_u n3_v n3_i
+ (...)
+First line is the image type the mesh is support to be applied to: 2 = fisheye, 1=radial
+Tthe next line has the mesh dimensions
+Rest of the lines are the nodes of the mesh. Each line has x y u v i
+ (x,y) are the normalised screen coordinates
+ (u,v) texture coordinates
+ i a multiplicative intensity factor
+
+x varies from -screen aspect to screen aspect
+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 nodeX=0, nodeY=0;
+
+ vector<STR_String> columns, lines;
+
+ lines = text.Explode('\n');
+ if(lines.size() < 6){
+ printf("Error: Warp Mesh File with insufficient data!\n");
+ return false;
+ }
+ columns = lines[1].Explode(' ');
+
+ if(columns.size() !=2){
+ printf("Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
+ return false;
+ }
+
+ warp.mode = atoi(lines[0]);// 1 = radial, 2 = fisheye
+
+ warp.n_width = atoi(columns[0]);
+ warp.n_height = atoi(columns[1]);
+
+ if (lines.size() < 2 + (warp.n_width * warp.n_height)){
+ printf("Error: Warp Mesh File with insufficient data!\n");
+ return false;
+ }else{
+ warp.nodes = vector<vector<WarpMeshNode> > (warp.n_height, vector<WarpMeshNode>(warp.n_width));
+
+ for(i=2; i-2 < (warp.n_width*warp.n_height); i++){
+ columns = lines[i].Explode(' ');
+
+ if (columns.size() == 5){
+ nodeX = (i-2)%warp.n_width;
+ nodeY = ((i-2) - nodeX) / warp.n_width;
+
+ warp.nodes[nodeY][nodeX].x = atof(columns[0]);
+ warp.nodes[nodeY][nodeX].y = atof(columns[1]);
+ warp.nodes[nodeY][nodeX].u = atof(columns[2]);
+ warp.nodes[nodeY][nodeX].v = atof(columns[3]);
+ warp.nodes[nodeY][nodeX].i = atof(columns[4]);
+ }
+ else{
+ warp.nodes.clear();
+ printf("Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void KX_Dome::CreateMeshDome180(void)
+{
+/*
+1)- Define the faces of half of a cube
+ - each face is made out of 2 triangles
+2) Subdivide the faces
+ - more resolution == more curved lines
+3) Spherize the cube
+ - normalize the verts
+4) Flatten onto xz plane
+ - transform it onto an equidistant spherical projection techniques to transform the sphere onto a dome image
+*/
+ int i,j;
+ float sqrt_2 = sqrt(2.0);
+ float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
+
+ m_radangle = m_angle * M_PI/180.0;//calculates the radians angle, used for flattening
+
+ //creating faces for the env mapcube 180º Dome
+ // Top Face - just a triangle
+ cubetop[0].verts[0][0] = -sqrt_2 / 2.0;
+ cubetop[0].verts[0][1] = 0.0;
+ cubetop[0].verts[0][2] = 0.5;
+ cubetop[0].u[0] = 0.0;
+ cubetop[0].v[0] = uv_ratio;
+
+ cubetop[0].verts[1][0] = 0.0;
+ cubetop[0].verts[1][1] = sqrt_2 / 2.0;
+ cubetop[0].verts[1][2] = 0.5;
+ cubetop[0].u[1] = 0.0;
+ cubetop[0].v[1] = 0.0;
+
+ cubetop[0].verts[2][0] = sqrt_2 / 2.0;
+ cubetop[0].verts[2][1] = 0.0;
+ cubetop[0].verts[2][2] = 0.5;
+ cubetop[0].u[2] = uv_ratio;
+ cubetop[0].v[2] = 0.0;
+
+ nfacestop = 1;
+
+ /* Bottom face - just a triangle */
+ cubebottom[0].verts[0][0] = -sqrt_2 / 2.0;
+ cubebottom[0].verts[0][1] = 0.0;
+ cubebottom[0].verts[0][2] = -0.5;
+ cubebottom[0].u[0] = uv_ratio;
+ cubebottom[0].v[0] = 0.0;
+
+ cubebottom[0].verts[1][0] = sqrt_2 / 2.0;
+ cubebottom[0].verts[1][1] = 0;
+ cubebottom[0].verts[1][2] = -0.5;
+ cubebottom[0].u[1] = 0.0;
+ cubebottom[0].v[1] = uv_ratio;
+
+ cubebottom[0].verts[2][0] = 0.0;
+ cubebottom[0].verts[2][1] = sqrt_2 / 2.0;
+ cubebottom[0].verts[2][2] = -0.5;
+ cubebottom[0].u[2] = 0.0;
+ cubebottom[0].v[2] = 0.0;
+
+ nfacesbottom = 1;
+
+ /* Left face - two triangles */
+
+ cubeleft[0].verts[0][0] = -sqrt_2 / 2.0;
+ cubeleft[0].verts[0][1] = .0;
+ cubeleft[0].verts[0][2] = -0.5;
+ cubeleft[0].u[0] = 0.0;
+ cubeleft[0].v[0] = 0.0;
+
+ cubeleft[0].verts[1][0] = 0.0;
+ cubeleft[0].verts[1][1] = sqrt_2 / 2.0;
+ cubeleft[0].verts[1][2] = -0.5;
+ cubeleft[0].u[1] = uv_ratio;
+ cubeleft[0].v[1] = 0.0;
+
+ cubeleft[0].verts[2][0] = -sqrt_2 / 2.0;
+ cubeleft[0].verts[2][1] = 0.0;
+ cubeleft[0].verts[2][2] = 0.5;
+ cubeleft[0].u[2] = 0.0;
+ cubeleft[0].v[2] = uv_ratio;
+
+ //second triangle
+ cubeleft[1].verts[0][0] = -sqrt_2 / 2.0;
+ cubeleft[1].verts[0][1] = 0.0;
+ cubeleft[1].verts[0][2] = 0.5;
+ cubeleft[1].u[0] = 0.0;
+ cubeleft[1].v[0] = uv_ratio;
+
+ cubeleft[1].verts[1][0] = 0.0;
+ cubeleft[1].verts[1][1] = sqrt_2 / 2.0;
+ cubeleft[1].verts[1][2] = -0.5;
+ cubeleft[1].u[1] = uv_ratio;
+ cubeleft[1].v[1] = 0.0;
+
+ cubeleft[1].verts[2][0] = 0.0;
+ cubeleft[1].verts[2][1] = sqrt_2 / 2.0;
+ cubeleft[1].verts[2][2] = 0.5;
+ cubeleft[1].u[2] = uv_ratio;
+ cubeleft[1].v[2] = uv_ratio;
+
+ nfacesleft = 2;
+
+ /* Right face - two triangles */
+ cuberight[0].verts[0][0] = 0.0;
+ cuberight[0].verts[0][1] = sqrt_2 / 2.0;
+ cuberight[0].verts[0][2] = -0.5;
+ cuberight[0].u[0] = 0.0;
+ cuberight[0].v[0] = 0.0;
+
+ cuberight[0].verts[1][0] = sqrt_2 / 2.0;
+ cuberight[0].verts[1][1] = 0.0;
+ cuberight[0].verts[1][2] = -0.5;
+ cuberight[0].u[1] = uv_ratio;
+ cuberight[0].v[1] = 0.0;
+
+ cuberight[0].verts[2][0] = sqrt_2 / 2.0;
+ cuberight[0].verts[2][1] = 0.0;
+ cuberight[0].verts[2][2] = 0.5;
+ cuberight[0].u[2] = uv_ratio;
+ cuberight[0].v[2] = uv_ratio;
+
+ //second triangle
+ cuberight[1].verts[0][0] = 0.0;
+ cuberight[1].verts[0][1] = sqrt_2 / 2.0;
+ cuberight[1].verts[0][2] = -0.5;
+ cuberight[1].u[0] = 0.0;
+ cuberight[1].v[0] = 0.0;
+
+ cuberight[1].verts[1][0] = sqrt_2 / 2.0;
+ cuberight[1].verts[1][1] = 0.0;
+ cuberight[1].verts[1][2] = 0.5;
+ cuberight[1].u[1] = uv_ratio;
+ cuberight[1].v[1] = uv_ratio;
+
+ cuberight[1].verts[2][0] = 0.0;
+ cuberight[1].verts[2][1] = sqrt_2 / 2.0;
+ cuberight[1].verts[2][2] = 0.5;
+ cuberight[1].u[2] = 0.0;
+ cuberight[1].v[2] = uv_ratio;
+
+ nfacesright = 2;
+
+ //Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration
+ //Could be made more efficient for drawing if the triangles were ordered in a fan. Not that important since we are using DisplayLists
+
+ for(i=0;i<m_resolution;i++){
+ cubetop.resize(4*nfacestop);
+ SplitFace(cubetop,&nfacestop);
+ cubebottom.resize(4*nfacesbottom);
+ SplitFace(cubebottom,&nfacesbottom);
+ cubeleft.resize(4*nfacesleft);
+ SplitFace(cubeleft,&nfacesleft);
+ cuberight.resize(4*nfacesright);
+ SplitFace(cuberight,&nfacesright);
+ }
+
+ // Turn into a hemisphere
+ for(j=0;j<3;j++){
+ for(i=0;i<nfacestop;i++)
+ cubetop[i].verts[j].normalize();
+ for(i=0;i<nfacesbottom;i++)
+ cubebottom[i].verts[j].normalize();
+ for(i=0;i<nfacesleft;i++)
+ cubeleft[i].verts[j].normalize();
+ for(i=0;i<nfacesright;i++)
+ cuberight[i].verts[j].normalize();
+ }
+
+ //flatten onto xz plane
+ for(i=0;i<nfacestop;i++)
+ FlattenDome(cubetop[i].verts);
+ for(i=0;i<nfacesbottom;i++)
+ FlattenDome(cubebottom[i].verts);
+ for(i=0;i<nfacesleft;i++)
+ FlattenDome(cubeleft[i].verts);
+ for(i=0;i<nfacesright;i++)
+ FlattenDome(cuberight[i].verts);
+
+}
+
+void KX_Dome::CreateMeshDome250(void)
+{
+/*
+1)- Define the faces of a cube without the back face
+ - each face is made out of 2 triangles
+2) Subdivide the faces
+ - more resolution == more curved lines
+3) Spherize the cube
+ - normalize the verts
+4) Flatten onto xz plane
+ - transform it onto an equidistant spherical projection techniques to transform the sphere onto a dome image
+*/
+
+ int i,j;
+ float uv_height, uv_base;
+ float verts_height;
+
+ float rad_ang = m_angle * MT_PI / 180.0;
+ float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
+
+ m_radangle = m_angle * M_PI/180.0;//calculates the radians angle, used for flattening
+/*
+verts_height is the exactly needed height of the cube faces (not always 1.0).
+When we want some horizontal information (e.g. for horizontal 220º domes) we don't need to create and tesselate the whole cube.
+Therefore the lateral cube faces could be small, and the tesselate mesh would be completely used.
+(if we always worked with verts_height = 1.0, we would be discarding a lot of the calculated and tesselated geometry).
+
+So I came out with this formula:
+verts_height = tan((rad_ang/2) - (MT_PI/2))*sqrt(2.0);
+
+Here we take half the sphere(rad_ang/2) and subtract a quarter of it (MT_PI/2)
+Therefore we have the lenght in radians of the dome/sphere over the horizon.
+Once we take the tangent of that angle, you have the verts coordinate corresponding to the verts on the side faces.
+Then we need to multiply it by sqrt(2.0) to get the coordinate of the verts on the diagonal of the original cube.
+*/
+ verts_height = tan((rad_ang/2) - (MT_PI/2))*sqrt(2.0);
+
+ uv_height = uv_ratio * ((verts_height/2) + 0.5);
+ uv_base = uv_ratio * (1.0 - ((verts_height/2) + 0.5));
+
+ //creating faces for the env mapcube 180º Dome
+ // Front Face - 2 triangles
+ cubefront[0].verts[0][0] =-1.0;
+ cubefront[0].verts[0][1] = 1.0;
+ cubefront[0].verts[0][2] =-1.0;
+ cubefront[0].u[0] = 0.0;
+ cubefront[0].v[0] = 0.0;
+
+ cubefront[0].verts[1][0] = 1.0;
+ cubefront[0].verts[1][1] = 1.0;
+ cubefront[0].verts[1][2] = 1.0;
+ cubefront[0].u[1] = uv_ratio;
+ cubefront[0].v[1] = uv_ratio;
+
+ cubefront[0].verts[2][0] =-1.0;
+ cubefront[0].verts[2][1] = 1.0;
+ cubefront[0].verts[2][2] = 1.0;
+ cubefront[0].u[2] = 0.0;
+ cubefront[0].v[2] = uv_ratio;
+
+ //second triangle
+ cubefront[1].verts[0][0] = 1.0;
+ cubefront[1].verts[0][1] = 1.0;
+ cubefront[1].verts[0][2] = 1.0;
+ cubefront[1].u[0] = uv_ratio;
+ cubefront[1].v[0] = uv_ratio;
+
+ cubefront[1].verts[1][0] =-1.0;
+ cubefront[1].verts[1][1] = 1.0;
+ cubefront[1].verts[1][2] =-1.0;
+ cubefront[1].u[1] = 0.0;
+ cubefront[1].v[1] = 0.0;
+
+ cubefront[1].verts[2][0] = 1.0;
+ cubefront[1].verts[2][1] = 1.0;
+ cubefront[1].verts[2][2] =-1.0;
+ cubefront[1].u[2] = uv_ratio;
+ cubefront[1].v[2] = 0.0;
+
+ nfacesfront = 2;
+
+ // Left Face - 2 triangles
+ cubeleft[0].verts[0][0] =-1.0;
+ cubeleft[0].verts[0][1] = 1.0;
+ cubeleft[0].verts[0][2] =-1.0;
+ cubeleft[0].u[0] = uv_ratio;
+ cubeleft[0].v[0] = 0.0;
+
+ cubeleft[0].verts[1][0] =-1.0;
+ cubeleft[0].verts[1][1] =-verts_height;
+ cubeleft[0].verts[1][2] = 1.0;
+ cubeleft[0].u[1] = uv_base;
+ cubeleft[0].v[1] = uv_ratio;
+
+ cubeleft[0].verts[2][0] =-1.0;
+ cubeleft[0].verts[2][1] =-verts_height;
+ cubeleft[0].verts[2][2] =-1.0;
+ cubeleft[0].u[2] = uv_base;
+ cubeleft[0].v[2] = 0.0;
+
+ //second triangle
+ cubeleft[1].verts[0][0] =-1.0;
+ cubeleft[1].verts[0][1] =-verts_height;
+ cubeleft[1].verts[0][2] = 1.0;
+ cubeleft[1].u[0] = uv_base;
+ cubeleft[1].v[0] = uv_ratio;
+
+ cubeleft[1].verts[1][0] =-1.0;
+ cubeleft[1].verts[1][1] = 1.0;
+ cubeleft[1].verts[1][2] =-1.0;
+ cubeleft[1].u[1] = uv_ratio;
+ cubeleft[1].v[1] = 0.0;
+
+ cubeleft[1].verts[2][0] =-1.0;
+ cubeleft[1].verts[2][1] = 1.0;
+ cubeleft[1].verts[2][2] = 1.0;
+ cubeleft[1].u[2] = uv_ratio;
+ cubeleft[1].v[2] = uv_ratio;
+
+ nfacesleft = 2;
+
+ // right Face - 2 triangles
+ cuberight[0].verts[0][0] = 1.0;
+ cuberight[0].verts[0][1] = 1.0;
+ cuberight[0].verts[0][2] = 1.0;
+ cuberight[0].u[0] = 0.0;
+ cuberight[0].v[0] = uv_ratio;
+
+ cuberight[0].verts[1][0] = 1.0;
+ cuberight[0].verts[1][1] =-verts_height;
+ cuberight[0].verts[1][2] =-1.0;
+ cuberight[0].u[1] = uv_height;
+ cuberight[0].v[1] = 0.0;
+
+ cuberight[0].verts[2][0] = 1.0;
+ cuberight[0].verts[2][1] =-verts_height;
+ cuberight[0].verts[2][2] = 1.0;
+ cuberight[0].u[2] = uv_height;
+ cuberight[0].v[2] = uv_ratio;
+
+ //second triangle
+ cuberight[1].verts[0][0] = 1.0;
+ cuberight[1].verts[0][1] =-verts_height;
+ cuberight[1].verts[0][2] =-1.0;
+ cuberight[1].u[0] = uv_height;
+ cuberight[1].v[0] = 0.0;
+
+ cuberight[1].verts[1][0] = 1.0;
+ cuberight[1].verts[1][1] = 1.0;
+ cuberight[1].verts[1][2] = 1.0;
+ cuberight[1].u[1] = 0.0;
+ cuberight[1].v[1] = uv_ratio;
+
+ cuberight[1].verts[2][0] = 1.0;
+ cuberight[1].verts[2][1] = 1.0;
+ cuberight[1].verts[2][2] =-1.0;
+ cuberight[1].u[2] = 0.0;
+ cuberight[1].v[2] = 0.0;
+
+ nfacesright = 2;
+
+ // top Face - 2 triangles
+ cubetop[0].verts[0][0] =-1.0;
+ cubetop[0].verts[0][1] = 1.0;
+ cubetop[0].verts[0][2] = 1.0;
+ cubetop[0].u[0] = 0.0;
+ cubetop[0].v[0] = 0.0;
+
+ cubetop[0].verts[1][0] = 1.0;
+ cubetop[0].verts[1][1] =-verts_height;
+ cubetop[0].verts[1][2] = 1.0;
+ cubetop[0].u[1] = uv_ratio;
+ cubetop[0].v[1] = uv_height;
+
+ cubetop[0].verts[2][0] =-1.0;
+ cubetop[0].verts[2][1] =-verts_height;
+ cubetop[0].verts[2][2] = 1.0;
+ cubetop[0].u[2] = 0.0;
+ cubetop[0].v[2] = uv_height;
+
+ //second triangle
+ cubetop[1].verts[0][0] = 1.0;
+ cubetop[1].verts[0][1] =-verts_height;
+ cubetop[1].verts[0][2] = 1.0;
+ cubetop[1].u[0] = uv_ratio;
+ cubetop[1].v[0] = uv_height;
+
+ cubetop[1].verts[1][0] =-1.0;
+ cubetop[1].verts[1][1] = 1.0;
+ cubetop[1].verts[1][2] = 1.0;
+ cubetop[1].u[1] = 0.0;
+ cubetop[1].v[1] = 0.0;
+
+ cubetop[1].verts[2][0] = 1.0;
+ cubetop[1].verts[2][1] = 1.0;
+ cubetop[1].verts[2][2] = 1.0;
+ cubetop[1].u[2] = uv_ratio;
+ cubetop[1].v[2] = 0.0;
+
+ nfacestop = 2;
+
+ // bottom Face - 2 triangles
+ cubebottom[0].verts[0][0] =-1.0;
+ cubebottom[0].verts[0][1] =-verts_height;
+ cubebottom[0].verts[0][2] =-1.0;
+ cubebottom[0].u[0] = 0.0;
+ cubebottom[0].v[0] = uv_base;
+
+ cubebottom[0].verts[1][0] = 1.0;
+ cubebottom[0].verts[1][1] = 1.0;
+ cubebottom[0].verts[1][2] =-1.0;
+ cubebottom[0].u[1] = uv_ratio;
+ cubebottom[0].v[1] = uv_ratio;
+
+ cubebottom[0].verts[2][0] =-1.0;
+ cubebottom[0].verts[2][1] = 1.0;
+ cubebottom[0].verts[2][2] =-1.0;
+ cubebottom[0].u[2] = 0.0;
+ cubebottom[0].v[2] = uv_ratio;
+
+ //second triangle
+ cubebottom[1].verts[0][0] = 1.0;
+ cubebottom[1].verts[0][1] = 1.0;
+ cubebottom[1].verts[0][2] =-1.0;
+ cubebottom[1].u[0] = uv_ratio;
+ cubebottom[1].v[0] = uv_ratio;
+
+ cubebottom[1].verts[1][0] =-1.0;
+ cubebottom[1].verts[1][1] =-verts_height;
+ cubebottom[1].verts[1][2] =-1.0;
+ cubebottom[1].u[1] = 0.0;
+ cubebottom[1].v[1] = uv_base;
+
+ cubebottom[1].verts[2][0] = 1.0;
+ cubebottom[1].verts[2][1] =-verts_height;
+ cubebottom[1].verts[2][2] =-1.0;
+ cubebottom[1].u[2] = uv_ratio;
+ cubebottom[1].v[2] = uv_base;
+
+ nfacesbottom = 2;
+
+ //Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration
+ //It could be made more efficient for drawing if the triangles were ordered in a strip!
+
+ for(i=0;i<m_resolution;i++){
+ cubefront.resize(4*nfacesfront);
+ SplitFace(cubefront,&nfacesfront);
+ cubetop.resize(4*nfacestop);
+ SplitFace(cubetop,&nfacestop);
+ cubebottom.resize(4*nfacesbottom);
+ SplitFace(cubebottom,&nfacesbottom);
+ cubeleft.resize(4*nfacesleft);
+ SplitFace(cubeleft,&nfacesleft);
+ cuberight.resize(4*nfacesright);
+ SplitFace(cuberight,&nfacesright);
+ }
+
+ // Turn into a hemisphere/sphere
+ for(j=0;j<3;j++){
+ for(i=0;i<nfacesfront;i++)
+ cubefront[i].verts[j].normalize();
+ for(i=0;i<nfacestop;i++)
+ cubetop[i].verts[j].normalize();
+ for(i=0;i<nfacesbottom;i++)
+ cubebottom[i].verts[j].normalize();
+ for(i=0;i<nfacesleft;i++)
+ cubeleft[i].verts[j].normalize();
+ for(i=0;i<nfacesright;i++)
+ cuberight[i].verts[j].normalize();
+ }
+
+ //flatten onto xz plane
+ for(i=0;i<nfacesfront;i++)
+ FlattenDome(cubefront[i].verts);
+ for(i=0;i<nfacestop;i++)
+ FlattenDome(cubetop[i].verts);
+ for(i=0;i<nfacesbottom;i++)
+ FlattenDome(cubebottom[i].verts);
+ for(i=0;i<nfacesleft;i++)
+ FlattenDome(cubeleft[i].verts);
+ for(i=0;i<nfacesright;i++)
+ FlattenDome(cuberight[i].verts);
+}
+
+void KX_Dome::CreateMeshPanorama(void)
+{
+/*
+1)- Define the faces of a cube without the top and bottom faces
+ - each face is made out of 2 triangles
+2) Subdivide the faces
+ - more resolution == more curved lines
+3) Spherize the cube
+ - normalize the verts t
+4) Flatten onto xz plane
+ - use spherical projection techniques to transform the sphere onto a flat panorama
+*/
+ int i,j;
+
+ float sqrt_2 = sqrt(2.0);
+ float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
+
+ /* Top face - two triangles */
+ cubetop[0].verts[0][0] = -sqrt_2;
+ cubetop[0].verts[0][1] = 0.0;
+ cubetop[0].verts[0][2] = 1.0;
+ cubetop[0].u[0] = 0.0;
+ cubetop[0].v[0] = uv_ratio;
+
+ cubetop[0].verts[1][0] = 0.0;
+ cubetop[0].verts[1][1] = sqrt_2;
+ cubetop[0].verts[1][2] = 1.0;
+ cubetop[0].u[1] = 0.0;
+ cubetop[0].v[1] = 0.0;
+
+ //second triangle
+ cubetop[0].verts[2][0] = sqrt_2;
+ cubetop[0].verts[2][1] = 0.0;
+ cubetop[0].verts[2][2] = 1.0;
+ cubetop[0].u[2] = uv_ratio;
+ cubetop[0].v[2] = 0.0;
+
+ cubetop[1].verts[0][0] = sqrt_2;
+ cubetop[1].verts[0][1] = 0.0;
+ cubetop[1].verts[0][2] = 1.0;
+ cubetop[1].u[0] = uv_ratio;
+ cubetop[1].v[0] = 0.0;
+
+ cubetop[1].verts[1][0] = 0.0;
+ cubetop[1].verts[1][1] = -sqrt_2;
+ cubetop[1].verts[1][2] = 1.0;
+ cubetop[1].u[1] = uv_ratio;
+ cubetop[1].v[1] = uv_ratio;
+
+ cubetop[1].verts[2][0] = -sqrt_2;
+ cubetop[1].verts[2][1] = 0.0;
+ cubetop[1].verts[2][2] = 1.0;
+ cubetop[1].u[2] = 0.0;
+ cubetop[1].v[2] = uv_ratio;
+
+ nfacestop = 2;
+
+ /* Bottom face - two triangles */
+ cubebottom[0].verts[0][0] = -sqrt_2;
+ cubebottom[0].verts[0][1] = 0.0;
+ cubebottom[0].verts[0][2] = -1.0;
+ cubebottom[0].u[0] = uv_ratio;
+ cubebottom[0].v[0] = 0.0;
+
+ cubebottom[0].verts[1][0] = sqrt_2;
+ cubebottom[0].verts[1][1] = 0.0;
+ cubebottom[0].verts[1][2] = -1.0;
+ cubebottom[0].u[1] = 0.0;
+ cubebottom[0].v[1] = uv_ratio;
+
+ cubebottom[0].verts[2][0] = 0.0;
+ cubebottom[0].verts[2][1] = sqrt_2;
+ cubebottom[0].verts[2][2] = -1.0;
+ cubebottom[0].u[2] = 0.0;
+ cubebottom[0].v[2] = 0.0;
+
+ //second triangle
+ cubebottom[1].verts[0][0] = sqrt_2;
+ cubebottom[1].verts[0][1] = 0.0;
+ cubebottom[1].verts[0][2] = -1.0;
+ cubebottom[1].u[0] = 0.0;
+ cubebottom[1].v[0] = uv_ratio;
+
+ cubebottom[1].verts[1][0] = -sqrt_2;
+ cubebottom[1].verts[1][1] = 0.0;
+ cubebottom[1].verts[1][2] = -1.0;
+ cubebottom[1].u[1] = uv_ratio;
+ cubebottom[1].v[1] = 0.0;
+
+ cubebottom[1].verts[2][0] = 0.0;
+ cubebottom[1].verts[2][1] = -sqrt_2;
+ cubebottom[1].verts[2][2] = -1.0;
+ cubebottom[1].u[2] = uv_ratio;
+ cubebottom[1].v[2] = uv_ratio;
+
+ nfacesbottom = 2;
+
+ /* Left Back (135º) face - two triangles */
+
+ cubeleftback[0].verts[0][0] = 0;
+ cubeleftback[0].verts[0][1] = -sqrt_2;
+ cubeleftback[0].verts[0][2] = -1.0;
+ cubeleftback[0].u[0] = 0;
+ cubeleftback[0].v[0] = 0;
+
+ cubeleftback[0].verts[1][0] = -sqrt_2;
+ cubeleftback[0].verts[1][1] = 0;
+ cubeleftback[0].verts[1][2] = -1.0;
+ cubeleftback[0].u[1] = uv_ratio;
+ cubeleftback[0].v[1] = 0;
+
+ cubeleftback[0].verts[2][0] = 0;
+ cubeleftback[0].verts[2][1] = -sqrt_2;
+ cubeleftback[0].verts[2][2] = 1.0;
+ cubeleftback[0].u[2] = 0;
+ cubeleftback[0].v[2] = uv_ratio;
+
+ //second triangle
+ cubeleftback[1].verts[0][0] = 0;
+ cubeleftback[1].verts[0][1] = -sqrt_2;
+ cubeleftback[1].verts[0][2] = 1.0;
+ cubeleftback[1].u[0] = 0;
+ cubeleftback[1].v[0] = uv_ratio;
+
+ cubeleftback[1].verts[1][0] = -sqrt_2;
+ cubeleftback[1].verts[1][1] = 0;
+ cubeleftback[1].verts[1][2] = -1.0;
+ cubeleftback[1].u[1] = uv_ratio;
+ cubeleftback[1].v[1] = 0;
+
+ cubeleftback[1].verts[2][0] = -sqrt_2;
+ cubeleftback[1].verts[2][1] = 0;
+ cubeleftback[1].verts[2][2] = 1.0;
+ cubeleftback[1].u[2] = uv_ratio;
+ cubeleftback[1].v[2] = uv_ratio;
+
+ nfacesleftback = 2;
+
+ /* Left face - two triangles */
+
+ cubeleft[0].verts[0][0] = -sqrt_2;
+ cubeleft[0].verts[0][1] = 0;
+ cubeleft[0].verts[0][2] = -1.0;
+ cubeleft[0].u[0] = 0;
+ cubeleft[0].v[0] = 0;
+
+ cubeleft[0].verts[1][0] = 0;
+ cubeleft[0].verts[1][1] = sqrt_2;
+ cubeleft[0].verts[1][2] = -1.0;
+ cubeleft[0].u[1] = uv_ratio;
+ cubeleft[0].v[1] = 0;
+
+ cubeleft[0].verts[2][0] = -sqrt_2;
+ cubeleft[0].verts[2][1] = 0;
+ cubeleft[0].verts[2][2] = 1.0;
+ cubeleft[0].u[2] = 0;
+ cubeleft[0].v[2] = uv_ratio;
+
+ //second triangle
+ cubeleft[1].verts[0][0] = -sqrt_2;
+ cubeleft[1].verts[0][1] = 0;
+ cubeleft[1].verts[0][2] = 1.0;
+ cubeleft[1].u[0] = 0;
+ cubeleft[1].v[0] = uv_ratio;
+
+ cubeleft[1].verts[1][0] = 0;
+ cubeleft[1].verts[1][1] = sqrt_2;
+ cubeleft[1].verts[1][2] = -1.0;
+ cubeleft[1].u[1] = uv_ratio;
+ cubeleft[1].v[1] = 0;
+
+ cubeleft[1].verts[2][0] = 0;
+ cubeleft[1].verts[2][1] = sqrt_2;
+ cubeleft[1].verts[2][2] = 1.0;
+ cubeleft[1].u[2] = uv_ratio;
+ cubeleft[1].v[2] = uv_ratio;
+
+ nfacesleft = 2;
+
+ /* Right face - two triangles */
+ cuberight[0].verts[0][0] = 0;
+ cuberight[0].verts[0][1] = sqrt_2;
+ cuberight[0].verts[0][2] = -1.0;
+ cuberight[0].u[0] = 0;
+ cuberight[0].v[0] = 0;
+
+ cuberight[0].verts[1][0] = sqrt_2;
+ cuberight[0].verts[1][1] = 0;
+ cuberight[0].verts[1][2] = -1.0;
+ cuberight[0].u[1] = uv_ratio;
+ cuberight[0].v[1] = 0;
+
+ cuberight[0].verts[2][0] = sqrt_2;
+ cuberight[0].verts[2][1] = 0;
+ cuberight[0].verts[2][2] = 1.0;
+ cuberight[0].u[2] = uv_ratio;
+ cuberight[0].v[2] = uv_ratio;
+
+ //second triangle
+ cuberight[1].verts[0][0] = 0;
+ cuberight[1].verts[0][1] = sqrt_2;
+ cuberight[1].verts[0][2] = -1.0;
+ cuberight[1].u[0] = 0;
+ cuberight[1].v[0] = 0;
+
+ cuberight[1].verts[1][0] = sqrt_2;
+ cuberight[1].verts[1][1] = 0;
+ cuberight[1].verts[1][2] = 1.0;
+ cuberight[1].u[1] = uv_ratio;
+ cuberight[1].v[1] = uv_ratio;
+
+ cuberight[1].verts[2][0] = 0;
+ cuberight[1].verts[2][1] = sqrt_2;
+ cuberight[1].verts[2][2] = 1.0;
+ cuberight[1].u[2] = 0;
+ cuberight[1].v[2] = uv_ratio;
+
+ nfacesright = 2;
+
+ /* Right Back (-135º) face - two triangles */
+ cuberightback[0].verts[0][0] = sqrt_2;
+ cuberightback[0].verts[0][1] = 0;
+ cuberightback[0].verts[0][2] = -1.0;
+ cuberightback[0].u[0] = 0;
+ cuberightback[0].v[0] = 0;
+
+ cuberightback[0].verts[1][0] = 0;
+ cuberightback[0].verts[1][1] = -sqrt_2;
+ cuberightback[0].verts[1][2] = -1.0;
+ cuberightback[0].u[1] = uv_ratio;
+ cuberightback[0].v[1] = 0;
+
+ cuberightback[0].verts[2][0] = 0;
+ cuberightback[0].verts[2][1] = -sqrt_2;
+ cuberightback[0].verts[2][2] = 1.0;
+ cuberightback[0].u[2] = uv_ratio;
+ cuberightback[0].v[2] = uv_ratio;
+
+ //second triangle
+ cuberightback[1].verts[0][0] = sqrt_2;
+ cuberightback[1].verts[0][1] = 0;
+ cuberightback[1].verts[0][2] = -1.0;
+ cuberightback[1].u[0] = 0;
+ cuberightback[1].v[0] = 0;
+
+ cuberightback[1].verts[1][0] = 0;
+ cuberightback[1].verts[1][1] = -sqrt_2;
+ cuberightback[1].verts[1][2] = 1.0;
+ cuberightback[1].u[1] = uv_ratio;
+ cuberightback[1].v[1] = uv_ratio;
+
+ cuberightback[1].verts[2][0] = sqrt_2;
+ cuberightback[1].verts[2][1] = 0;
+ cuberightback[1].verts[2][2] = 1.0;
+ cuberightback[1].u[2] = 0;
+ cuberightback[1].v[2] = uv_ratio;
+
+ nfacesrightback = 2;
+
+ // Subdivide the faces
+ for(i=0;i<m_resolution;i++)
+ {
+ cubetop.resize(4*nfacestop);
+ SplitFace(cubetop,&nfacestop);
+
+ cubebottom.resize(4*nfacesbottom);
+ SplitFace(cubebottom,&nfacesbottom);
+
+ cubeleft.resize(4*nfacesleft);
+ SplitFace(cubeleft,&nfacesleft);
+
+ cuberight.resize(4*nfacesright);
+ SplitFace(cuberight,&nfacesright);
+
+ cubeleftback.resize(4*nfacesleftback);
+ SplitFace(cubeleftback,&nfacesleftback);
+
+ cuberightback.resize(4*nfacesrightback);
+ SplitFace(cuberightback,&nfacesrightback);
+ }
+
+ // Spherize the cube
+ for(j=0;j<3;j++)
+ {
+ for(i=0;i<nfacestop;i++)
+ cubetop[i].verts[j].normalize();
+
+ for(i=0;i<nfacesbottom;i++)
+ cubebottom[i].verts[j].normalize();
+
+ for(i=0;i<nfacesleftback;i++)
+ cubeleftback[i].verts[j].normalize();
+
+ for(i=0;i<nfacesleft;i++)
+ cubeleft[i].verts[j].normalize();
+
+ for(i=0;i<nfacesright;i++)
+ cuberight[i].verts[j].normalize();
+
+ for(i=0;i<nfacesrightback;i++)
+ cuberightback[i].verts[j].normalize();
+ }
+
+ //Flatten onto xz plane
+ for(i=0;i<nfacesleftback;i++)
+ FlattenPanorama(cubeleftback[i].verts);
+
+ for(i=0;i<nfacesleft;i++)
+ FlattenPanorama(cubeleft[i].verts);
+
+ for(i=0;i<nfacesright;i++)
+ FlattenPanorama(cuberight[i].verts);
+
+ for(i=0;i<nfacesrightback;i++)
+ FlattenPanorama(cuberightback[i].verts);
+
+ for(i=0;i<nfacestop;i++)
+ FlattenPanorama(cubetop[i].verts);
+
+ for(i=0;i<nfacesbottom;i++)
+ FlattenPanorama(cubebottom[i].verts);
+}
+
+void KX_Dome::FlattenDome(MT_Vector3 verts[3])
+{
+ double phi, r;
+
+ for (int i=0;i<3;i++){
+ r = atan2(sqrt(verts[i][0]*verts[i][0] + verts[i][2]*verts[i][2]), verts[i][1]);
+ r /= m_radangle/2;
+
+ phi = atan2(verts[i][2], verts[i][0]);
+
+ verts[i][0] = r * cos(phi);
+ verts[i][1] = 0;
+ verts[i][2] = r * sin(phi);
+
+ if (r > 1.0){
+ //round the border
+ verts[i][0] = cos(phi);
+ verts[i][1] = -3.0;
+ verts[i][2] = sin(phi);
+ }
+ }
+}
+
+void KX_Dome::FlattenPanorama(MT_Vector3 verts[3])
+{
+// it creates a full spherical panoramic (360º)
+ int i;
+ double phi;
+ bool edge=false;
+
+ for (i=0;i<3;i++){
+ phi = atan2(verts[i][1], verts[i][0]);
+ phi *= -1.0; //flipping
+
+ if (phi == -MT_PI) //It's on the edge
+ edge=true;
+
+ verts[i][0] = phi / MT_PI;
+ verts[i][1] = 0;
+
+ verts[i][2] = atan2(verts[i][2], 1.0);
+ verts[i][2] /= MT_PI / 2;
+ }
+ if(edge){
+ bool right=false;
+
+ for (i=0;i<3;i++){
+ if(fmod(verts[i][0],1.0) > 0.0){
+ right=true;
+ break;
+ }
+ }
+ if(right){
+ for (i=0;i<3;i++){
+ if(verts[i][0] < 0.0)
+ verts[i][0] *= -1.0;
+ }
+ }
+ }
+}
+
+void KX_Dome::SplitFace(vector <DomeFace>& face, int *nfaces)
+{
+ int i;
+ int n1, n2;
+
+ n1 = n2 = *nfaces;
+
+ for(i=0;i<n1;i++){
+
+ face[n2].verts[0] = (face[i].verts[0] + face[i].verts[1]) /2;
+ face[n2].verts[1] = face[i].verts[1];
+ face[n2].verts[2] = (face[i].verts[1] + face[i].verts[2]) /2;
+ face[n2].u[0] = (face[i].u[0] + face[i].u[1]) /2;
+ face[n2].u[1] = face[i].u[1];
+ face[n2].u[2] = (face[i].u[1] + face[i].u[2]) /2;
+ face[n2].v[0] = (face[i].v[0] + face[i].v[1]) /2;
+ face[n2].v[1] = face[i].v[1];
+ face[n2].v[2] = (face[i].v[1] + face[i].v[2]) /2;
+
+ face[n2+1].verts[0] = (face[i].verts[1] + face[i].verts[2]) /2;
+ face[n2+1].verts[1] = face[i].verts[2];
+ face[n2+1].verts[2] = (face[i].verts[2] + face[i].verts[0]) /2;
+ face[n2+1].u[0] = (face[i].u[1] + face[i].u[2]) /2;
+ face[n2+1].u[1] = face[i].u[2];
+ face[n2+1].u[2] = (face[i].u[2] + face[i].u[0]) /2;
+ face[n2+1].v[0] = (face[i].v[1] + face[i].v[2]) /2;
+ face[n2+1].v[1] = face[i].v[2];
+ face[n2+1].v[2] = (face[i].v[2] + face[i].v[0]) /2;
+
+ face[n2+2].verts[0] = (face[i].verts[0] + face[i].verts[1]) /2;
+ face[n2+2].verts[1] = (face[i].verts[1] + face[i].verts[2]) /2;
+ face[n2+2].verts[2] = (face[i].verts[2] + face[i].verts[0]) /2;
+ face[n2+2].u[0] = (face[i].u[0] + face[i].u[1]) /2;
+ face[n2+2].u[1] = (face[i].u[1] + face[i].u[2]) /2;
+ face[n2+2].u[2] = (face[i].u[2] + face[i].u[0]) /2;
+ face[n2+2].v[0] = (face[i].v[0] + face[i].v[1]) /2;
+ face[n2+2].v[1] = (face[i].v[1] + face[i].v[2]) /2;
+ face[n2+2].v[2] = (face[i].v[2] + face[i].v[0]) /2;
+
+ //face[i].verts[0] = face[i].verts[0] ;
+ face[i].verts[1] = (face[i].verts[0] + face[i].verts[1]) /2;
+ face[i].verts[2] = (face[i].verts[0] + face[i].verts[2]) /2;
+ //face[i].u[0] = face[i].u[0];
+ face[i].u[1] = (face[i].u[0] + face[i].u[1]) /2;
+ face[i].u[2] = (face[i].u[0] + face[i].u[2]) /2;
+ //face[i].v[0] = face[i].v[0] ;
+ face[i].v[1] = (face[i].v[0] + face[i].v[1]) /2;
+ face[i].v[2] = (face[i].v[0] + face[i].v[2]) /2;
+
+ n2 += 3; // number of faces
+ }
+ *nfaces = n2;
+}
+
+void KX_Dome::CalculateFrustum(KX_Camera * cam)
+{
+ /*
+ // manually creating a 90º Field of View Frustum
+
+ 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
+ left = aspect * bottom
+ right = aspect * top
+
+ // the equivalent GLU call is:
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar());
+ */
+
+ RAS_FrameFrustum m_frustrum; //90 deg. Frustum
+
+ m_frustrum.camnear = cam->GetCameraNear();
+ m_frustrum.camfar = cam->GetCameraFar();
+
+// float top = tan(90.0*MT_PI/360.0) * m_frustrum.camnear;
+ float top = m_frustrum.camnear; // for deg = 90º, tan = 1
+
+ m_frustrum.x1 = -top;
+ m_frustrum.x2 = top;
+ m_frustrum.y1 = -top;
+ m_frustrum.y2 = top;
+
+ m_projmat = m_rasterizer->GetFrustumMatrix(
+ m_frustrum.x1, m_frustrum.x2, m_frustrum.y1, m_frustrum.y2, m_frustrum.camnear, m_frustrum.camfar);
+
+}
+
+void KX_Dome::CalculateCameraOrientation()
+{
+/*
+Uses 4 cameras for angles up to 180º
+Uses 5 cameras for angles up to 250º
+Uses 6 cameras for angles up to 360º
+*/
+ float deg45 = MT_PI / 4;
+ MT_Scalar c = cos(deg45);
+ MT_Scalar s = sin(deg45);
+
+ if ((m_mode == DOME_FISHEYE && m_angle <= 180)|| m_mode == DOME_TRUNCATED){
+
+ m_locRot[0] = MT_Matrix3x3( // 90º - Top
+ c, -s, 0.0,
+ 0.0,0.0, -1.0,
+ s, c, 0.0);
+
+ m_locRot[1] = MT_Matrix3x3( // 90º - Bottom
+ -s, c, 0.0,
+ 0.0,0.0, 1.0,
+ s, c, 0.0);
+
+ m_locRot[2] = MT_Matrix3x3( // 45º - Left
+ c, 0.0, s,
+ 0, 1.0, 0.0,
+ -s, 0.0, c);
+
+ m_locRot[3] = MT_Matrix3x3( // 45º - Right
+ c, 0.0, -s,
+ 0.0, 1.0, 0.0,
+ s, 0.0, c);
+
+ } else if ((m_mode == DOME_FISHEYE && m_angle > 180)){
+
+ m_locRot[0] = MT_Matrix3x3( // 90º - Top
+ 1.0, 0.0, 0.0,
+ 0.0, 0.0,-1.0,
+ 0.0, 1.0, 0.0);
+
+ m_locRot[1] = MT_Matrix3x3( // 90º - Bottom
+ 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0,
+ 0.0,-1.0, 0.0);
+
+ m_locRot[2] = MT_Matrix3x3( // -90º - Left
+ 0.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0,
+ -1.0, 0.0, 0.0);
+
+ m_locRot[3] = MT_Matrix3x3( // 90º - Right
+ 0.0, 0.0,-1.0,
+ 0.0, 1.0, 0.0,
+ 1.0, 0.0, 0.0);
+
+ m_locRot[4] = MT_Matrix3x3( // 0º - Front
+ 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+
+ m_locRot[5] = MT_Matrix3x3( // 180º - Back - NOT USING
+ -1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0,-1.0);
+
+ } else if (m_mode == DOME_PANORAM_SPH){
+
+ m_locRot[0] = MT_Matrix3x3( // Top
+ c, s, 0.0,
+ 0.0,0.0, -1.0,
+ -s, c, 0.0);
+
+ m_locRot[1] = MT_Matrix3x3( // Bottom
+ c, s, 0.0,
+ 0.0 ,0.0, 1.0,
+ s, -c, 0.0);
+
+ m_locRot[2] = MT_Matrix3x3( // 45º - Left
+ -s, 0.0, c,
+ 0, 1.0, 0.0,
+ -c, 0.0, -s);
+
+ m_locRot[3] = MT_Matrix3x3( // 45º - Right
+ c, 0.0, s,
+ 0, 1.0, 0.0,
+ -s, 0.0, c);
+
+ m_locRot[4] = MT_Matrix3x3( // 135º - LeftBack
+ -s, 0.0, -c,
+ 0.0, 1.0, 0.0,
+ c, 0.0, -s);
+
+ m_locRot[5] = MT_Matrix3x3( // 135º - RightBack
+ c, 0.0, -s,
+ 0.0, 1.0, 0.0,
+ s, 0.0, c);
+ }
+}
+
+void KX_Dome::RotateCamera(KX_Camera* cam, int i)
+{
+// I'm not using it, I'm doing inline calls for these commands
+// but it's nice to have it here in case I need it
+
+ MT_Matrix3x3 camori = cam->GetSGNode()->GetLocalOrientation();
+
+ cam->NodeSetLocalOrientation(camori*m_locRot[i]);
+ cam->NodeUpdateGS(0.f);
+
+ MT_Transform camtrans(cam->GetWorldToCamera());
+ MT_Matrix4x4 viewmat(camtrans);
+ m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
+ cam->GetCameraLocation(), cam->GetCameraOrientation());
+ cam->SetModelviewMatrix(viewmat);
+
+ // restore the original orientation
+ cam->NodeSetLocalOrientation(camori);
+ cam->NodeUpdateGS(0.f);
+}
+
+void KX_Dome::Draw(void)
+{
+
+ switch(m_mode){
+ case DOME_FISHEYE:
+ DrawDomeFisheye();
+ break;
+ case DOME_TRUNCATED:
+ DrawDomeFisheye();
+ break;
+ case DOME_PANORAM_SPH:
+ DrawPanorama();
+ break;
+ }
+
+ 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);
+ DrawDomeWarped();
+ }
+}
+
+void KX_Dome::DrawDomeFisheye(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, (-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 {
+ 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);
+ }
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(0.0,-1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0);
+
+ if(m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
+ glPolygonMode(GL_FRONT, GL_LINE);
+ else
+ 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);
+
+ if (dlistSupported){
+ for(i=0;i<m_numfaces;i++){
+ glBindTexture(GL_TEXTURE_2D, domefacesId[i]);
+ glCallList(dlistId+i);
+ }
+ }
+ else { // DisplayLists not supported
+ // top triangle
+ glBindTexture(GL_TEXTURE_2D, domefacesId[0]);
+ GLDrawTriangles(cubetop, nfacestop);
+
+ // bottom triangle
+ glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
+ GLDrawTriangles(cubebottom, nfacesbottom);
+
+ // left triangle
+ glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
+ GLDrawTriangles(cubeleft, nfacesleft);
+
+ // right triangle
+ glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
+ GLDrawTriangles(cuberight, nfacesright);
+
+ if (m_angle > 180){
+ // front triangle
+ glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
+ GLDrawTriangles(cubefront, nfacesfront);
+ }
+ }
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void KX_Dome::DrawPanorama(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_height = 1.0;
+ float ortho_width = 1.0;
+
+ if (warp.usemesh)
+ glOrtho((-1.0), 1.0, (-0.5), 0.5, -20.0, 10.0); //stretch the image to reduce resolution lost
+
+ else {
+ //using all the screen
+ if ((can_width / 2) <= (can_height)){
+ ortho_width = 1.0;
+ ortho_height = (float)can_height/can_width;
+ }else{
+ 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);
+ }
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(0.0,-1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0);
+
+ if(m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
+ glPolygonMode(GL_FRONT, GL_LINE);
+ else
+ 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);
+
+ if (dlistSupported){
+ for(i=0;i<m_numfaces;i++){
+ glBindTexture(GL_TEXTURE_2D, domefacesId[i]);
+ glCallList(dlistId+i);
+ }
+ }
+ else {
+ // domefacesId[4] => (top)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[0]);
+ GLDrawTriangles(cubetop, nfacestop);
+
+ // domefacesId[5] => (bottom)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
+ GLDrawTriangles(cubebottom, nfacesbottom);
+
+ // domefacesId[1] => -45º (left)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
+ GLDrawTriangles(cubeleft, nfacesleft);
+
+ // domefacesId[2] => 45º (right)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
+ GLDrawTriangles(cuberight, nfacesright);
+
+ // domefacesId[0] => -135º (leftback)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
+ GLDrawTriangles(cubeleftback, nfacesleftback);
+
+ // domefacesId[3] => 135º (rightback)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[5]);
+ GLDrawTriangles(cuberightback, nfacesrightback);
+ }
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void KX_Dome::DrawDomeWarped(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();
+
+ 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);
+
+
+ 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);
+
+ if(m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
+ glPolygonMode(GL_FRONT, GL_LINE);
+ else
+ 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_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);
+ }
+ else{
+ glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
+ GLDrawWarpQuads();
+ }
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void KX_Dome::BindImages(int i)
+{
+ glBindTexture(GL_TEXTURE_2D, domefacesId[i]);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), m_buffersize, m_buffersize);
+}
+
+void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
+{
+ if (!cam)
+ return;
+
+ m_canvas->SetViewPort(0,0,m_buffersize-1,m_buffersize-1);
+
+// m_rasterizer->SetAmbient();
+ m_rasterizer->DisplayFog();
+
+ CalculateFrustum(cam); //calculates m_projmat
+ cam->SetProjectionMatrix(m_projmat);
+ m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
+// Dome_RotateCamera(cam,i);
+
+ MT_Matrix3x3 camori = cam->GetSGNode()->GetLocalOrientation();
+
+ cam->NodeSetLocalOrientation(camori*m_locRot[i]);
+ cam->NodeUpdateGS(0.f);
+
+ MT_Transform camtrans(cam->GetWorldToCamera());
+ MT_Matrix4x4 viewmat(camtrans);
+ m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
+ cam->GetCameraLocation(), cam->GetCameraOrientation());
+ cam->SetModelviewMatrix(viewmat);
+
+ scene->CalculateVisibleMeshes(m_rasterizer,cam);
+ scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+
+ // 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
new file mode 100644
index 00000000000..786e04b4385
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_Dome.h
@@ -0,0 +1,183 @@
+/* $Id$
+-----------------------------------------------------------------------------
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser 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, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+
+Contributor(s): Dalai Felinto
+
+This source uses some of the ideas and code from Paul Bourke.
+Developed as part of a Research and Development project for SAT - La Société des arts technologiques.
+-----------------------------------------------------------------------------
+*/
+
+#if !defined KX_DOME_H
+#define KX_DOME_H
+
+#include "KX_Scene.h"
+#include "KX_Camera.h"
+#include "DNA_screen_types.h"
+#include "RAS_ICanvas.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_IRenderTools.h"
+#include "KX_KetsjiEngine.h"
+
+#include "GL/glew.h"
+#include <vector>
+
+#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_TRUNCATED 2
+#define DOME_PANORAM_SPH 3
+#define DOME_NUM_MODES 4
+
+
+/// class for render 3d scene
+class KX_Dome
+{
+public:
+ /// constructor
+ KX_Dome (
+ RAS_ICanvas* m_canvas,
+ /// rasterizer
+ RAS_IRasterizer* m_rasterizer,
+ /// render tools
+ RAS_IRenderTools* m_rendertools,
+ /// engine
+ KX_KetsjiEngine* m_engine,
+
+ float size,
+ short res,
+ short mode,
+ short angle,
+ float resbuf,
+ struct Text* warptext
+ );
+
+ /// destructor
+ virtual ~KX_Dome (void);
+
+ //openGL checks:
+ bool dlistSupported;
+
+ //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
+ GLuint dlistId; // ID of the Display Lists of the images (used as an offset)
+
+ typedef struct {
+ double u[3], v[3];
+ MT_Vector3 verts[3]; //three verts
+ } DomeFace;
+
+ //mesh warp functions
+ typedef struct {
+ double x, y, u, v, i;
+ } WarpMeshNode;
+
+ struct {
+ bool usemesh;
+ int mode;
+ int n_width, n_height; //nodes width and height
+ int imagewidth, imageheight;
+ int bufferwidth, bufferheight;
+ vector <vector <WarpMeshNode> > nodes;
+ } warp;
+
+ bool ParseWarpMesh(STR_String text);
+
+ vector <DomeFace> cubetop, cubebottom, cuberight, cubeleft, cubefront, cubeback; //for fisheye
+ vector <DomeFace> cubeleftback, cuberightback; //for panorama
+
+ int nfacestop, nfacesbottom, nfacesleft, nfacesright, nfacesfront, nfacesback;
+ int nfacesleftback, nfacesrightback;
+
+ int GetNumberRenders(){return m_numfaces;};
+
+ void RenderDome(void);
+ void RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i);
+ void BindImages(int i);
+
+ void SetViewPort(GLuint viewport[4]);
+ void CalculateFrustum(KX_Camera* cam);
+ void RotateCamera(KX_Camera* cam, int i);
+
+ //Mesh Creating Functions
+ void CreateMeshDome180(void);
+ void CreateMeshDome250(void);
+ void CreateMeshPanorama(void);
+
+ void SplitFace(vector <DomeFace>& face, int *nfaces);
+
+ void FlattenDome(MT_Vector3 verts[3]);
+ void FlattenPanorama(MT_Vector3 verts[3]);
+
+ //Draw functions
+ void GLDrawTriangles(vector <DomeFace>& face, int nfaces);
+ void GLDrawWarpQuads(void);
+ void Draw(void);
+ void DrawDomeFisheye(void);
+ void DrawPanorama(void);
+ void DrawDomeWarped(void);
+
+ //setting up openGL
+ void CreateGLImages(void);
+ void ClearGLImages(void);//called on resize
+ bool CreateDL(void); //create Display Lists
+ void ClearDL(void); //remove Display Lists
+
+ void CalculateCameraOrientation();
+ void CalculateImageSize(); //set m_imagesize
+
+ int canvaswidth;
+ int canvasheight;
+
+protected:
+ int m_drawingmode;
+
+ int m_imagesize;
+ 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
+
+ RAS_Rect m_viewport;
+
+ MT_Matrix4x4 m_projmat;
+
+ MT_Matrix3x3 m_locRot [6];// the rotation matrix
+
+ /// rendered scene
+ KX_Scene * m_scene;
+
+ /// canvas
+ RAS_ICanvas* m_canvas;
+ /// rasterizer
+ RAS_IRasterizer* m_rasterizer;
+ /// render tools
+ RAS_IRenderTools* m_rendertools;
+ /// engine
+ KX_KetsjiEngine* m_engine;
+};
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index 3c0695b5952..8b587c6f7de 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -208,22 +208,22 @@ bool KX_GameActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_GameActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_GameActuator",
- sizeof(KX_GameActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -241,21 +241,38 @@ PyParentObject KX_GameActuator::Parents[] =
PyMethodDef KX_GameActuator::Methods[] =
{
+ // Deprecated ----->
{"getFile", (PyCFunction) KX_GameActuator::sPyGetFile, METH_VARARGS, (PY_METHODCHAR)GetFile_doc},
{"setFile", (PyCFunction) KX_GameActuator::sPySetFile, METH_VARARGS, (PY_METHODCHAR)SetFile_doc},
+ // <-----
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_GameActuator::Attributes[] = {
+ KX_PYATTRIBUTE_STRING_RW("file",0,100,false,KX_GameActuator,m_filename),
{ NULL } //Sentinel
};
+PyObject*
+KX_GameActuator::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_IActuator);
+}
+
+int KX_GameActuator::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(SCA_IActuator);
+}
+
+
+// Deprecated ----->
/* getFile */
const char KX_GameActuator::GetFile_doc[] =
"getFile()\n"
"get the name of the file to start.\n";
-PyObject* KX_GameActuator::PyGetFile(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_GameActuator::PyGetFile(PyObject* args, PyObject* kwds)
{
+ ShowDeprecationWarning("getFile()", "the file property");
return PyString_FromString(m_filename);
}
@@ -263,11 +280,13 @@ PyObject* KX_GameActuator::PyGetFile(PyObject* self, PyObject* args, PyObject* k
const char KX_GameActuator::SetFile_doc[] =
"setFile(name)\n"
"set the name of the file to start.\n";
-PyObject* KX_GameActuator::PySetFile(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_GameActuator::PySetFile(PyObject* args, PyObject* kwds)
{
char* new_file;
+
+ ShowDeprecationWarning("setFile()", "the file property");
- if (!PyArg_ParseTuple(args, "s", &new_file))
+ if (!PyArg_ParseTuple(args, "s:setFile", &new_file))
{
return NULL;
}
@@ -277,12 +296,4 @@ PyObject* KX_GameActuator::PySetFile(PyObject* self, PyObject* args, PyObject* k
Py_RETURN_NONE;
}
-
-
-
-PyObject* KX_GameActuator::_getattr(const char *attr)
-{
- _getattr_up(SCA_IActuator);
-}
-
-
+// <-----
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
index 856fa0c24e9..570cb2e68ef 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.h
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -77,9 +77,13 @@ protected:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+
+ // Deprecated functions ----->
KX_PYMETHOD_DOC(KX_GameActuator,GetFile);
KX_PYMETHOD_DOC(KX_GameActuator,SetFile);
+ // <-----
}; /* end of class KX_GameActuator */
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 95df9d51a26..bea0fcff2af 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -55,6 +55,7 @@ typedef unsigned long uint_ptr;
#include <stdio.h> // printf
#include "SG_Controller.h"
#include "KX_IPhysicsController.h"
+#include "PHY_IGraphicController.h"
#include "SG_Node.h"
#include "SG_Controller.h"
#include "KX_ClientObjectInfo.h"
@@ -64,6 +65,8 @@ typedef unsigned long uint_ptr;
#include "KX_PyMath.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
+#include "SCA_IController.h"
+#include "NG_NetworkScene.h" //Needed for sendMessage()
#include "PyObjectPlus.h" /* python stuff */
@@ -72,6 +75,12 @@ typedef unsigned long uint_ptr;
#include "KX_SG_NodeRelationships.h"
+static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
+static MT_Vector3 dummy_scaling = MT_Vector3(1.0, 1.0, 1.0);
+static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+
KX_GameObject::KX_GameObject(
void* sgReplicationInfo,
SG_Callbacks callbacks,
@@ -87,11 +96,14 @@ KX_GameObject::KX_GameObject(
m_bIsNegativeScaling(false),
m_bVisible(true),
m_bCulled(true),
+ m_bOccluder(false),
m_pPhysicsController1(NULL),
+ m_pGraphicController(NULL),
m_pPhysicsEnvironment(NULL),
m_xray(false),
m_pHitObject(NULL),
- m_isDeformable(false)
+ m_isDeformable(false),
+ m_attr_dict(NULL)
{
m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
@@ -129,9 +141,23 @@ KX_GameObject::~KX_GameObject()
}
m_pSGNode->SetSGClientObject(NULL);
}
+ if (m_pGraphicController)
+ {
+ delete m_pGraphicController;
+ }
+
+ if (m_attr_dict) {
+ PyDict_Clear(m_attr_dict); /* incase of circular refs or other weired cases */
+ Py_DECREF(m_attr_dict);
+ }
}
-
+KX_GameObject* KX_GameObject::GetClientObject(KX_ClientObjectInfo* info)
+{
+ if (!info)
+ return NULL;
+ return info->m_gameobject;
+}
CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val)
{
@@ -154,7 +180,7 @@ const STR_String & KX_GameObject::GetText()
-float KX_GameObject::GetNumber()
+double KX_GameObject::GetNumber()
{
return 0;
}
@@ -246,7 +272,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
NodeSetLocalScale(scale1);
NodeSetLocalPosition(MT_Point3(newpos[0],newpos[1],newpos[2]));
NodeSetLocalOrientation(invori*NodeGetWorldOrientation());
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
// object will now be a child, it must be removed from the parent list
CListValue* rootlist = scene->GetRootParentList();
if (rootlist->RemoveValue(this))
@@ -266,6 +292,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
rootobj->m_pPhysicsController1->AddCompoundChild(m_pPhysicsController1);
}
}
+ // graphically, the object hasn't change place, no need to update m_pGraphicController
}
}
@@ -283,7 +310,7 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
// Remove us from our parent
GetSGNode()->DisconnectFromParent();
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
// the object is now a root object, add it to the parentlist
CListValue* rootlist = scene->GetRootParentList();
if (!rootlist->SearchValue(this))
@@ -300,16 +327,21 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
}
m_pPhysicsController1->RestoreDynamics();
}
+ // graphically, the object hasn't change place, no need to update m_pGraphicController
}
}
void KX_GameObject::ProcessReplica(KX_GameObject* replica)
{
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;
+ if(m_attr_dict)
+ replica->m_attr_dict= PyDict_Copy(m_attr_dict);
+
}
@@ -345,11 +377,14 @@ void KX_GameObject::ApplyTorque(const MT_Vector3& torque,bool local)
void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
{
- if (m_pPhysicsController1) // (IsDynamic())
+ if (GetSGNode())
{
- m_pPhysicsController1->RelativeTranslate(dloc,local);
+ if (m_pPhysicsController1) // (IsDynamic())
+ {
+ m_pPhysicsController1->RelativeTranslate(dloc,local);
+ }
+ GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
}
- GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
}
@@ -357,11 +392,13 @@ void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
void KX_GameObject::ApplyRotation(const MT_Vector3& drot,bool local)
{
MT_Matrix3x3 rotmat(drot);
+
+ if (GetSGNode()) {
+ GetSGNode()->RelativeRotate(rotmat,local);
- GetSGNode()->RelativeRotate(rotmat,local);
-
- if (m_pPhysicsController1) { // (IsDynamic())
- m_pPhysicsController1->RelativeRotate(rotmat,local);
+ if (m_pPhysicsController1) { // (IsDynamic())
+ m_pPhysicsController1->RelativeRotate(rotmat,local);
+ }
}
}
@@ -374,16 +411,17 @@ double* KX_GameObject::GetOpenGLMatrix()
{
// todo: optimize and only update if necessary
double* fl = m_OpenGL_4x4Matrix.getPointer();
- MT_Transform trans;
+ if (GetSGNode()) {
+ MT_Transform trans;
- trans.setOrigin(GetSGNode()->GetWorldPosition());
- trans.setBasis(GetSGNode()->GetWorldOrientation());
+ trans.setOrigin(GetSGNode()->GetWorldPosition());
+ trans.setBasis(GetSGNode()->GetWorldOrientation());
- MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
- 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);
-
+ MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
+ 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);
+ }
return fl;
}
@@ -414,13 +452,15 @@ static void UpdateBuckets_recursive(SG_Node* node)
void KX_GameObject::UpdateBuckets( bool recursive )
{
- double* fl = GetOpenGLMatrix();
+ if (GetSGNode()) {
+ double* fl = GetOpenGLMatrixPtr()->getPointer();
- for (size_t i=0;i<m_meshes.size();i++)
- m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
+ for (size_t i=0;i<m_meshes.size();i++)
+ m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
- if (recursive) {
- UpdateBuckets_recursive(m_pSGNode);
+ if (recursive) {
+ UpdateBuckets_recursive(GetSGNode());
+ }
}
}
@@ -434,22 +474,18 @@ void KX_GameObject::RemoveMeshes()
m_meshes.clear();
}
-
-
-void KX_GameObject::UpdateNonDynas()
+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
+ // but merely sets there collision flag to "kinematic" because the synchronization is
+ // done differently during physics simulation
m_pPhysicsController1->SetSumoTransform(true);
- }
-}
-
-
+ if (m_pGraphicController)
+ // update the culling tree
+ m_pGraphicController->SetGraphicTransform();
-void KX_GameObject::UpdateTransform()
-{
- if (m_pPhysicsController1)
- m_pPhysicsController1->SetSumoTransform(false);
}
void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene)
@@ -575,28 +611,43 @@ KX_GameObject::SetVisible(
bool recursive
)
{
- m_bVisible = v;
- if (recursive)
- setVisible_recursive(m_pSGNode, v);
+ if (GetSGNode()) {
+ m_bVisible = v;
+ if (recursive)
+ setVisible_recursive(GetSGNode(), v);
+ }
}
-bool
-KX_GameObject::GetCulled(
- void
- )
+static void setOccluder_recursive(SG_Node* node, bool v)
{
- return m_bCulled;
+ NodeList& children = node->GetSGChildren();
+
+ for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
+ {
+ SG_Node* childnode = (*childit);
+ KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
+ if (clientgameobj != NULL) // This is a GameObject
+ clientgameobj->SetOccluder(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.
+ setOccluder_recursive(childnode, v);
+ }
}
void
-KX_GameObject::SetCulled(
- bool c
+KX_GameObject::SetOccluder(
+ bool v,
+ bool recursive
)
{
- m_bCulled = c;
+ if (GetSGNode()) {
+ m_bOccluder = v;
+ if (recursive)
+ setOccluder_recursive(GetSGNode(), v);
+ }
}
-
void
KX_GameObject::SetLayer(
int l
@@ -764,6 +815,16 @@ MT_Scalar KX_GameObject::GetMass()
return 0.0;
}
+MT_Vector3 KX_GameObject::GetLocalInertia()
+{
+ MT_Vector3 local_inertia(0.0,0.0,0.0);
+ if (m_pPhysicsController1)
+ {
+ local_inertia = m_pPhysicsController1->GetLocalInertia();
+ }
+ return local_inertia;
+}
+
MT_Vector3 KX_GameObject::GetLinearVelocity(bool local)
{
MT_Vector3 velocity(0.0,0.0,0.0), locvel;
@@ -829,6 +890,7 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
}
GetSGNode()->SetLocalPosition(trans);
+
}
@@ -883,7 +945,9 @@ void KX_GameObject::NodeSetRelativeScale(const MT_Vector3& scale)
void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans)
{
- SG_Node* parent = m_pSGNode->GetSGParent();
+ if (!GetSGNode())
+ return;
+ SG_Node* parent = GetSGNode()->GetSGParent();
if (parent != NULL)
{
// Make sure the objects have some scale
@@ -908,7 +972,7 @@ void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans)
}
-void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
+void KX_GameObject::NodeUpdateGS(double time)
{
if (GetSGNode())
GetSGNode()->UpdateWorldData(time);
@@ -918,13 +982,9 @@ void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
{
- static MT_Matrix3x3 defaultOrientation = MT_Matrix3x3( 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 0.0, 0.0, 1.0);
-
// check on valid node in case a python controller holds a reference to a deleted object
if (!GetSGNode())
- return defaultOrientation;
+ return dummy_orientation;
return GetSGNode()->GetWorldOrientation();
}
@@ -932,11 +992,9 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
{
- static MT_Vector3 defaultScaling = MT_Vector3(1.0, 1.0, 1.0);
-
// check on valid node in case a python controller holds a reference to a deleted object
if (!GetSGNode())
- return defaultScaling;
+ return dummy_scaling;
return GetSGNode()->GetWorldScaling();
}
@@ -949,7 +1007,7 @@ const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
if (GetSGNode())
return GetSGNode()->GetWorldPosition();
else
- return MT_Point3(0.0, 0.0, 0.0);
+ return dummy_point;
}
/* Suspend/ resume: for the dynamic behaviour, there is a simple
@@ -963,7 +1021,8 @@ void KX_GameObject::Resume(void)
{
if (m_suspended) {
SCA_IObject::Resume();
- GetPhysicsController()->RestoreDynamics();
+ if(GetPhysicsController())
+ GetPhysicsController()->RestoreDynamics();
m_suspended = false;
}
@@ -974,22 +1033,54 @@ void KX_GameObject::Suspend()
if ((!m_ignore_activity_culling)
&& (!m_suspended)) {
SCA_IObject::Suspend();
- GetPhysicsController()->SuspendDynamics();
+ if(GetPhysicsController())
+ GetPhysicsController()->SuspendDynamics();
m_suspended = true;
}
}
+static void walk_children(SG_Node* node, CListValue* list, bool recursive)
+{
+ if (!node)
+ return;
+ NodeList& children = node->GetSGChildren();
+ for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
+ {
+ SG_Node* childnode = (*childit);
+ CValue* childobj = (CValue*)childnode->GetSGClientObject();
+ if (childobj != NULL) // This is a GameObject
+ {
+ // add to the list
+ list->Add(childobj->AddRef());
+ }
+
+ // if the childobj is NULL then this may be an inverse parent link
+ // so a non recursive search should still look down this node.
+ if (recursive || childobj==NULL) {
+ walk_children(childnode, list, recursive);
+ }
+ }
+}
+CListValue* KX_GameObject::GetChildren()
+{
+ CListValue* list = new CListValue();
+ walk_children(GetSGNode(), list, 0); /* GetSGNode() is always valid or it would have raised an exception before this */
+ return list;
+}
-/* ------- python stuff ---------------------------------------------------*/
-
+CListValue* KX_GameObject::GetChildrenRecursive()
+{
+ CListValue* list = new CListValue();
+ walk_children(GetSGNode(), list, 1);
+ return list;
+}
+/* ------- python stuff ---------------------------------------------------*/
PyMethodDef KX_GameObject::Methods[] = {
- {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS},
- {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O},
{"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O},
{"applyForce", (PyCFunction) KX_GameObject::sPyApplyForce, METH_VARARGS},
{"applyTorque", (PyCFunction) KX_GameObject::sPyApplyTorque, METH_VARARGS},
@@ -1000,14 +1091,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getAngularVelocity", (PyCFunction) KX_GameObject::sPyGetAngularVelocity, METH_VARARGS},
{"setAngularVelocity", (PyCFunction) KX_GameObject::sPySetAngularVelocity, METH_VARARGS},
{"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
- {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_NOARGS},
{"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS},
- {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS},
- {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O},
- {"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_NOARGS},
- {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
- {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS},
- {"setState",(PyCFunction) KX_GameObject::sPySetState, METH_O},
{"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
{"getAxisVect",(PyCFunction) KX_GameObject::sPyGetAxisVect, METH_O},
{"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_NOARGS},
@@ -1016,25 +1100,66 @@ 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},
- {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_NOARGS},
{"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
+ {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
+ {"setOcclusion",(PyCFunction) KX_GameObject::sPySetOcclusion, METH_VARARGS},
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
{"getChildren", (PyCFunction)KX_GameObject::sPyGetChildren,METH_NOARGS},
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
- {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_NOARGS},
{"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS},
{"replaceMesh",(PyCFunction) KX_GameObject::sPyReplaceMesh, METH_O},
{"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS},
+
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
KX_PYMETHODTABLE(KX_GameObject, rayCast),
KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo),
KX_PYMETHODTABLE_O(KX_GameObject, getVectTo),
+ KX_PYMETHODTABLE(KX_GameObject, sendMessage),
+
+ // deprecated
+ {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS},
+ {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O},
+ {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS},
+ {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O},
+ {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS},
+ {"setState",(PyCFunction) KX_GameObject::sPySetState, METH_O},
+ {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_NOARGS},
+ {"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_NOARGS},
+ {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_NOARGS},
+ {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_GameObject::Attributes[] = {
- { NULL } //Sentinel
+ KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name),
+ KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
+ KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
+ KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min),
+ KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMax", KX_GameObject, pyattr_get_lin_vel_max, pyattr_set_lin_vel_max),
+ KX_PYATTRIBUTE_RW_FUNCTION("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
+ KX_PYATTRIBUTE_BOOL_RW ("occlusion", KX_GameObject, m_bOccluder),
+ KX_PYATTRIBUTE_RW_FUNCTION("position", KX_GameObject, pyattr_get_worldPosition, pyattr_set_localPosition),
+ KX_PYATTRIBUTE_RO_FUNCTION("localInertia", KX_GameObject, pyattr_get_localInertia),
+ KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_localOrientation),
+ KX_PYATTRIBUTE_RW_FUNCTION("scaling", KX_GameObject, pyattr_get_worldScaling, pyattr_set_localScaling),
+ KX_PYATTRIBUTE_RW_FUNCTION("timeOffset",KX_GameObject, pyattr_get_timeOffset,pyattr_set_timeOffset),
+ 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("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_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),
+ KX_PYATTRIBUTE_RO_FUNCTION("actuators", KX_GameObject, pyattr_get_actuators),
+ {NULL} //Sentinel
};
@@ -1054,29 +1179,19 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
}
*/
-PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PyReplaceMesh(PyObject* value)
{
KX_Scene *scene = KX_GetActiveScene();
- char* meshname;
- void* mesh_pt;
-
- meshname = PyString_AsString(value);
- if (meshname==NULL) {
- PyErr_SetString(PyExc_ValueError, "Expected a mesh name");
- return NULL;
- }
- mesh_pt = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname));
+ RAS_MeshObject* new_mesh;
- if (mesh_pt==NULL) {
- PyErr_SetString(PyExc_ValueError, "The mesh name given does not exist");
+ if (!ConvertPythonToMesh(value, &new_mesh, false, "gameOb.replaceMesh(value): KX_GameObject"))
return NULL;
- }
- scene->ReplaceMesh(this, (class RAS_MeshObject*)mesh_pt);
+ scene->ReplaceMesh(this, new_mesh);
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyEndObject(PyObject* self)
+PyObject* KX_GameObject::PyEndObject()
{
KX_Scene *scene = KX_GetActiveScene();
@@ -1087,34 +1202,183 @@ PyObject* KX_GameObject::PyEndObject(PyObject* self)
}
-PyObject* KX_GameObject::PyGetPosition(PyObject* self)
+PyObject* KX_GameObject::PyGetPosition()
{
+ ShowDeprecationWarning("getPosition()", "the position property");
return PyObjectFrom(NodeGetWorldPosition());
}
+Py_ssize_t KX_GameObject::Map_Len(PyObject* self_v)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>BGE_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_cast<KX_GameObject*>BGE_PROXY_REF(self_v);
+ const char *attr_str= PyString_AsString(item);
+ CValue* resultattr;
+ PyObject* pyconvert;
+
+ if (self==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
+ /* first see if the attributes a string and try get the cvalue attribute */
+ if(attr_str && (resultattr=self->GetProperty(attr_str))) {
+ pyconvert = resultattr->ConvertValueToPython();
+ return pyconvert ? pyconvert:resultattr->GetProxy();
+ }
+ /* no CValue attribute, try get the python only m_attr_dict attribute */
+ else if (self->m_attr_dict && (pyconvert=PyDict_GetItem(self->m_attr_dict, item))) {
+
+ if (attr_str)
+ PyErr_Clear();
+ Py_INCREF(pyconvert);
+ return pyconvert;
+ }
+ else {
+ if(attr_str) PyErr_Format(PyExc_KeyError, "value = gameOb[key]: KX_GameObject, key \"%s\" does not exist", attr_str);
+ else PyErr_SetString(PyExc_KeyError, "value = gameOb[key]: KX_GameObject, key does not exist");
+ return NULL;
+ }
+
+}
+
+
+int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v);
+ const char *attr_str= PyString_AsString(key);
+ if(attr_str==NULL)
+ PyErr_Clear();
+
+ if (self==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
+ return -1;
+ }
+
+ if (val==NULL) { /* del ob["key"] */
+ int del= 0;
+
+ /* try remove both just incase */
+ if(attr_str)
+ del |= (self->RemoveProperty(attr_str)==true) ? 1:0;
+
+ if(self->m_attr_dict)
+ del |= (PyDict_DelItem(self->m_attr_dict, key)==0) ? 1:0;
+
+ 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");
+ return -1;
+ }
+ else if (self->m_attr_dict) {
+ PyErr_Clear(); /* PyDict_DelItem sets an error when it fails */
+ }
+ }
+ else { /* ob["key"] = value */
+ int set= 0;
+
+ /* as CValue */
+ if(attr_str)
+ {
+ CValue* vallie = self->ConvertPythonToValue(val);
+
+ if(vallie)
+ {
+ CValue* oldprop = self->GetProperty(attr_str);
+
+ if (oldprop)
+ oldprop->SetValue(vallie);
+ else
+ self->SetProperty(attr_str, vallie);
+
+ vallie->Release();
+ set= 1;
+
+ /* try remove dict value to avoid double ups */
+ if (self->m_attr_dict){
+ if (PyDict_DelItem(self->m_attr_dict, key) != 0)
+ PyErr_Clear();
+ }
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+
+ if(set==0)
+ {
+ if (self->m_attr_dict==NULL) /* lazy init */
+ self->m_attr_dict= PyDict_New();
+
+
+ if(PyDict_SetItem(self->m_attr_dict, key, val)==0)
+ {
+ if(attr_str)
+ self->RemoveProperty(attr_str); /* overwrite the CValue if it exists */
+ set= 1;
+ }
+ else {
+ if(attr_str) PyErr_Format(PyExc_KeyError, "gameOb[key] = value: KX_GameObject, key \"%s\" not be added to internal dictionary", attr_str);
+ else PyErr_SetString(PyExc_KeyError, "gameOb[key] = value: KX_GameObject, key not be added to internal dictionary");
+ }
+ }
+
+ if(set==0)
+ return -1; /* pythons error value */
+
+ }
+
+ return 0; /* success */
+}
+
+
+PyMappingMethods KX_GameObject::Mapping = {
+ (lenfunc)KX_GameObject::Map_Len, /*inquiry mp_length */
+ (binaryfunc)KX_GameObject::Map_GetItem, /*binaryfunc mp_subscript */
+ (objobjargproc)KX_GameObject::Map_SetItem, /*objobjargproc mp_ass_subscript */
+};
+
PyTypeObject KX_GameObject::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_GameObject",
- sizeof(KX_GameObject),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
0,
0,
0,
- 0
+ py_base_repr,
+ 0,0,
+ &Mapping,
+ 0,0,0,
+ py_base_getattro,
+ py_base_setattro,
+ 0,0,0,0,0,0,0,0,0,
+ Methods
};
+
+
+
PyParentObject KX_GameObject::Parents[] = {
&KX_GameObject::Type,
&SCA_IObject::Type,
@@ -1122,181 +1386,448 @@ PyParentObject KX_GameObject::Parents[] = {
NULL
};
+PyObject* KX_GameObject::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ return PyString_FromString(self->GetName().ReadPtr());
+}
+PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_GameObject* parent = self->GetParent();
+ if (parent)
+ return parent->GetProxy();
+ Py_RETURN_NONE;
+}
+PyObject* KX_GameObject::pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetMass() : 0.0f);
+}
-PyObject* KX_GameObject::_getattr(const char *attr)
+int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
- if (m_pPhysicsController1)
- {
- if (!strcmp(attr, "mass"))
- return PyFloat_FromDouble(m_pPhysicsController1->GetMass());
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ 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;
}
- if (!strcmp(attr, "parent"))
- {
- KX_GameObject* parent = GetParent();
- if (parent)
- return parent->AddRef();
- Py_RETURN_NONE;
+ if (spc)
+ spc->SetMass(val);
+
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetLinVelocityMax() : 0.0f);
+}
+
+int KX_GameObject::pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ 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;
}
- if (!strcmp(attr, "visible"))
- return PyInt_FromLong(m_bVisible);
-
- if (!strcmp(attr, "position"))
- return PyObjectFrom(NodeGetWorldPosition());
-
- if (!strcmp(attr, "orientation"))
- return PyObjectFrom(NodeGetWorldOrientation());
+ if (spc)
+ spc->SetLinVelocityMin(val);
+
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ return PyFloat_FromDouble(spc ? spc->GetLinVelocityMax() : 0.0f);
+}
+
+int KX_GameObject::pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ KX_IPhysicsController *spc = self->GetPhysicsController();
+ 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;
+ }
+
+ if (spc)
+ spc->SetLinVelocityMax(val);
+
+ return 0;
+}
+
+
+PyObject* KX_GameObject::pyattr_get_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ return PyBool_FromLong(self->GetVisible());
+}
+
+int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ int param = PyObject_IsTrue( value );
+ if (param == -1) {
+ PyErr_SetString(PyExc_AttributeError, "gameOb.visible = bool: KX_GameObject, expected True or False");
+ return 1;
+ }
+
+ self->SetVisible(param, false);
+ self->UpdateBuckets(false);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ return PyObjectFrom(self->NodeGetWorldPosition());
+}
+
+int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ MT_Point3 pos;
+ if (!PyVecTo(value, pos))
+ return 1;
- if (!strcmp(attr, "scaling"))
- return PyObjectFrom(NodeGetWorldScaling());
-
- if (!strcmp(attr, "name"))
- return PyString_FromString(m_name.ReadPtr());
+ self->NodeSetWorldPosition(pos);
+ self->NodeUpdateGS(0.f);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode())
+ return PyObjectFrom(self->GetSGNode()->GetLocalPosition());
+ else
+ return PyObjectFrom(dummy_point);
+}
+
+int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ MT_Point3 pos;
+ if (!PyVecTo(value, pos))
+ return 1;
- if (!strcmp(attr, "timeOffset"))
+ self->NodeSetLocalPosition(pos);
+ self->NodeUpdateGS(0.f);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetPhysicsController())
{
- if (m_pSGNode->GetSGParent()->IsSlowParent()) {
- return PyFloat_FromDouble(static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->GetTimeOffset());
- } else {
- return PyFloat_FromDouble(0.0);
- }
+ return PyObjectFrom(self->GetPhysicsController()->GetLocalInertia());
}
+ return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f);
+}
+
+PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ return PyObjectFrom(self->NodeGetWorldOrientation());
+}
+
+PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode())
+ return PyObjectFrom(self->GetSGNode()->GetLocalOrientation());
+ else
+ return PyObjectFrom(dummy_orientation);
+}
+
+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);
-
- _getattr_up(SCA_IObject);
+ /* if value is not a sequence PyOrientationTo makes an error */
+ MT_Matrix3x3 rot;
+ if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, "))
+ return NULL;
+
+ self->NodeSetLocalOrientation(rot);
+ self->NodeUpdateGS(0.f);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ return PyObjectFrom(self->NodeGetWorldScaling());
+}
+
+PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode())
+ return PyObjectFrom(self->GetSGNode()->GetLocalScale());
+ else
+ return PyObjectFrom(dummy_scaling);
+}
+
+int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ MT_Vector3 scale;
+ if (!PyVecTo(value, scale))
+ return 1;
+
+ self->NodeSetLocalScale(scale);
+ self->NodeUpdateGS(0.f);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ SG_Node* sg_parent;
+ if (self->GetSGNode() && (sg_parent = self->GetSGNode()->GetSGParent()) != NULL && sg_parent->IsSlowParent()) {
+ return PyFloat_FromDouble(static_cast<KX_SlowParentRelation *>(sg_parent->GetParentRelation())->GetTimeOffset());
+ } else {
+ return PyFloat_FromDouble(0.0);
+ }
+}
+
+int KX_GameObject::pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ if (self->GetSGNode()) {
+ MT_Scalar val = PyFloat_AsDouble(value);
+ 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;
+ }
+ if (sg_parent && sg_parent->IsSlowParent())
+ static_cast<KX_SlowParentRelation *>(sg_parent->GetParentRelation())->SetTimeOffset(val);
+ }
+ return 0;
}
-int KX_GameObject::_setattr(const char *attr, PyObject *value) // _setattr method
+PyObject* KX_GameObject::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ int state = 0;
+ state |= self->GetState();
+ return PyInt_FromLong(state);
+}
+
+int KX_GameObject::pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ int state_i = PyInt_AsLong(value);
+ unsigned int state = 0;
- if (!strcmp(attr, "parent")) {
- PyErr_SetString(PyExc_AttributeError, "attribute \"parent\" is read only\nUse setParent()");
+ if (state_i == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "gameOb.state = int: KX_GameObject, expected an int bit field");
return 1;
}
-
- if (PyInt_Check(value))
+
+ 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;
+ }
+ self->SetState(state);
+ return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ PyObject *meshes= PyList_New(self->m_meshes.size());
+ int i;
+
+ for(i=0; i < self->m_meshes.size(); i++)
{
- int val = PyInt_AsLong(value);
- if (!strcmp(attr, "visible"))
- {
- SetVisible(val != 0, false);
- UpdateBuckets(false);
- return 0;
- }
+ KX_MeshProxy* meshproxy = new KX_MeshProxy(self->m_meshes[i]);
+ PyList_SET_ITEM(meshes, i, meshproxy->GetProxy());
}
+
+ return meshes;
+}
- if (PyFloat_Check(value))
+/* experemental! */
+PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ SCA_SensorList& sensors= self->GetSensors();
+ PyObject* resultlist = PyList_New(sensors.size());
+
+ for (unsigned int index=0;index<sensors.size();index++)
+ PyList_SET_ITEM(resultlist, index, sensors[index]->GetProxy());
+
+ return resultlist;
+}
+
+PyObject* KX_GameObject::pyattr_get_controllers(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ SCA_ControllerList& controllers= self->GetControllers();
+ PyObject* resultlist = PyList_New(controllers.size());
+
+ for (unsigned int index=0;index<controllers.size();index++)
+ PyList_SET_ITEM(resultlist, index, controllers[index]->GetProxy());
+
+ return resultlist;
+}
+
+PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ SCA_ActuatorList& actuators= self->GetActuators();
+ PyObject* resultlist = PyList_New(actuators.size());
+
+ for (unsigned int index=0;index<actuators.size();index++)
+ PyList_SET_ITEM(resultlist, index, actuators[index]->GetProxy());
+
+ 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<KX_GameObject*>(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)
{
- MT_Scalar val = PyFloat_AsDouble(value);
- if (!strcmp(attr, "timeOffset")) {
- if (m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsSlowParent()) {
- static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->SetTimeOffset(val);
- return 0;
- } else {
- return 0;
- }
- }
- if (!strcmp(attr, "mass")) {
- if (m_pPhysicsController1)
- m_pPhysicsController1->SetMass(val);
- return 0;
- }
+ int i;
+ for(i=0; i<PyList_Size(list); i++)
+ PyDict_SetItem(dict, PyList_GET_ITEM(list, i), Py_None);
}
+ else
+ PyErr_Clear();
+
+ Py_DECREF(list);
- if (PySequence_Check(value))
+ /* Add m_attr_dict if we have it */
+ if(self->m_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)
+{
+ py_getattro_up(SCA_IObject);
+}
+
+int KX_GameObject::py_setattro__internal(PyObject *attr, PyObject *value) // py_setattro method
+{
+ py_setattro_up(SCA_IObject);
+}
+
+
+PyObject* KX_GameObject::py_getattro(PyObject *attr)
+{
+ PyObject *object= py_getattro__internal(attr);
+
+ if (object==NULL && m_attr_dict)
{
- if (!strcmp(attr, "orientation"))
- {
- MT_Matrix3x3 rot;
- if (PyObject_IsMT_Matrix(value, 3))
- {
- if (PyMatTo(value, rot))
- {
- NodeSetLocalOrientation(rot);
- NodeUpdateGS(0.f,true);
- return 0;
- }
- return 1;
- }
-
- if (PySequence_Size(value) == 4)
- {
- MT_Quaternion qrot;
- if (PyVecTo(value, qrot))
- {
- rot.setRotation(qrot);
- NodeSetLocalOrientation(rot);
- NodeUpdateGS(0.f,true);
- return 0;
- }
- return 1;
- }
+ /* backup the exception incase the attr doesnt exist in the dict either */
+ PyObject *err_type, *err_value, *err_tb;
+ PyErr_Fetch(&err_type, &err_value, &err_tb);
+
+ object= PyDict_GetItem(m_attr_dict, attr);
+ if (object) {
+ Py_INCREF(object);
- if (PySequence_Size(value) == 3)
- {
- MT_Vector3 erot;
- if (PyVecTo(value, erot))
- {
- rot.setEuler(erot);
- NodeSetLocalOrientation(rot);
- NodeUpdateGS(0.f,true);
- return 0;
- }
- return 1;
- }
- PyErr_SetString(PyExc_AttributeError, "could not set the orientation from a 3x3 matrix, quaternion or euler sequence");
- return 1;
+ PyErr_Clear();
+ Py_XDECREF( err_type );
+ Py_XDECREF( err_value );
+ Py_XDECREF( err_tb );
}
-
- if (!strcmp(attr, "position"))
- {
- MT_Point3 pos;
- if (PyVecTo(value, pos))
- {
- NodeSetLocalPosition(pos);
- NodeUpdateGS(0.f,true);
- return 0;
- }
- return 1;
+ else {
+ PyErr_Restore(err_type, err_value, err_tb); /* use the error from the parent function */
}
-
- if (!strcmp(attr, "scaling"))
- {
- MT_Vector3 scale;
- if (PyVecTo(value, scale))
- {
- NodeSetLocalScale(scale);
- NodeUpdateGS(0.f,true);
- return 0;
- }
- return 1;
+ }
+ return object;
+}
+
+int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro method
+{
+ int ret;
+
+ ret= py_setattro__internal(attr, value);
+
+ if (ret==PY_SET_ATTR_SUCCESS) {
+ /* remove attribute in our own dict to avoid double ups */
+ /* NOTE: Annoying that we also do this for setting builtin attributes like mass and visibility :/ */
+ if (m_attr_dict) {
+ if (PyDict_DelItem(m_attr_dict, attr) != 0)
+ PyErr_Clear();
}
}
- if (PyString_Check(value))
- {
- if (!strcmp(attr, "name"))
- {
-#if 0 // was added in revision 2832, but never took into account Object name mappings from revision 2
- // unlikely anyone ever used this successfully , removing.
- m_name = PyString_AsString(value);
- return 0;
-#else
- PyErr_SetString(PyExc_AttributeError, "object name readonly");
- return 1;
-#endif
+ if (ret==PY_SET_ATTR_COERCE_FAIL) {
+ /* CValue attribute exists, remove CValue and add PyDict value */
+ RemoveProperty(STR_String(PyString_AsString(attr)));
+ ret= PY_SET_ATTR_MISSING;
+ }
+
+ if (ret==PY_SET_ATTR_MISSING) {
+ /* Lazy initialization */
+ if (m_attr_dict==NULL)
+ m_attr_dict = PyDict_New();
+
+ if (PyDict_SetItem(m_attr_dict, attr, value)==0) {
+ PyErr_Clear();
+ ret= PY_SET_ATTR_SUCCESS;
+ }
+ else {
+ PyErr_Format(PyExc_AttributeError, "gameOb.myAttr = value: KX_GameObject, failed assigning value to internal dictionary");
+ ret= PY_SET_ATTR_FAIL;
}
}
- /* Need to have parent settable here too */
+ return ret;
+}
+
+
+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
+ return 0;
+
+ if (m_attr_dict && (PyDict_DelItem(m_attr_dict, attr) == 0))
+ return 0;
- return SCA_IObject::_setattr(attr, value);
+ PyErr_Format(PyExc_AttributeError, "del gameOb.myAttr: KX_GameObject, attribute \"%s\" dosnt exist", attr_str);
+ return 1;
}
-PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args)
+
+PyObject* KX_GameObject::PyApplyForce(PyObject* args)
{
int local = 0;
PyObject* pyvect;
@@ -1311,7 +1842,7 @@ PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args)
return NULL;
}
-PyObject* KX_GameObject::PyApplyTorque(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyApplyTorque(PyObject* args)
{
int local = 0;
PyObject* pyvect;
@@ -1326,7 +1857,7 @@ PyObject* KX_GameObject::PyApplyTorque(PyObject* self, PyObject* args)
return NULL;
}
-PyObject* KX_GameObject::PyApplyRotation(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyApplyRotation(PyObject* args)
{
int local = 0;
PyObject* pyvect;
@@ -1341,7 +1872,7 @@ PyObject* KX_GameObject::PyApplyRotation(PyObject* self, PyObject* args)
return NULL;
}
-PyObject* KX_GameObject::PyApplyMovement(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyApplyMovement(PyObject* args)
{
int local = 0;
PyObject* pyvect;
@@ -1356,7 +1887,7 @@ PyObject* KX_GameObject::PyApplyMovement(PyObject* self, PyObject* args)
return NULL;
}
-PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* args)
{
// only can get the velocity if we have a physics object connected to us...
int local = 0;
@@ -1370,7 +1901,7 @@ PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args)
}
}
-PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PySetLinearVelocity(PyObject* args)
{
int local = 0;
PyObject* pyvect;
@@ -1385,7 +1916,7 @@ PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self, PyObject* args)
return NULL;
}
-PyObject* KX_GameObject::PyGetAngularVelocity(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyGetAngularVelocity(PyObject* args)
{
// only can get the velocity if we have a physics object connected to us...
int local = 0;
@@ -1399,7 +1930,7 @@ PyObject* KX_GameObject::PyGetAngularVelocity(PyObject* self, PyObject* args)
}
}
-PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PySetAngularVelocity(PyObject* args)
{
int local = 0;
PyObject* pyvect;
@@ -1414,7 +1945,7 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args)
return NULL;
}
-PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PySetVisible(PyObject* args)
{
int visible, recursive = 0;
if (!PyArg_ParseTuple(args,"i|i:setVisible",&visible, &recursive))
@@ -1426,20 +1957,33 @@ PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args)
}
-PyObject* KX_GameObject::PyGetVisible(PyObject* self)
+PyObject* KX_GameObject::PySetOcclusion(PyObject* args)
{
+ int occlusion, recursive = 0;
+ if (!PyArg_ParseTuple(args,"i|i:setOcclusion",&occlusion, &recursive))
+ return NULL;
+
+ SetOccluder(occlusion ? true:false, recursive ? true:false);
+ Py_RETURN_NONE;
+}
+
+PyObject* KX_GameObject::PyGetVisible()
+{
+ ShowDeprecationWarning("getVisible()", "the visible property");
return PyInt_FromLong(m_bVisible);
}
-PyObject* KX_GameObject::PyGetState(PyObject* self)
+PyObject* KX_GameObject::PyGetState()
{
+ ShowDeprecationWarning("getState()", "the state property");
int state = 0;
state |= GetState();
return PyInt_FromLong(state);
}
-PyObject* KX_GameObject::PySetState(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PySetState(PyObject* value)
{
+ ShowDeprecationWarning("setState()", "the state property");
int state_i = PyInt_AsLong(value);
unsigned int state = 0;
@@ -1458,9 +2002,7 @@ PyObject* KX_GameObject::PySetState(PyObject* self, PyObject* value)
Py_RETURN_NONE;
}
-
-
-PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyGetVelocity(PyObject* args)
{
// only can get the velocity if we have a physics object connected to us...
MT_Point3 point(0.0,0.0,0.0);
@@ -1486,110 +2028,89 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args)
-PyObject* KX_GameObject::PyGetMass(PyObject* self)
+PyObject* KX_GameObject::PyGetMass()
{
- return PyFloat_FromDouble(GetPhysicsController()->GetMass());
+ ShowDeprecationWarning("getMass()", "the mass property");
+ return PyFloat_FromDouble((GetPhysicsController() != NULL) ? GetPhysicsController()->GetMass() : 0.0f);
}
-
-
-PyObject* KX_GameObject::PyGetReactionForce(PyObject* self)
+PyObject* KX_GameObject::PyGetReactionForce()
{
// only can get the velocity if we have a physics object connected to us...
- return PyObjectFrom(GetPhysicsController()->getReactionForce());
+
+ // XXX - Currently not working with bullet intergration, see KX_BulletPhysicsController.cpp's getReactionForce
+ /*
+ if (GetPhysicsController())
+ return PyObjectFrom(GetPhysicsController()->getReactionForce());
+ return PyObjectFrom(dummy_point);
+ */
+
+ return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f);
+
}
-PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self)
+PyObject* KX_GameObject::PyEnableRigidBody()
{
- GetPhysicsController()->setRigidBody(true);
+ if(GetPhysicsController())
+ GetPhysicsController()->setRigidBody(true);
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self)
+PyObject* KX_GameObject::PyDisableRigidBody()
{
- GetPhysicsController()->setRigidBody(false);
+ if(GetPhysicsController())
+ GetPhysicsController()->setRigidBody(false);
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyGetParent(PyObject* self)
+PyObject* KX_GameObject::PyGetParent()
{
+ ShowDeprecationWarning("getParent()", "the parent property");
KX_GameObject* parent = this->GetParent();
if (parent)
- return parent->AddRef();
+ return parent->GetProxy();
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PySetParent(PyObject* value)
{
- if (!PyObject_TypeCheck(value, &KX_GameObject::Type)) {
- PyErr_SetString(PyExc_TypeError, "expected a KX_GameObject type");
+ KX_GameObject *obj;
+ if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject"))
return NULL;
- }
-
- // The object we want to set as parent
- CValue *m_ob = (CValue*)value;
- KX_GameObject *obj = ((KX_GameObject*)m_ob);
- KX_Scene *scene = KX_GetActiveScene();
- this->SetParent(scene, obj);
-
+ this->SetParent(KX_GetActiveScene(), obj);
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
+PyObject* KX_GameObject::PyRemoveParent()
{
KX_Scene *scene = KX_GetActiveScene();
this->RemoveParent(scene);
Py_RETURN_NONE;
}
-
-static void walk_children(SG_Node* node, CListValue* list, bool recursive)
-{
- NodeList& children = node->GetSGChildren();
-
- for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
- {
- SG_Node* childnode = (*childit);
- CValue* childobj = (CValue*)childnode->GetSGClientObject();
- if (childobj != NULL) // This is a GameObject
- {
- // add to the list
- list->Add(childobj->AddRef());
- }
-
- // if the childobj is NULL then this may be an inverse parent link
- // so a non recursive search should still look down this node.
- if (recursive || childobj==NULL) {
- walk_children(childnode, list, recursive);
- }
- }
-}
-
-PyObject* KX_GameObject::PyGetChildren(PyObject* self)
+PyObject* KX_GameObject::PyGetChildren()
{
- CListValue* list = new CListValue();
- walk_children(m_pSGNode, list, 0);
- return list;
+ return GetChildren()->NewProxy(true);
}
-PyObject* KX_GameObject::PyGetChildrenRecursive(PyObject* self)
+PyObject* KX_GameObject::PyGetChildrenRecursive()
{
- CListValue* list = new CListValue();
- walk_children(m_pSGNode, list, 1);
- return list;
+ return GetChildrenRecursive()->NewProxy(true);
}
-PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyGetMesh(PyObject* args)
{
+ ShowDeprecationWarning("getMesh()", "the meshes property");
+
int mesh = 0;
if (!PyArg_ParseTuple(args, "|i:getMesh", &mesh))
@@ -1598,7 +2119,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args)
if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0)
{
KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[mesh]);
- return meshproxy;
+ return meshproxy->NewProxy(true); // XXX Todo Python own.
}
Py_RETURN_NONE;
@@ -1608,7 +2129,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args)
-PyObject* KX_GameObject::PySetCollisionMargin(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PySetCollisionMargin(PyObject* value)
{
float collisionMargin = PyFloat_AsDouble(value);
@@ -1628,7 +2149,7 @@ PyObject* KX_GameObject::PySetCollisionMargin(PyObject* self, PyObject* value)
-PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyApplyImpulse(PyObject* args)
{
PyObject* pyattach;
PyObject* pyimpulse;
@@ -1655,7 +2176,7 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, PyObject* args)
-PyObject* KX_GameObject::PySuspendDynamics(PyObject* self)
+PyObject* KX_GameObject::PySuspendDynamics()
{
SuspendDynamics();
Py_RETURN_NONE;
@@ -1663,7 +2184,7 @@ PyObject* KX_GameObject::PySuspendDynamics(PyObject* self)
-PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self)
+PyObject* KX_GameObject::PyRestoreDynamics()
{
RestoreDynamics();
Py_RETURN_NONE;
@@ -1671,20 +2192,22 @@ PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self)
-PyObject* KX_GameObject::PyGetOrientation(PyObject* self) //keywords
+PyObject* KX_GameObject::PyGetOrientation() //keywords
{
+ ShowDeprecationWarning("getOrientation()", "the orientation property");
return PyObjectFrom(NodeGetWorldOrientation());
}
-PyObject* KX_GameObject::PySetOrientation(PyObject* self, PyObject* value)
+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,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
@@ -1693,13 +2216,13 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self, PyObject* value)
{
matrix.setRotation(quat);
NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
return NULL;
}
-PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, PyObject* args)
+PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args)
{
PyObject* pyvect;
int axis = 2; //z axis is the default
@@ -1714,14 +2237,14 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, PyObject* args)
if (fac> 1.0) fac= 1.0;
AlignAxisToVect(vect,axis,fac);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
}
return NULL;
}
-PyObject* KX_GameObject::PyGetAxisVect(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PyGetAxisVect(PyObject* value)
{
MT_Vector3 vect;
if (PyVecTo(value, vect))
@@ -1731,33 +2254,34 @@ PyObject* KX_GameObject::PyGetAxisVect(PyObject* self, PyObject* value)
return NULL;
}
-PyObject* KX_GameObject::PySetPosition(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PySetPosition(PyObject* value)
{
+ ShowDeprecationWarning("setPosition()", "the position property");
MT_Point3 pos;
if (PyVecTo(value, pos))
{
NodeSetLocalPosition(pos);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
return NULL;
}
-PyObject* KX_GameObject::PySetWorldPosition(PyObject* self, PyObject* value)
+PyObject* KX_GameObject::PySetWorldPosition(PyObject* value)
{
MT_Point3 pos;
if (PyVecTo(value, pos))
{
NodeSetWorldPosition(pos);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
return NULL;
}
-PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self)
+PyObject* KX_GameObject::PyGetPhysicsId()
{
KX_IPhysicsController* ctrl = GetPhysicsController();
uint_ptr physid=0;
@@ -1768,9 +2292,19 @@ PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self)
return PyInt_FromLong((long)physid);
}
-PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self)
+PyObject* KX_GameObject::PyGetPropertyNames()
{
- return ConvertKeysToPython();
+ PyObject *list= ConvertKeysToPython();
+
+ if(m_attr_dict) {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ while (PyDict_Next(m_attr_dict, &pos, &key, &value)) {
+ PyList_Append(list, key);
+ }
+ }
+ return list;
}
KX_PYMETHODDEF_DOC_O(KX_GameObject, getDistanceTo,
@@ -1784,7 +2318,7 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getDistanceTo,
PyErr_Clear();
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()));
}
@@ -1807,12 +2341,12 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo,
PyErr_Clear();
KX_GameObject *other;
- if (ConvertPythonToGameObject(value, &other, false))
+ if (ConvertPythonToGameObject(value, &other, false, "")) /* error will be overwritten */
{
toPoint = other->NodeGetWorldPosition();
} else
{
- PyErr_SetString(PyExc_TypeError, "Expected a 3D Vector or GameObject type");
+ PyErr_SetString(PyExc_TypeError, "gameOb.getVectTo(other): KX_GameObject, expected a 3D Vector or KX_GameObject type");
return NULL;
}
}
@@ -1901,12 +2435,12 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
KX_GameObject *other;
PyErr_Clear();
- if (ConvertPythonToGameObject(pyarg, &other, false))
+ if (ConvertPythonToGameObject(pyarg, &other, false, "")) /* error will be overwritten */
{
toPoint = other->NodeGetWorldPosition();
} else
{
- PyErr_SetString(PyExc_TypeError, "the first argument to rayCastTo must be a vector or a KX_GameObject");
+ PyErr_SetString(PyExc_TypeError, "gameOb.rayCastTo(other,dist,prop): KX_GameObject, the first argument to rayCastTo must be a vector or a KX_GameObject");
return NULL;
}
}
@@ -1935,7 +2469,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
if (m_pHitObject)
- return m_pHitObject->AddRef();
+ return m_pHitObject->GetProxy();
Py_RETURN_NONE;
}
@@ -1977,7 +2511,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
{
PyErr_Clear();
- if (ConvertPythonToGameObject(pyto, &other, false))
+ if (ConvertPythonToGameObject(pyto, &other, false, "")) /* error will be overwritten */
{
toPoint = other->NodeGetWorldPosition();
} else
@@ -1994,12 +2528,12 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
{
PyErr_Clear();
- if (ConvertPythonToGameObject(pyfrom, &other, false))
+ if (ConvertPythonToGameObject(pyfrom, &other, false, "")) /* error will be overwritten */
{
fromPoint = other->NodeGetWorldPosition();
} else
{
- PyErr_SetString(PyExc_TypeError, "the second optional argument to rayCast must be a vector or a KX_GameObject");
+ PyErr_SetString(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly): KX_GameObject, the second optional argument to rayCast must be a vector or a KX_GameObject");
return NULL;
}
}
@@ -2037,7 +2571,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
{
PyObject* returnValue = (poly) ? PyTuple_New(4) : PyTuple_New(3);
if (returnValue) { // unlikely this would ever fail, if it does python sets an error
- PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef());
+ PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->GetProxy());
PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(callback.m_hitPoint));
PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(callback.m_hitNormal));
if (poly)
@@ -2047,7 +2581,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
// if this field is set, then we can trust that m_hitPolygon is a valid polygon
RAS_Polygon* polygon = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon);
KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, polygon);
- PyTuple_SET_ITEM(returnValue, 3, polyproxy);
+ PyTuple_SET_ITEM(returnValue, 3, polyproxy->NewProxy(true));
}
else
{
@@ -2065,6 +2599,26 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
}
+KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage,
+ "sendMessage(subject, [body, to])\n"
+"sends a message in same manner as a message actuator"
+"subject = Subject of the message (string)"
+"body = Message body (string)"
+"to = Name of object to send the message to")
+{
+ char* subject;
+ char* body = (char *)"";
+ char* to = (char *)"";
+ const STR_String& from = GetName();
+
+ if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to))
+ return NULL;
+
+ KX_GetActiveScene()->GetNetworkScene()->SendMessage(to, from, subject, body);
+
+ Py_RETURN_NONE;
+}
+
/* ---------------------------------------------------------------------
* Some stuff taken from the header
* --------------------------------------------------------------------- */
@@ -2087,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) {
- 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;
return false;
}
@@ -2101,33 +2655,40 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
if (py_none_ok) {
return true;
} 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;
}
}
if (PyString_Check(value)) {
- *object = (KX_GameObject *)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( PyString_AsString(value) ));
+ *object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( PyString_AsString(value) ));
if (*object) {
return true;
} 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;
}
}
if (PyObject_TypeCheck(value, &KX_GameObject::Type)) {
- *object = static_cast<KX_GameObject*>(value);
+ *object = static_cast<KX_GameObject*>BGE_PROXY_REF(value);
+
+ /* sets the error */
+ if (*object==NULL) {
+ PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
+ return false;
+ }
+
return true;
}
*object = NULL;
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 {
- 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;
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 211c9b7ca7d..ec02dc17b75 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -51,15 +51,18 @@
#include "SCA_LogicManager.h" /* for ConvertPythonToGameObject to search object names */
#define KX_OB_DYNAMIC 1
-
//Forward declarations.
struct KX_ClientObjectInfo;
class KX_RayCast;
class RAS_MeshObject;
class KX_IPhysicsController;
+class PHY_IGraphicController;
class PHY_IPhysicsEnvironment;
struct Object;
+/* utility conversion function */
+bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix);
+
/**
* KX_GameObject is the main class for dynamic objects.
*/
@@ -86,8 +89,10 @@ protected:
// culled = while rendering, depending on camera
bool m_bVisible;
bool m_bCulled;
+ bool m_bOccluder;
KX_IPhysicsController* m_pPhysicsController1;
+ PHY_IGraphicController* m_pGraphicController;
// used for ray casting
PHY_IPhysicsEnvironment* m_pPhysicsEnvironment;
STR_String m_testPropName;
@@ -101,6 +106,28 @@ protected:
public:
bool m_isDeformable;
+ /**
+ * Helper function for modules that can't include KX_ClientObjectInfo.h
+ */
+ static KX_GameObject* GetClientObject(KX_ClientObjectInfo* info);
+
+ // Python attributes that wont convert into CValue
+ //
+ // there are 2 places attributes can be stored, in the CValue,
+ // where attributes are converted into BGE's CValue types
+ // these can be used with property actuators
+ //
+ // For the python API, For types that cannot be converted into CValues (lists, dicts, GameObjects)
+ // these will be put into "m_attr_dict", logic bricks cannot access them.
+ //
+ // rules for setting attributes.
+ //
+ // * there should NEVER be a CValue and a m_attr_dict attribute with matching names. get/sets make sure of this.
+ // * if CValue conversion fails, use a PyObject in "m_attr_dict"
+ // * when assigning a value, first see if it can be a CValue, if it can remove the "m_attr_dict" and set the CValue
+ //
+ PyObject* m_attr_dict;
+
virtual void /* This function should be virtual - derived classed override it */
Relink(
GEN_Map<GEN_HashedPtr, void*> *map
@@ -206,7 +233,7 @@ public:
/**
* Inherited from CValue -- does nothing!
*/
- float
+ double
GetNumber(
);
@@ -279,6 +306,12 @@ public:
MT_Scalar
GetMass();
+ /**
+ * Return the local inertia vector of the object
+ */
+ MT_Vector3
+ GetLocalInertia();
+
/**
* Return the angular velocity of the game object.
*/
@@ -351,6 +384,19 @@ public:
}
/**
+ * @return a pointer to the graphic controller owner by this class
+ */
+ PHY_IGraphicController* GetGraphicController()
+ {
+ return m_pGraphicController;
+ }
+
+ void SetGraphicController(PHY_IGraphicController* graphiccontroller)
+ {
+ m_pGraphicController = graphiccontroller;
+ }
+
+ /**
* @section Coordinate system manipulation functions
*/
@@ -367,8 +413,7 @@ public:
void
NodeUpdateGS(
- double time,
- bool bInitiator
+ double time
);
const
@@ -525,13 +570,6 @@ public:
static void UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene);
/**
- * Only update the transform if it's a non-dynamic object
- */
- void
- UpdateNonDynas(
- );
-
- /**
* Function to set IPO option at start of IPO
*/
void
@@ -665,20 +703,37 @@ public:
/**
* Was this object culled?
*/
- bool
+ inline bool
GetCulled(
void
- );
+ ) { return m_bCulled; }
/**
* Set culled flag of this object
*/
- void
+ inline void
SetCulled(
bool c
- );
+ ) { m_bCulled = c; }
+
+ /**
+ * Is this object an occluder?
+ */
+ inline bool
+ GetOccluder(
+ void
+ ) { return m_bOccluder; }
/**
+ * Set occluder flag of this object
+ */
+ void
+ SetOccluder(
+ bool v,
+ bool recursive
+ );
+
+ /**
* Change the layer of the object (when it is added in another layer
* than the original layer)
*/
@@ -752,14 +807,29 @@ public:
}
KX_ClientObjectInfo* getClientInfo() { return m_pClient_info; }
+
+ CListValue* GetChildren();
+ CListValue* GetChildrenRecursive();
+
/**
* @section Python interface functions.
*/
-
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *value); // _setattr method
- virtual PyObject* _repr(void) { return PyString_FromString(GetName().ReadPtr()); }
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value); // py_setattro method
+ virtual int py_delattro(PyObject *attr);
+ virtual PyObject* py_repr(void)
+ {
+ return PyString_FromString(GetName().ReadPtr());
+ }
+
+
+ /* quite annoying that we need these but the bloody
+ * py_getattro_up and py_setattro_up macro's have a returns in them! */
+ PyObject* py_getattro__internal(PyObject *attr);
+ int py_setattro__internal(PyObject *attr, PyObject *value); // py_setattro method
+
+
KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition);
KX_PYMETHOD_O(KX_GameObject,SetPosition);
KX_PYMETHOD_O(KX_GameObject,SetWorldPosition);
@@ -778,6 +848,7 @@ public:
KX_PYMETHOD_O(KX_GameObject,SetOrientation);
KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible);
KX_PYMETHOD_VARARGS(KX_GameObject,SetVisible);
+ KX_PYMETHOD_VARARGS(KX_GameObject,SetOcclusion);
KX_PYMETHOD_NOARGS(KX_GameObject,GetState);
KX_PYMETHOD_O(KX_GameObject,SetState);
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
@@ -802,6 +873,50 @@ public:
KX_PYMETHOD_DOC(KX_GameObject,rayCast);
KX_PYMETHOD_DOC_O(KX_GameObject,getDistanceTo);
KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo);
+ KX_PYMETHOD_DOC_VARARGS(KX_GameObject, sendMessage);
+ /* 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);
+
+ static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ 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 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);
+ static PyObject* pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ 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);
+
+ /* for dir(), python3 uses __dir__() */
+ static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
+ /* Experemental! */
+ static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_controllers(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
+ /* getitem/setitem */
+ static Py_ssize_t Map_Len(PyObject* self);
+ static PyMappingMethods Mapping;
+ static PyObject* Map_GetItem(PyObject *self_v, PyObject *item);
+ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val);
private :
@@ -820,8 +935,7 @@ private :
};
-/* utility conversion function */
-bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok);
+
#endif //__KX_GAMEOBJECT
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
index 13501f1fbbd..10b66da7b76 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -79,6 +79,13 @@ public:
virtual void setScaling(const MT_Vector3& scaling)=0;
virtual MT_Scalar GetMass()=0;
virtual void SetMass(MT_Scalar newmass)=0;
+
+ virtual float GetLinVelocityMin()=0;
+ virtual void SetLinVelocityMin(float newmass)=0;
+ virtual float GetLinVelocityMax()=0;
+ virtual void SetLinVelocityMax(float newmass)=0;
+
+ virtual MT_Vector3 GetLocalInertia()=0;
virtual MT_Vector3 getReactionForce()=0;
virtual void setRigidBody(bool rigid)=0;
virtual void AddCompoundChild(KX_IPhysicsController* child) = 0;
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index 623a939bf62..f04e3c79a8e 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -84,7 +84,7 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
m_ipo_as_force(ipo_as_force),
m_ipo_add(ipo_add),
m_ipo_local(ipo_local),
- m_type((IpoActType)acttype)
+ m_type(acttype)
{
m_starttime = -2.0*fabs(m_endframe - m_startframe) - 1.0;
m_bIpoPlaying = false;
@@ -190,7 +190,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
}
}
- switch (m_type)
+ switch ((IpoActType)m_type)
{
case KX_ACT_IPO_PLAY:
@@ -383,7 +383,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
return result;
}
-KX_IpoActuator::IpoActType KX_IpoActuator::string2mode(char* modename) {
+int KX_IpoActuator::string2mode(char* modename) {
IpoActType res = KX_ACT_IPO_NODEF;
if (modename == S_KX_ACT_IPO_PLAY_STRING) {
@@ -413,22 +413,22 @@ KX_IpoActuator::IpoActType KX_IpoActuator::string2mode(char* modename) {
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_IpoActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_IpoActuator",
- sizeof(KX_IpoActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_IpoActuator::Parents[] = {
@@ -441,6 +441,8 @@ PyParentObject KX_IpoActuator::Parents[] = {
PyMethodDef KX_IpoActuator::Methods[] = {
{"set", (PyCFunction) KX_IpoActuator::sPySet, METH_VARARGS, (PY_METHODCHAR)Set_doc},
+
+ // deprecated
{"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},
@@ -450,22 +452,35 @@ PyMethodDef KX_IpoActuator::Methods[] = {
{"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce, METH_NOARGS, (PY_METHODCHAR)GetIpoAsForce_doc},
{"setIpoAdd", (PyCFunction) KX_IpoActuator::sPySetIpoAdd, METH_VARARGS, (PY_METHODCHAR)SetIpoAdd_doc},
{"getIpoAdd", (PyCFunction) KX_IpoActuator::sPyGetIpoAdd, METH_NOARGS, (PY_METHODCHAR)GetIpoAdd_doc},
- {"setType", (PyCFunction) KX_IpoActuator::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc},
- {"getType", (PyCFunction) KX_IpoActuator::sPyGetType, METH_NOARGS, (PY_METHODCHAR)GetType_doc},
{"setForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPySetForceIpoActsLocal, METH_VARARGS, (PY_METHODCHAR)SetForceIpoActsLocal_doc},
{"getForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPyGetForceIpoActsLocal, METH_NOARGS, (PY_METHODCHAR)GetForceIpoActsLocal_doc},
+ {"setType", (PyCFunction) KX_IpoActuator::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc},
+ {"getType", (PyCFunction) KX_IpoActuator::sPyGetType, METH_NOARGS, (PY_METHODCHAR)GetType_doc},
{NULL,NULL} //Sentinel
};
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_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_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),
+ KX_PYATTRIBUTE_BOOL_RW("useChildren", KX_IpoActuator, m_recurse),
+
{ NULL } //Sentinel
};
-PyObject* KX_IpoActuator::_getattr(const char *attr) {
- _getattr_up(SCA_IActuator);
+PyObject* KX_IpoActuator::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_IActuator);
}
-
+int KX_IpoActuator::py_setattro(PyObject *attr, PyObject *value) // py_setattro method
+{
+ py_setattro_up(SCA_IActuator);
+}
/* set --------------------------------------------------------------------- */
const char KX_IpoActuator::Set_doc[] =
@@ -475,17 +490,18 @@ const char KX_IpoActuator::Set_doc[] =
"\t - endframe : last frame to use (int)\n"
"\t - mode? : special mode (0=normal, 1=interpret location as force, 2=additive)"
"\tSet the properties of the actuator.\n";
-PyObject* KX_IpoActuator::PySet(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySet(PyObject* args) {
+
+ ShowDeprecationWarning("set()", "a number properties");
+
/* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND */
/* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe, */
/* arg4 = force toggle */
char* mode;
int forceToggle;
- IpoActType modenum;
+ int modenum;
int startFrame, stopFrame;
- if(!PyArg_ParseTuple(args, "siii", &mode, &startFrame,
+ if(!PyArg_ParseTuple(args, "siii:set", &mode, &startFrame,
&stopFrame, &forceToggle)) {
return NULL;
}
@@ -515,13 +531,14 @@ const char KX_IpoActuator::SetProperty_doc[] =
"setProperty(propname)\n"
"\t - propname: name of the property (string)\n"
"\tSet the property to be used in FromProp mode.\n";
-PyObject* KX_IpoActuator::PySetProperty(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetProperty(PyObject* args) {
+
+ ShowDeprecationWarning("setProperty()", "the propName property");
+
/* mode is implicit here, but not supported yet... */
/* args: property */
char *propertyName;
- if(!PyArg_ParseTuple(args, "s", &propertyName)) {
+ if(!PyArg_ParseTuple(args, "s:setProperty", &propertyName)) {
return NULL;
}
@@ -535,11 +552,12 @@ const char KX_IpoActuator::SetStart_doc[] =
"setStart(frame)\n"
"\t - frame: first frame to use (int)\n"
"\tSet the frame from which the ipo starts playing.\n";
-PyObject* KX_IpoActuator::PySetStart(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetStart(PyObject* args) {
+
+ ShowDeprecationWarning("setStart()", "the startFrame property");
+
float startArg;
- if(!PyArg_ParseTuple(args, "f", &startArg)) {
+ if(!PyArg_ParseTuple(args, "f:setStart", &startArg)) {
return NULL;
}
@@ -551,7 +569,8 @@ PyObject* KX_IpoActuator::PySetStart(PyObject* self,
const char KX_IpoActuator::GetStart_doc[] =
"getStart()\n"
"\tReturns the frame from which the ipo starts playing.\n";
-PyObject* KX_IpoActuator::PyGetStart(PyObject* self) {
+PyObject* KX_IpoActuator::PyGetStart() {
+ ShowDeprecationWarning("getStart()", "the startFrame property");
return PyFloat_FromDouble(m_startframe);
}
@@ -560,11 +579,10 @@ const char KX_IpoActuator::SetEnd_doc[] =
"setEnd(frame)\n"
"\t - frame: last frame to use (int)\n"
"\tSet the frame at which the ipo stops playing.\n";
-PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetEnd(PyObject* args) {
+ ShowDeprecationWarning("setEnd()", "the endFrame property");
float endArg;
- if(!PyArg_ParseTuple(args, "f", &endArg)) {
+ if(!PyArg_ParseTuple(args, "f:setEnd", &endArg)) {
return NULL;
}
@@ -576,7 +594,8 @@ PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
const char KX_IpoActuator::GetEnd_doc[] =
"getEnd()\n"
"\tReturns the frame at which the ipo stops playing.\n";
-PyObject* KX_IpoActuator::PyGetEnd(PyObject* self) {
+PyObject* KX_IpoActuator::PyGetEnd() {
+ ShowDeprecationWarning("getEnd()", "the endFrame property");
return PyFloat_FromDouble(m_endframe);
}
@@ -585,12 +604,11 @@ const char KX_IpoActuator::SetIpoAsForce_doc[] =
"setIpoAsForce(force?)\n"
"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)\n"
"\tSet whether to interpret the ipo as a force rather than a displacement.\n";
-PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* args) {
+ ShowDeprecationWarning("setIpoAsForce()", "the useIpoAsForce property");
int boolArg;
- if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ if (!PyArg_ParseTuple(args, "i:setIpoAsForce", &boolArg)) {
return NULL;
}
@@ -604,7 +622,8 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
const char KX_IpoActuator::GetIpoAsForce_doc[] =
"getIpoAsForce()\n"
"\tReturns whether to interpret the ipo as a force rather than a displacement.\n";
-PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self) {
+PyObject* KX_IpoActuator::PyGetIpoAsForce() {
+ ShowDeprecationWarning("getIpoAsForce()", "the useIpoAsForce property");
return BoolToPyArg(m_ipo_as_force);
}
@@ -613,12 +632,11 @@ const char KX_IpoActuator::SetIpoAdd_doc[] =
"setIpoAdd(add?)\n"
"\t - add? : add flag (KX_TRUE, KX_FALSE)\n"
"\tSet whether to interpret the ipo as additive rather than absolute.\n";
-PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* args) {
+ ShowDeprecationWarning("setIpoAdd()", "the useIpoAdd property");
int boolArg;
- if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ if (!PyArg_ParseTuple(args, "i:setIpoAdd", &boolArg)) {
return NULL;
}
@@ -632,7 +650,8 @@ PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self,
const char KX_IpoActuator::GetIpoAdd_doc[] =
"getIpoAsAdd()\n"
"\tReturns whether to interpret the ipo as additive rather than absolute.\n";
-PyObject* KX_IpoActuator::PyGetIpoAdd(PyObject* self) {
+PyObject* KX_IpoActuator::PyGetIpoAdd() {
+ ShowDeprecationWarning("getIpoAdd()", "the useIpoAdd property");
return BoolToPyArg(m_ipo_add);
}
@@ -641,18 +660,17 @@ const char KX_IpoActuator::SetType_doc[] =
"setType(mode)\n"
"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
"\tSet the operation mode of the actuator.\n";
-PyObject* KX_IpoActuator::PySetType(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetType(PyObject* args) {
+ ShowDeprecationWarning("setType()", "the type property");
int typeArg;
- if (!PyArg_ParseTuple(args, "i", &typeArg)) {
+ if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
return NULL;
}
if ( (typeArg > KX_ACT_IPO_NODEF)
- && (typeArg < KX_ACT_IPO_KEY2KEY) ) {
- m_type = (IpoActType) typeArg;
+ && (typeArg < KX_ACT_IPO_MAX) ) {
+ m_type = typeArg;
}
Py_RETURN_NONE;
@@ -661,7 +679,8 @@ PyObject* KX_IpoActuator::PySetType(PyObject* self,
const char KX_IpoActuator::GetType_doc[] =
"getType()\n"
"\tReturns the operation mode of the actuator.\n";
-PyObject* KX_IpoActuator::PyGetType(PyObject* self) {
+PyObject* KX_IpoActuator::PyGetType() {
+ ShowDeprecationWarning("getType()", "the type property");
return PyInt_FromLong(m_type);
}
@@ -672,12 +691,11 @@ const char KX_IpoActuator::SetForceIpoActsLocal_doc[] =
"\t coordinates? (KX_TRUE, KX_FALSE)\n"
"\tSet whether to apply the force in the object's local\n"
"\tcoordinates rather than the world global coordinates.\n";
-PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* args) {
+ ShowDeprecationWarning("setForceIpoActsLocal()", "the useIpoLocal property");
int boolArg;
- if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ if (!PyArg_ParseTuple(args, "i:setForceIpoActsLocal", &boolArg)) {
return NULL;
}
@@ -690,7 +708,8 @@ const char KX_IpoActuator::GetForceIpoActsLocal_doc[] =
"getForceIpoActsLocal()\n"
"\tReturn whether to apply the force in the object's local\n"
"\tcoordinates rather than the world global coordinates.\n";
-PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self) {
+PyObject* KX_IpoActuator::PyGetForceIpoActsLocal() {
+ ShowDeprecationWarning("getForceIpoActsLocal()", "the useIpoLocal property");
return BoolToPyArg(m_ipo_local);
}
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h
index 12e1835ab49..184ad5512de 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.h
+++ b/source/gameengine/Ketsji/KX_IpoActuator.h
@@ -108,9 +108,9 @@ public:
static STR_String S_KX_ACT_IPO_KEY2KEY_STRING;
static STR_String S_KX_ACT_IPO_FROM_PROP_STRING;
- IpoActType string2mode(char* modename);
+ int string2mode(char* modename);
- IpoActType m_type;
+ int m_type;
KX_IpoActuator(SCA_IObject* gameobj,
const STR_String& propname,
@@ -141,22 +141,24 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+
//KX_PYMETHOD_DOC
- KX_PYMETHOD_DOC(KX_IpoActuator,Set);
- KX_PYMETHOD_DOC(KX_IpoActuator,SetProperty);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,Set);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetProperty);
/* KX_PYMETHOD_DOC(KX_IpoActuator,SetKey2Key); */
- KX_PYMETHOD_DOC(KX_IpoActuator,SetStart);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetStart);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetStart);
- KX_PYMETHOD_DOC(KX_IpoActuator,SetEnd);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetEnd);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetEnd);
- KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAsForce);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetIpoAsForce);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetIpoAsForce);
- KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAdd);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetIpoAdd);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetIpoAdd);
- KX_PYMETHOD_DOC(KX_IpoActuator,SetType);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetType);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetType);
- KX_PYMETHOD_DOC(KX_IpoActuator,SetForceIpoActsLocal);
+ KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,SetForceIpoActsLocal);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetForceIpoActsLocal);
};
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 97b4213b8bd..83a2fa8a448 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -55,6 +55,7 @@
#include "KX_Scene.h"
#include "MT_CmMatrix4x4.h"
#include "KX_Camera.h"
+#include "KX_Dome.h"
#include "KX_Light.h"
#include "KX_PythonInit.h"
#include "KX_PyConstraintBinding.h"
@@ -144,6 +145,8 @@ 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
@@ -179,6 +182,8 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
KX_KetsjiEngine::~KX_KetsjiEngine()
{
delete m_logger;
+ if(m_usedome)
+ delete m_dome;
}
@@ -256,7 +261,129 @@ 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)
+{
+ m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, size, res, mode, angle, resbuf, text);
+ m_usedome = true;
+}
+
+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);
+
+ KX_Scene* firstscene = *m_scenes.begin();
+ const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
+
+ m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+
+ // hiding mouse cursor each frame
+ // (came back when going out of focus and then back in again)
+ if (m_hideCursor)
+ m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
+
+ // clear the entire game screen with the border color
+ // only once per frame
+
+ m_canvas->BeginDraw();
+
+ // BeginFrame() sets the actual drawing area. You can use a part of the window
+ if (!BeginFrame())
+ return;
+
+ KX_SceneList::iterator sceneit;
+ 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;i<n_renders;i++){
+ m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+ // for each scene, call the proceed functions
+ {
+ KX_Scene* scene = *sceneit;
+ KX_Camera* cam = scene->GetActiveCamera();
+
+ m_rendertools->BeginFrame(m_rasterizer);
+ // pass the scene's worldsettings to the rasterizer
+ SetWorldSettings(scene->GetWorldInfo());
+
+ // shadow buffers
+ if (i == 0){
+ RenderShadowBuffers(scene);
+ }
+ // Avoid drawing the scene with the active camera twice when it's viewport is enabled
+ if(cam && !cam->GetViewport())
+ {
+ if (scene->IsClearingZBuffer())
+ m_rasterizer->ClearDepthBuffer();
+
+ m_rendertools->SetAuxilaryClientInfo(scene);
+
+ // do the rendering
+ m_dome->RenderDomeFrame(scene,cam, i);
+ }
+
+ list<class KX_Camera*>* cameras = scene->GetCameras();
+
+ // Draw the scene once for each camera with an enabled viewport
+ list<KX_Camera*>::iterator it = cameras->begin();
+ while(it != cameras->end())
+ {
+ if((*it)->GetViewport())
+ {
+ if (scene->IsClearingZBuffer())
+ m_rasterizer->ClearDepthBuffer();
+
+ m_rendertools->SetAuxilaryClientInfo(scene);
+
+ // do the rendering
+ m_dome->RenderDomeFrame(scene, (*it),i);
+ }
+
+ it++;
+ }
+ }
+ 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());
+
+ if (m_overrideFrameColor) //XXX why do we want
+ {
+ // Do not use the framing bar color set in the Blender scenes
+ m_canvas->ClearColor(
+ m_overrideFrameColorR,
+ m_overrideFrameColorG,
+ m_overrideFrameColorB,
+ 1.0
+ );
+ }
+ else
+ {
+ // Use the framing bar color set in the Blender scenes
+ m_canvas->ClearColor(
+ framesettings.BarRed(),
+ framesettings.BarGreen(),
+ framesettings.BarBlue(),
+ 1.0
+ );
+ }
+
+ m_dome->Draw();
+
+ //run 2dfilters
+ EndFrame();
+}
/**
* Ketsji Init(), Initializes datastructures and converts data from
@@ -412,7 +539,7 @@ else
// Compute the number of logic frames to do each update (fixed tic bricks)
- int frames =int(deltatime*m_ticrate);
+ int frames =int(deltatime*m_ticrate+1e-6);
// if (frames>1)
// printf("****************************************");
// printf("dt = %f, deltatime = %f, frames = %d\n",dt, deltatime,frames);
@@ -465,12 +592,15 @@ else
m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_NETWORK);
scene->GetNetworkScene()->proceed(m_frameTime);
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- scene->UpdateParents(m_frameTime);
+ //m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ //SG_SetActiveStage(SG_STAGE_NETWORK_UPDATE);
+ //scene->UpdateParents(m_frameTime);
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS1);
// set Python hooks for each scene
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
KX_SetActiveScene(scene);
@@ -479,31 +609,37 @@ else
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- scene->UpdateParents(m_frameTime);
+ //m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ //SG_SetActiveStage(SG_STAGE_PHYSICS1_UPDATE);
+ //scene->UpdateParents(m_frameTime);
// Process sensors, and controllers
m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_CONTROLLER);
scene->LogicBeginFrame(m_frameTime);
// Scenegraph needs to be updated again, because Logic Controllers
// can affect the local matrices.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_CONTROLLER_UPDATE);
scene->UpdateParents(m_frameTime);
// Process actuators
// Do some cleanup work for this logic frame
m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ACTUATOR);
scene->LogicUpdateFrame(m_frameTime, true);
scene->LogicEndFrame();
// Actuators can affect the scenegraph
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
scene->UpdateParents(m_frameTime);
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS2);
scene->GetPhysicsEnvironment()->beginFrame();
// Perform physics calculations on the scene. This can involve
@@ -511,6 +647,7 @@ else
scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,1.0/m_ticrate);//m_deltatimerealDeltaTime);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS2_UPDATE);
scene->UpdateParents(m_frameTime);
@@ -574,6 +711,7 @@ else
KX_SetActiveScene(scene);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS1);
scene->UpdateParents(m_clockTime);
// Perform physics calculations on the scene. This can involve
@@ -583,6 +721,7 @@ else
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS2);
scene->UpdateParents(m_clockTime);
// Do some cleanup work for this logic frame
@@ -591,6 +730,7 @@ else
// Actuators can affect the scenegraph
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ACTUATOR);
scene->UpdateParents(m_clockTime);
scene->setSuspendedTime(0.0);
@@ -618,10 +758,15 @@ else
void KX_KetsjiEngine::Render()
{
+ if(m_usedome){
+ RenderDome();
+ return;
+ }
KX_Scene* firstscene = *m_scenes.begin();
const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_RENDER);
// hiding mouse cursor each frame
// (came back when going out of focus and then back in again)
@@ -672,6 +817,9 @@ void KX_KetsjiEngine::Render()
// pass the scene's worldsettings to the rasterizer
SetWorldSettings(scene->GetWorldInfo());
+ // do this only once per scene
+ scene->UpdateMeshTransformations();
+
// shadow buffers
RenderShadowBuffers(scene);
@@ -758,6 +906,9 @@ void KX_KetsjiEngine::Render()
}
} // if(m_rasterizer->Stereo())
+ // run the 2dfilters and motion blur once for all the scenes
+ PostRenderFrame();
+
EndFrame();
}
@@ -997,7 +1148,6 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
light->BindShadowBuffer(m_rasterizer, cam, camtrans);
/* update scene */
- scene->UpdateMeshTransformations();
scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
/* render */
@@ -1102,30 +1252,34 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
cam->GetCameraLocation(), cam->GetCameraOrientation());
cam->SetModelviewMatrix(viewmat);
- scene->UpdateMeshTransformations();
+ //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
// runs through the individual objects.
+
+ m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_CULLING);
+
scene->CalculateVisibleMeshes(m_rasterizer,cam);
+ m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_RENDER);
+
scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
if (scene->GetPhysicsEnvironment())
scene->GetPhysicsEnvironment()->debugDrawWorld();
m_rasterizer->FlushDebugLines();
-
- PostRenderFrame();
}
void KX_KetsjiEngine::PostRenderFrame()
{
- m_rendertools->PushMatrix();
m_rendertools->Render2DFilters(m_canvas);
m_rendertools->MotionBlur(m_rasterizer);
- m_rendertools->PopMatrix();
}
void KX_KetsjiEngine::StopEngine()
@@ -1166,15 +1320,17 @@ void KX_KetsjiEngine::AddScene(KX_Scene* scene)
void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
{
bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName));
-
- // if there is no activecamera, or the camera is being
- // overridden we need to construct a temporarily camera
+
+ SG_SetActiveStage(SG_STAGE_SCENE);
+
+ // if there is no activecamera, or the camera is being
+ // overridden we need to construct a temporarily camera
if (!scene->GetActiveCamera() || override_camera)
{
KX_Camera* activecam = NULL;
RAS_CameraData camdata = RAS_CameraData();
- activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata, false);
+ activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata);
activecam->SetName("__default__cam__");
// set transformation
@@ -1186,11 +1342,11 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
activecam->NodeSetLocalPosition(camtrans.getOrigin());
activecam->NodeSetLocalOrientation(camtrans.getBasis());
- activecam->NodeUpdateGS(0,true);
+ activecam->NodeUpdateGS(0);
} else {
activecam->NodeSetLocalPosition(MT_Point3(0.0, 0.0, 0.0));
activecam->NodeSetLocalOrientation(MT_Vector3(0.0, 0.0, 0.0));
- activecam->NodeUpdateGS(0,true);
+ activecam->NodeUpdateGS(0);
}
scene->AddCamera(activecam);
@@ -1675,4 +1831,3 @@ void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const
}
-
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 8516049f6d8..a8ccd6100d7 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -74,6 +74,7 @@ private:
PyObject* m_pythondictionary;
class SCA_IInputDevice* m_keyboarddevice;
class SCA_IInputDevice* m_mousedevice;
+ class KX_Dome* m_dome; // dome stereo mode
/** Lists of scenes scheduled to be removed at the end of the frame. */
std::set<STR_String> m_removingScenes;
@@ -208,6 +209,12 @@ public:
RAS_ICanvas* GetCanvas(){return m_canvas;};
RAS_IRenderTools* GetRenderTools(){return m_rendertools;};
+ /// Dome functions
+ void InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text);
+ void EndDome();
+ void RenderDome();
+ bool m_usedome;
+
///returns true if an update happened to indicate -> Render
bool NextFrame();
void Render();
@@ -234,6 +241,8 @@ public:
void GetSceneViewport(KX_Scene* scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport);
void SetDrawType(int drawingtype);
+ int GetDrawType(){return m_drawingmode;};
+
void SetCameraZoom(float camzoom);
void EnableCameraOverride(const STR_String& forscene);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index a2e93ecdd36..713838c88ec 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -57,6 +57,7 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
{
m_lightobj = lightobj;
m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr();
+ m_lightobj.m_scene = sgReplicationInfo;
m_rendertools->AddLight(&m_lightobj);
m_glsl = glsl;
m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene();
@@ -158,7 +159,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T
cam->NodeSetLocalPosition(camtrans.getOrigin());
cam->NodeSetLocalOrientation(camtrans.getBasis());
- cam->NodeUpdateGS(0,true);
+ cam->NodeUpdateGS(0);
/* setup rasterizer transformations */
ras->SetProjectionMatrix(projectionmat);
@@ -172,109 +173,114 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
GPU_lamp_shadow_buffer_unbind(lamp);
}
-PyObject* KX_LightObject::_getattr(const char *attr)
+PyObject* KX_LightObject::py_getattro(PyObject *attr)
{
- if (!strcmp(attr, "layer"))
+ char *attr_str= PyString_AsString(attr);
+
+ if (!strcmp(attr_str, "layer"))
return PyInt_FromLong(m_lightobj.m_layer);
- if (!strcmp(attr, "energy"))
+ if (!strcmp(attr_str, "energy"))
return PyFloat_FromDouble(m_lightobj.m_energy);
- if (!strcmp(attr, "distance"))
+ if (!strcmp(attr_str, "distance"))
return PyFloat_FromDouble(m_lightobj.m_distance);
- if (!strcmp(attr, "colour") || !strcmp(attr, "color"))
+ 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, "lin_attenuation"))
+ if (!strcmp(attr_str, "lin_attenuation"))
return PyFloat_FromDouble(m_lightobj.m_att1);
- if (!strcmp(attr, "quad_attenuation"))
+ if (!strcmp(attr_str, "quad_attenuation"))
return PyFloat_FromDouble(m_lightobj.m_att2);
- if (!strcmp(attr, "spotsize"))
+ if (!strcmp(attr_str, "spotsize"))
return PyFloat_FromDouble(m_lightobj.m_spotsize);
- if (!strcmp(attr, "spotblend"))
+ if (!strcmp(attr_str, "spotblend"))
return PyFloat_FromDouble(m_lightobj.m_spotblend);
- if (!strcmp(attr, "SPOT"))
+ if (!strcmp(attr_str, "SPOT"))
return PyInt_FromLong(RAS_LightObject::LIGHT_SPOT);
- if (!strcmp(attr, "SUN"))
+ if (!strcmp(attr_str, "SUN"))
return PyInt_FromLong(RAS_LightObject::LIGHT_SUN);
- if (!strcmp(attr, "NORMAL"))
+ if (!strcmp(attr_str, "NORMAL"))
return PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL);
- if (!strcmp(attr, "type"))
+ if (!strcmp(attr_str, "type"))
return PyInt_FromLong(m_lightobj.m_type);
- _getattr_up(KX_GameObject);
+ py_getattro_up(KX_GameObject);
}
-int KX_LightObject::_setattr(const char *attr, PyObject *pyvalue)
-{
+
+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, "layer"))
+ if (!strcmp(attr_str, "layer"))
{
m_lightobj.m_layer = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "type"))
+ 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 0;
+ return PY_SET_ATTR_SUCCESS;
}
}
- if (PyFloat_Check(pyvalue))
+ if (PyFloat_Check(pyvalue) || PyInt_Check(pyvalue))
{
float value = PyFloat_AsDouble(pyvalue);
- if (!strcmp(attr, "energy"))
+ if (!strcmp(attr_str, "energy"))
{
m_lightobj.m_energy = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "distance"))
+ if (!strcmp(attr_str, "distance"))
{
m_lightobj.m_distance = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "lin_attenuation"))
+ if (!strcmp(attr_str, "lin_attenuation"))
{
m_lightobj.m_att1 = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "quad_attenuation"))
+ if (!strcmp(attr_str, "quad_attenuation"))
{
m_lightobj.m_att2 = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "spotsize"))
+ if (!strcmp(attr_str, "spotsize"))
{
m_lightobj.m_spotsize = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "spotblend"))
+ if (!strcmp(attr_str, "spotblend"))
{
m_lightobj.m_spotblend = value;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
}
if (PySequence_Check(pyvalue))
{
- if (!strcmp(attr, "colour") || !strcmp(attr, "color"))
+ if (!strcmp(attr_str, "colour") || !strcmp(attr_str, "color"))
{
MT_Vector3 color;
if (PyVecTo(pyvalue, color))
@@ -282,19 +288,19 @@ int KX_LightObject::_setattr(const char *attr, PyObject *pyvalue)
m_lightobj.m_red = color[0];
m_lightobj.m_green = color[1];
m_lightobj.m_blue = color[2];
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- return 1;
+ return PY_SET_ATTR_FAIL;
}
}
- if (!strcmp(attr, "SPOT") || !strcmp(attr, "SUN") || !strcmp(attr, "NORMAL"))
+ if (!strcmp(attr_str, "SPOT") || !strcmp(attr_str, "SUN") || !strcmp(attr_str, "NORMAL"))
{
- PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr);
- return 1;
+ PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr_str);
+ return PY_SET_ATTR_FAIL;
}
- return KX_GameObject::_setattr(attr, pyvalue);
+ return KX_GameObject::py_setattro(attr, pyvalue);
}
PyMethodDef KX_LightObject::Methods[] = {
@@ -302,51 +308,41 @@ PyMethodDef KX_LightObject::Methods[] = {
};
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
};
-char KX_LightObject::doc[] = "Module KX_LightObject\n\n"
-"Constants:\n"
-"\tSPOT\n"
-"\tSUN\n"
-"\tNORMAL\n"
-"Attributes:\n"
-"\ttype -> SPOT, SUN or NORMAL\n"
-"\t\tThe type of light.\n"
-"\tlayer -> integer bit field.\n"
-"\t\tThe layers this light applies to.\n"
-"\tenergy -> float.\n"
-"\t\tThe brightness of the light.\n"
-"\tdistance -> float.\n"
-"\t\tThe effect radius of the light.\n"
-"\tcolour -> list [r, g, b].\n"
-"\tcolor -> list [r, g, b].\n"
-"\t\tThe color of the light.\n"
-"\tlin_attenuation -> float.\n"
-"\t\tThe attenuation factor for the light.\n"
-"\tspotsize -> float.\n"
-"\t\tThe size of the spot.\n"
-"\tspotblend -> float.\n"
-"\t\tThe blend? of the spot.\n";
-
PyTypeObject KX_LightObject::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_LightObject",
- sizeof(KX_LightObject),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
0,
0,
0,
- 0, 0, 0, 0, 0, 0,
- doc
+ py_base_repr,
+ 0,0,
+ &KX_GameObject::Mapping,
+ 0,0,0,
+ py_base_getattro,
+ py_base_setattro,
+ 0,0,0,0,0,0,0,0,0,
+ Methods
};
PyParentObject KX_LightObject::Parents[] = {
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 47edd09b5b9..4559954c8d7 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -47,7 +47,6 @@ protected:
class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj
bool m_glsl;
Scene* m_blenderscene;
- static char doc[];
public:
KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl, PyTypeObject *T = &Type);
@@ -63,8 +62,8 @@ public:
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
void Update();
- virtual PyObject* _getattr(const char *attr); /* lens, near, far, projection_matrix */
- virtual int _setattr(const char *attr, PyObject *pyvalue);
+ virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */
+ virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
virtual bool IsLight(void) { return true; }
};
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index a0c0a496c06..6be1da55ff8 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -46,22 +46,22 @@
#include "PyObjectPlus.h"
PyTypeObject KX_MeshProxy::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_MeshProxy",
- sizeof(KX_MeshProxy),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_MeshProxy::Parents[] = {
@@ -73,8 +73,11 @@ PyParentObject KX_MeshProxy::Parents[] = {
};
PyMethodDef KX_MeshProxy::Methods[] = {
+// Deprecated ----->
{"getNumMaterials", (PyCFunction)KX_MeshProxy::sPyGetNumMaterials,METH_VARARGS},
{"getNumPolygons", (PyCFunction)KX_MeshProxy::sPyGetNumPolygons,METH_NOARGS},
+// <-----
+
{"getMaterialName", (PyCFunction)KX_MeshProxy::sPyGetMaterialName,METH_VARARGS},
{"getTextureName", (PyCFunction)KX_MeshProxy::sPyGetTextureName,METH_VARARGS},
{"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS},
@@ -87,6 +90,10 @@ KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh),
};
PyAttributeDef KX_MeshProxy::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("materials", KX_MeshProxy, pyattr_get_materials),
+ KX_PYATTRIBUTE_RO_FUNCTION("numPolygons", KX_MeshProxy, pyattr_get_numPolygons),
+ KX_PYATTRIBUTE_RO_FUNCTION("numMaterials", KX_MeshProxy, pyattr_get_numMaterials),
+
{ NULL } //Sentinel
};
@@ -96,35 +103,19 @@ void KX_MeshProxy::SetMeshModified(bool v)
}
-PyObject*
-KX_MeshProxy::_getattr(const char *attr)
+PyObject* KX_MeshProxy::py_getattro(PyObject *attr)
{
- if (!strcmp(attr, "materials"))
- {
- PyObject *materials = PyList_New(0);
- list<RAS_MeshMaterial>::iterator mit = m_meshobj->GetFirstMaterial();
- for(; mit != m_meshobj->GetLastMaterial(); ++mit)
- {
- RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial();
-
- if(polymat->GetFlag() & RAS_BLENDERMAT)
- {
- KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat);
- PyList_Append(materials, mat);
- }else
- {
- PyList_Append(materials, static_cast<KX_PolygonMaterial*>(polymat));
- }
- }
- return materials;
- }
- _getattr_up(SCA_IObject);
+ py_getattro_up(SCA_IObject);
}
+int KX_MeshProxy::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IObject);
+}
KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh)
- : m_meshobj(mesh)
+ : SCA_IObject(&Type), m_meshobj(mesh)
{
}
@@ -139,7 +130,7 @@ CValue* KX_MeshProxy::Calc(VALUE_OPERATOR op, CValue *val) { return NULL;}
CValue* KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) { return NULL;}
const STR_String & KX_MeshProxy::GetText() {return m_meshobj->GetName();};
-float KX_MeshProxy::GetNumber() { return -1;}
+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;}
@@ -148,28 +139,26 @@ void KX_MeshProxy::ReplicaSetName(STR_String name) {};
// stuff for python integration
-PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* args, PyObject* kwds)
{
int num = m_meshobj->NumMaterials();
+ ShowDeprecationWarning("getNumMaterials()", "the numMaterials property");
return PyInt_FromLong(num);
}
-PyObject* KX_MeshProxy::PyGetNumPolygons(PyObject* self)
+PyObject* KX_MeshProxy::PyGetNumPolygons()
{
int num = m_meshobj->NumPolygons();
+ ShowDeprecationWarning("getNumPolygons()", "the numPolygons property");
return PyInt_FromLong(num);
}
-PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* args, PyObject* kwds)
{
int matid= 1;
STR_String matname;
- if (PyArg_ParseTuple(args,"i",&matid))
+ if (PyArg_ParseTuple(args,"i:getMaterialName",&matid))
{
matname = m_meshobj->GetMaterialName(matid);
}
@@ -182,14 +171,12 @@ PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self,
}
-PyObject* KX_MeshProxy::PyGetTextureName(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MeshProxy::PyGetTextureName(PyObject* args, PyObject* kwds)
{
int matid= 1;
STR_String matname;
- if (PyArg_ParseTuple(args,"i",&matid))
+ if (PyArg_ParseTuple(args,"i:getTextureName",&matid))
{
matname = m_meshobj->GetTextureName(matid);
}
@@ -201,45 +188,41 @@ PyObject* KX_MeshProxy::PyGetTextureName(PyObject* self,
}
-PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* args, PyObject* kwds)
{
- int matid= -1;
- int length = -1;
+ int matid= 0;
+ int length = 0;
- if (PyArg_ParseTuple(args,"i",&matid))
+ if (!PyArg_ParseTuple(args,"i:getVertexArrayLength",&matid))
+ return NULL;
+
+
+ RAS_MeshMaterial *mmat = m_meshobj->GetMeshMaterial(matid); /* can be NULL*/
+
+ if (mmat)
{
- RAS_MeshMaterial *mmat = m_meshobj->GetMeshMaterial(matid);
RAS_IPolyMaterial* mat = mmat->m_bucket->GetPolyMaterial();
-
if (mat)
length = m_meshobj->NumVertices(mat);
}
- else {
- return NULL;
- }
-
+
return PyInt_FromLong(length);
-
}
-PyObject* KX_MeshProxy::PyGetVertex(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MeshProxy::PyGetVertex(PyObject* args, PyObject* kwds)
{
int vertexindex= 1;
int matindex= 1;
PyObject* vertexob = NULL;
- if (PyArg_ParseTuple(args,"ii",&matindex,&vertexindex))
+ if (PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex))
{
RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex);
if (vertex)
{
- vertexob = new KX_VertexProxy(this, vertex);
+ vertexob = (new KX_VertexProxy(this, vertex))->NewProxy(true);
}
}
else {
@@ -250,24 +233,28 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* self,
}
-PyObject* KX_MeshProxy::PyGetPolygon(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MeshProxy::PyGetPolygon(PyObject* args, PyObject* kwds)
{
int polyindex= 1;
PyObject* polyob = NULL;
- if (!PyArg_ParseTuple(args,"i",&polyindex))
+ if (!PyArg_ParseTuple(args,"i:getPolygon",&polyindex))
+ return NULL;
+
+ if (polyindex<0 || polyindex >= m_meshobj->NumPolygons())
+ {
+ PyErr_SetString(PyExc_AttributeError, "mesh.getPolygon(int): KX_MeshProxy, invalid polygon index");
return NULL;
+ }
+
RAS_Polygon* polygon = m_meshobj->GetPolygon(polyindex);
if (polygon)
{
- polyob = new KX_PolyProxy(m_meshobj, polygon);
+ polyob = (new KX_PolyProxy(m_meshobj, polygon))->NewProxy(true);
}
- else
- {
- PyErr_SetString(PyExc_AttributeError, "Invalid polygon index");
+ else {
+ PyErr_SetString(PyExc_AttributeError, "mesh.getPolygon(int): KX_MeshProxy, polygon is NULL, unknown reason");
}
return polyob;
}
@@ -278,3 +265,97 @@ KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh,
//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;
}
+
+PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MeshProxy* self= static_cast<KX_MeshProxy*>(self_v);
+
+ int tot= self->m_meshobj->NumMaterials();
+ int i;
+
+ PyObject *materials = PyList_New( tot );
+
+ list<RAS_MeshMaterial>::iterator mit= self->m_meshobj->GetFirstMaterial();
+
+
+ for(i=0; i<tot; mit++, i++) {
+ RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial();
+
+ /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
+ if(polymat->GetFlag() & RAS_BLENDERMAT)
+ {
+ KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat);
+ PyList_SET_ITEM(materials, i, mat->GetProxy());
+ }
+ else {
+ KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial*>(polymat);
+ PyList_SET_ITEM(materials, i, mat->GetProxy());
+ }
+ }
+ return materials;
+}
+
+PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) {
+ KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv);
+ return PyInt_FromLong(self->m_meshobj->NumMaterials());
+}
+
+PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) {
+ KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv);
+ 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;
+}
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h
index 34f60a54a3a..aeecefc09e6 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.h
+++ b/source/gameengine/Ketsji/KX_MeshProxy.h
@@ -31,6 +31,9 @@
#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
{
Py_Header;
@@ -46,24 +49,31 @@ public:
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val) ;
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
virtual const STR_String & GetText();
- virtual float GetNumber();
+ 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 void ReplicaSetName(STR_String name);
virtual CValue* GetReplica();
// stuff for python integration
- virtual PyObject* _getattr(const char *attr);
- KX_PYMETHOD(KX_MeshProxy,GetNumMaterials);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
+
+ KX_PYMETHOD(KX_MeshProxy,GetNumMaterials); // Deprecated
KX_PYMETHOD(KX_MeshProxy,GetMaterialName);
KX_PYMETHOD(KX_MeshProxy,GetTextureName);
- KX_PYMETHOD_NOARGS(KX_MeshProxy,GetNumPolygons);
+ KX_PYMETHOD_NOARGS(KX_MeshProxy,GetNumPolygons); // Deprecated
// both take materialid (int)
KX_PYMETHOD(KX_MeshProxy,GetVertexArrayLength);
KX_PYMETHOD(KX_MeshProxy,GetVertex);
KX_PYMETHOD(KX_MeshProxy,GetPolygon);
KX_PYMETHOD_DOC(KX_MeshProxy, reinstancePhysicsMesh);
+
+ static PyObject* pyattr_get_materials(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject * pyattr_get_numMaterials(void * self, const KX_PYATTRIBUTE_DEF * attrdef);
+ static PyObject * pyattr_get_numPolygons(void * self, const KX_PYATTRIBUTE_DEF * attrdef);
};
#endif //__KX_MESHPROXY
diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp
index 15f100af915..b4d58dccfdf 100644
--- a/source/gameengine/Ketsji/KX_MotionState.cpp
+++ b/source/gameengine/Ketsji/KX_MotionState.cpp
@@ -44,7 +44,7 @@ KX_MotionState::~KX_MotionState()
void KX_MotionState::getWorldPosition(float& posX,float& posY,float& posZ)
{
- MT_Point3 pos = m_node->GetWorldPosition();
+ const MT_Point3& pos = m_node->GetWorldPosition();
posX = pos[0];
posY = pos[1];
posZ = pos[2];
@@ -52,7 +52,7 @@ void KX_MotionState::getWorldPosition(float& posX,float& posY,float& posZ)
void KX_MotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
{
- MT_Vector3 scale = m_node->GetWorldScaling();
+ const MT_Vector3& scale = m_node->GetWorldScaling();
scaleX = scale[0];
scaleY = scale[1];
scaleZ = scale[2];
@@ -67,10 +67,16 @@ void KX_MotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float&
quatReal = orn[3];
}
+void KX_MotionState::getWorldOrientation(float* ori)
+{
+ const MT_Matrix3x3& mat = m_node->GetWorldOrientation();
+ mat.getValue(ori);
+}
+
void KX_MotionState::setWorldPosition(float posX,float posY,float posZ)
{
m_node->SetLocalPosition(MT_Point3(posX,posY,posZ));
- m_node->SetWorldPosition(MT_Point3(posX,posY,posZ));
+ //m_node->SetWorldPosition(MT_Point3(posX,posY,posZ));
}
void KX_MotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
@@ -82,13 +88,15 @@ void KX_MotionState::setWorldOrientation(float quatIma0,float quatIma1,float qua
orn[3] = quatReal;
m_node->SetLocalOrientation(orn);
- m_node->SetWorldOrientation(orn);
+ //m_node->SetWorldOrientation(orn);
}
void KX_MotionState::calculateWorldTransformations()
{
- m_node->ComputeWorldTransforms(NULL);
+ //Not needed, will be done in KX_Scene::UpdateParents() after the physics simulation
+ //bool parentUpdated = false;
+ //m_node->ComputeWorldTransforms(NULL, parentUpdated);
}
diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h
index c83af664817..7ba3ca2f85c 100644
--- a/source/gameengine/Ketsji/KX_MotionState.h
+++ b/source/gameengine/Ketsji/KX_MotionState.h
@@ -44,6 +44,7 @@ public:
virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal);
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 calculateWorldTransformations();
};
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 384034485e7..87b5c81392d 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -61,14 +61,12 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
int starty,
short int mousemode,
int focusmode,
- RAS_ICanvas* canvas,
KX_Scene* kxscene,
KX_KetsjiEngine *kxengine,
SCA_IObject* gameobj,
PyTypeObject* T)
: SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T),
m_focusmode(focusmode),
- m_gp_canvas(canvas),
m_kxscene(kxscene),
m_kxengine(kxengine)
{
@@ -81,6 +79,11 @@ void KX_MouseFocusSensor::Init()
m_positive_event = false;
m_hitObject = 0;
m_reset = true;
+
+ m_hitPosition.setValue(0,0,0);
+ m_prevTargetPoint.setValue(0,0,0);
+ m_prevSourcePoint.setValue(0,0,0);
+ m_hitNormal.setValue(0,0,1);
}
bool KX_MouseFocusSensor::Evaluate(CValue* event)
@@ -150,12 +153,8 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, KX_RayCast* r
-bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
+bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
{
- m_hitObject = 0;
- m_hitPosition = MT_Vector3(0,0,0);
- m_hitNormal = MT_Vector3(1,0,0);
-
/* All screen handling in the gameengine is done by GL,
* specifically the model/view and projection parts. The viewport
* part is in the creator.
@@ -187,6 +186,7 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
* = 1.0 - 2(y_blender - y_lb)/height
*
* */
+
/* Because we don't want to worry about resize events, camera
* changes and all that crap, we just determine this over and
@@ -195,15 +195,18 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
* canvas, the test is irrelevant. The 1.0 makes sure the
* calculations don't bomb. Maybe we should explicitly guard for
* division by 0.0...*/
-
- KX_Camera* cam = m_kxscene->GetActiveCamera();
-
- /* get the scenes current viewport. we recompute it because there
- * may be multiple cameras and m_kxscene->GetSceneViewport() only
- * has the one that was last drawn */
-
+
RAS_Rect area, viewport;
m_kxengine->GetSceneViewport(m_kxscene, cam, area, viewport);
+
+ /* Check if the mouse is in the viewport */
+ if (( m_x < viewport.m_x2 && // less then right
+ m_x > viewport.m_x1 && // more then then left
+ m_y < viewport.m_y2 && // below top
+ m_y > viewport.m_y1) == 0) // above bottom
+ {
+ return false;
+ }
float height = float(viewport.m_y2 - viewport.m_y1 + 1);
float width = float(viewport.m_x2 - viewport.m_x1 + 1);
@@ -211,14 +214,13 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
float x_lb = float(viewport.m_x1);
float y_lb = float(viewport.m_y1);
+ MT_Vector4 frompoint;
+ MT_Vector4 topoint;
+
/* There's some strangeness I don't fully get here... These values
- * _should_ be wrong! */
+ * _should_ be wrong! - see from point Z values */
+
-
- /* old: */
- float nearclip = 0.0;
- float farclip = 1.0;
-
/* build the from and to point in normalized device coordinates
* Looks like normailized device coordinates are [-1,1] in x [-1,1] in y
* [0,-1] in z
@@ -226,18 +228,15 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
* The actual z coordinates used don't have to be exact just infront and
* behind of the near and far clip planes.
*/
- MT_Vector4 frompoint = MT_Vector4(
- (2 * (m_x-x_lb) / width) - 1.0,
- 1.0 - (2 * (m_y - y_lb) / height),
- nearclip,
- 1.0
- );
- MT_Vector4 topoint = MT_Vector4(
- (2 * (m_x-x_lb) / width) - 1.0,
- 1.0 - (2 * (m_y-y_lb) / height),
- farclip,
- 1.0
- );
+ frompoint.setValue( (2 * (m_x-x_lb) / width) - 1.0,
+ 1.0 - (2 * (m_y - y_lb) / height),
+ 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 */
+ 1.0 );
/* camera to world */
MT_Transform wcs_camcs_tranform = cam->GetWorldToCamera();
@@ -260,31 +259,74 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
topoint = camcs_wcs_matrix * topoint;
/* from hom wcs to 3d wcs: */
- MT_Point3 frompoint3 = MT_Point3(frompoint[0]/frompoint[3],
- frompoint[1]/frompoint[3],
- frompoint[2]/frompoint[3]);
- MT_Point3 topoint3 = MT_Point3(topoint[0]/topoint[3],
- topoint[1]/topoint[3],
- topoint[2]/topoint[3]);
- m_prevTargetPoint = topoint3;
- m_prevSourcePoint = frompoint3;
+ m_prevSourcePoint.setValue( frompoint[0]/frompoint[3],
+ frompoint[1]/frompoint[3],
+ frompoint[2]/frompoint[3]);
+
+ m_prevTargetPoint.setValue( topoint[0]/topoint[3],
+ topoint[1]/topoint[3],
+ topoint[2]/topoint[3]);
/* 2. Get the object from PhysicsEnvironment */
/* Shoot! Beware that the first argument here is an
* ignore-object. We don't ignore anything... */
-
KX_IPhysicsController* physics_controller = cam->GetPhysicsController();
PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment();
- bool result = false;
-
KX_RayCast::Callback<KX_MouseFocusSensor> callback(this,physics_controller);
- KX_RayCast::RayTest(physics_environment, frompoint3, topoint3, callback);
+
+ KX_RayCast::RayTest(physics_environment, m_prevSourcePoint, m_prevTargetPoint, callback);
+
+ if (m_hitObject)
+ return true;
- result = (m_hitObject!=0);
+ return false;
+}
- return result;
+bool KX_MouseFocusSensor::ParentObjectHasFocus()
+{
+ m_hitObject = 0;
+ m_hitPosition.setValue(0,0,0);
+ m_hitNormal.setValue(1,0,0);
+
+ KX_Camera *cam= m_kxscene->GetActiveCamera();
+
+ if(ParentObjectHasFocusCamera(cam))
+ return true;
+
+ list<class KX_Camera*>* cameras = m_kxscene->GetCameras();
+ list<KX_Camera*>::iterator it = cameras->begin();
+
+ while(it != cameras->end())
+ {
+ if(((*it) != cam) && (*it)->GetViewport())
+ if (ParentObjectHasFocusCamera(*it))
+ return true;
+
+ it++;
+ }
+
+ return false;
+}
+
+const MT_Point3& KX_MouseFocusSensor::RaySource() const
+{
+ return m_prevSourcePoint;
+}
+
+const MT_Point3& KX_MouseFocusSensor::RayTarget() const
+{
+ return m_prevTargetPoint;
+}
+
+const MT_Point3& KX_MouseFocusSensor::HitPosition() const
+{
+ return m_hitPosition;
+}
+const MT_Vector3& KX_MouseFocusSensor::HitNormal() const
+{
+ return m_hitNormal;
}
/* ------------------------------------------------------------------------- */
@@ -293,22 +335,22 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_MouseFocusSensor::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_MouseFocusSensor",
- sizeof(KX_MouseFocusSensor),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_MouseFocusSensor::Parents[] = {
@@ -328,26 +370,33 @@ PyMethodDef KX_MouseFocusSensor::Methods[] = {
{"getHitNormal",(PyCFunction) KX_MouseFocusSensor::sPyGetHitNormal,METH_NOARGS, (PY_METHODCHAR)GetHitNormal_doc},
{"getRayDirection",(PyCFunction) KX_MouseFocusSensor::sPyGetRayDirection,METH_NOARGS, (PY_METHODCHAR)GetRayDirection_doc},
-
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_MouseFocusSensor::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("raySource", KX_MouseFocusSensor, pyattr_get_ray_source),
+ KX_PYATTRIBUTE_RO_FUNCTION("rayTarget", KX_MouseFocusSensor, pyattr_get_ray_target),
+ KX_PYATTRIBUTE_RO_FUNCTION("rayDirection", KX_MouseFocusSensor, pyattr_get_ray_direction),
+ KX_PYATTRIBUTE_RO_FUNCTION("hitObject", KX_MouseFocusSensor, pyattr_get_hit_object),
+ KX_PYATTRIBUTE_RO_FUNCTION("hitPosition", KX_MouseFocusSensor, pyattr_get_hit_position),
+ KX_PYATTRIBUTE_RO_FUNCTION("hitNormal", KX_MouseFocusSensor, pyattr_get_hit_normal),
{ NULL } //Sentinel
};
-PyObject* KX_MouseFocusSensor::_getattr(const char *attr) {
- _getattr_up(SCA_MouseSensor);
+PyObject* KX_MouseFocusSensor::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_MouseSensor);
}
const char KX_MouseFocusSensor::GetHitObject_doc[] =
"getHitObject()\n"
-"\tReturns the name of the object that was hit by this ray.\n";
-PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self)
+"\tReturns the object that was hit by this ray.\n";
+PyObject* KX_MouseFocusSensor::PyGetHitObject()
{
+ ShowDeprecationWarning("GetHitObject()", "the hitObject property");
+
if (m_hitObject)
- return m_hitObject->AddRef();
+ return m_hitObject->GetProxy();
Py_RETURN_NONE;
}
@@ -356,27 +405,33 @@ PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self)
const char KX_MouseFocusSensor::GetHitPosition_doc[] =
"getHitPosition()\n"
"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
-PyObject* KX_MouseFocusSensor::PyGetHitPosition(PyObject* self)
+PyObject* KX_MouseFocusSensor::PyGetHitPosition()
{
+ ShowDeprecationWarning("getHitPosition()", "the hitPosition property");
+
return PyObjectFrom(m_hitPosition);
}
const char KX_MouseFocusSensor::GetRayDirection_doc[] =
"getRayDirection()\n"
"\tReturns the direction from the ray (in worldcoordinates) .\n";
-PyObject* KX_MouseFocusSensor::PyGetRayDirection(PyObject* self)
+PyObject* KX_MouseFocusSensor::PyGetRayDirection()
{
-
+ ShowDeprecationWarning("getRayDirection()", "the rayDirection property");
+
MT_Vector3 dir = m_prevTargetPoint - m_prevSourcePoint;
- dir.normalize();
+ if(MT_fuzzyZero(dir)) dir.setValue(0,0,0);
+ else dir.normalize();
return PyObjectFrom(dir);
}
const char KX_MouseFocusSensor::GetHitNormal_doc[] =
"getHitNormal()\n"
-"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
-PyObject* KX_MouseFocusSensor::PyGetHitNormal(PyObject* self)
+"\tReturns the normal (in worldcoordinates) at the point of collision where the object was hit by this ray.\n";
+PyObject* KX_MouseFocusSensor::PyGetHitNormal()
{
+ ShowDeprecationWarning("getHitNormal()", "the hitNormal property");
+
return PyObjectFrom(m_hitNormal);
}
@@ -386,7 +441,10 @@ const char KX_MouseFocusSensor::GetRayTarget_doc[] =
"getRayTarget()\n"
"\tReturns the target of the ray that seeks the focus object,\n"
"\tin worldcoordinates.";
-PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self) {
+PyObject* KX_MouseFocusSensor::PyGetRayTarget()
+{
+ ShowDeprecationWarning("getRayTarget()", "the rayTarget property");
+
return PyObjectFrom(m_prevTargetPoint);
}
@@ -395,9 +453,58 @@ const char KX_MouseFocusSensor::GetRaySource_doc[] =
"getRaySource()\n"
"\tReturns the source of the ray that seeks the focus object,\n"
"\tin worldcoordinates.";
-PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self) {
+PyObject* KX_MouseFocusSensor::PyGetRaySource()
+{
+ ShowDeprecationWarning("getRaySource()", "the raySource property");
+
return PyObjectFrom(m_prevSourcePoint);
}
+/* Attributes */
+PyObject* KX_MouseFocusSensor::pyattr_get_ray_source(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v);
+ return PyObjectFrom(self->RaySource());
+}
+
+PyObject* KX_MouseFocusSensor::pyattr_get_ray_target(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v);
+ return PyObjectFrom(self->RayTarget());
+}
+
+PyObject* KX_MouseFocusSensor::pyattr_get_ray_direction(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v);
+ MT_Vector3 dir = self->RayTarget() - self->RaySource();
+ if(MT_fuzzyZero(dir)) dir.setValue(0,0,0);
+ else dir.normalize();
+ return PyObjectFrom(dir);
+}
+
+PyObject* KX_MouseFocusSensor::pyattr_get_hit_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v);
+
+ if(self->m_hitObject)
+ return self->m_hitObject->GetProxy();
+
+ Py_RETURN_NONE;
+}
+
+PyObject* KX_MouseFocusSensor::pyattr_get_hit_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v);
+ return PyObjectFrom(self->HitPosition());
+}
+
+PyObject* KX_MouseFocusSensor::pyattr_get_hit_normal(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v);
+ return PyObjectFrom(self->HitNormal());
+}
+
+
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 4979783032c..8de1f88c5c3 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -54,7 +54,6 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
int starty,
short int mousemode,
int focusmode,
- RAS_ICanvas* canvas,
KX_Scene* kxscene,
KX_KetsjiEngine* kxengine,
SCA_IObject* gameobj,
@@ -82,12 +81,15 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
bool NeedRayCast(KX_ClientObjectInfo* client) { return true; }
-
+ const MT_Point3& RaySource() const;
+ const MT_Point3& RayTarget() const;
+ const MT_Point3& HitPosition() const;
+ const MT_Vector3& HitNormal() const;
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayTarget);
KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRaySource);
@@ -97,6 +99,14 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitNormal);
KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayDirection);
+ /* attributes */
+ static PyObject* pyattr_get_ray_source(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_ray_target(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_ray_direction(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hit_object(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hit_position(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hit_normal(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
/* --------------------------------------------------------------------- */
SCA_IObject* m_hitObject;
@@ -116,9 +126,13 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
*/
bool m_positive_event;
+ /**
+ * Tests whether the object is in mouse focus for this camera
+ */
+ bool ParentObjectHasFocusCamera(KX_Camera *cam);
/**
- * Tests whether the object is in mouse focus in this frame.
+ * Tests whether the object is in mouse focus in this scene.
*/
bool ParentObjectHasFocus(void);
@@ -142,12 +156,6 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
* the object was hit. */
MT_Vector3 m_hitNormal;
-
- /**
- * The active canvas. The size of this canvas determines a part of
- * the start position of the picking ray. */
- RAS_ICanvas* m_gp_canvas;
-
/**
* The KX scene that holds the camera. The camera position
* determines a part of the start location of the picking ray. */
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 993a6b3d86c..0489b7090e9 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -127,13 +127,10 @@ CValue* KX_NearSensor::GetReplica()
}
}
- //static_cast<KX_TouchEventManager*>(m_eventmgr)->RegisterSensor(this);
- //todo: make sure replication works fine
- //>m_sumoObj = new SM_Object(DT_NewSphere(0.0),NULL,NULL,NULL);
- //replica->m_sumoObj->setMargin(m_Margin);
- //replica->m_sumoObj->setClientObject(replica->m_client_info);
-
- ((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
+ //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;
@@ -154,8 +151,10 @@ void KX_NearSensor::ReParent(SCA_IObject* parent)
client_info->m_sensors.push_back(this);
SCA_ISensor::ReParent(parent);
*/
- ((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
- SynchronizeTransform();
+ //Not needed, was done in GetReplica() already
+ //bool parentUpdated = false;
+ //((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
+ //SynchronizeTransform();
SCA_ISensor::ReParent(parent);
}
@@ -287,22 +286,22 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData
/* ------------------------------------------------------------------------- */
PyTypeObject KX_NearSensor::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_NearSensor",
- sizeof(KX_NearSensor),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -330,20 +329,12 @@ PyAttributeDef KX_NearSensor::Attributes[] = {
};
-PyObject* KX_NearSensor::_getattr(const char *attr)
+PyObject* KX_NearSensor::py_getattro(PyObject *attr)
{
- PyObject* object = _getattr_self(Attributes, this, attr);
- if (object != NULL)
- return object;
-
- _getattr_up(KX_TouchSensor);
+ py_getattro_up(KX_TouchSensor);
}
-int KX_NearSensor::_setattr(const char *attr, PyObject* value)
+int KX_NearSensor::py_setattro(PyObject*attr, PyObject* value)
{
- int ret = _setattr_self(Attributes, this, attr, value);
- if (ret >= 0)
- return ret;
-
- return KX_TouchSensor::_setattr(attr, value);
+ py_setattro_up(KX_TouchSensor);
}
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
index ee03992e734..26c5feb4e67 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.h
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -82,8 +82,8 @@ public:
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject* value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
//No methods
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index 0666261b470..861c5757971 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -277,22 +277,22 @@ bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_ObjectActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_ObjectActuator",
- sizeof(KX_ObjectActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_ObjectActuator::Parents[] = {
@@ -336,15 +336,15 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* KX_ObjectActuator::_getattr(const char *attr) {
- _getattr_up(SCA_IActuator);
+PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_IActuator);
};
/* 1. set ------------------------------------------------------------------ */
/* Removed! */
/* 2. getForce */
-PyObject* KX_ObjectActuator::PyGetForce(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetForce()
{
PyObject *retVal = PyList_New(4);
@@ -356,13 +356,11 @@ PyObject* KX_ObjectActuator::PyGetForce(PyObject* self)
return retVal;
}
/* 3. setForce */
-PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetForce(PyObject* args)
{
float vecArg[3];
int bToggle = 0;
- if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ if (!PyArg_ParseTuple(args, "fffi:setForce", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
return NULL;
}
@@ -373,7 +371,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
}
/* 4. getTorque */
-PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetTorque()
{
PyObject *retVal = PyList_New(4);
@@ -385,13 +383,11 @@ PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self)
return retVal;
}
/* 5. setTorque */
-PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetTorque(PyObject* args)
{
float vecArg[3];
int bToggle = 0;
- if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ if (!PyArg_ParseTuple(args, "fffi:setTorque", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
return NULL;
}
@@ -402,7 +398,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
}
/* 6. getDLoc */
-PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetDLoc()
{
PyObject *retVal = PyList_New(4);
@@ -414,13 +410,11 @@ PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self)
return retVal;
}
/* 7. setDLoc */
-PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetDLoc(PyObject* args)
{
float vecArg[3];
int bToggle = 0;
- if(!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ if(!PyArg_ParseTuple(args, "fffi:setDLoc", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
return NULL;
}
@@ -431,7 +425,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
}
/* 8. getDRot */
-PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetDRot()
{
PyObject *retVal = PyList_New(4);
@@ -443,13 +437,11 @@ PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self)
return retVal;
}
/* 9. setDRot */
-PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetDRot(PyObject* args)
{
float vecArg[3];
int bToggle = 0;
- if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ if (!PyArg_ParseTuple(args, "fffi:setDRot", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
return NULL;
}
@@ -460,7 +452,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
}
/* 10. getLinearVelocity */
-PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self) {
+PyObject* KX_ObjectActuator::PyGetLinearVelocity() {
PyObject *retVal = PyList_New(4);
PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
@@ -472,12 +464,10 @@ PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self) {
}
/* 11. setLinearVelocity */
-PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) {
float vecArg[3];
int bToggle = 0;
- if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ if (!PyArg_ParseTuple(args, "fffi:setLinearVelocity", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
return NULL;
}
@@ -489,7 +479,7 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
/* 12. getAngularVelocity */
-PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self) {
+PyObject* KX_ObjectActuator::PyGetAngularVelocity() {
PyObject *retVal = PyList_New(4);
PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
@@ -500,12 +490,10 @@ PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self) {
return retVal;
}
/* 13. setAngularVelocity */
-PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* args) {
float vecArg[3];
int bToggle = 0;
- if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ if (!PyArg_ParseTuple(args, "fffi:setAngularVelocity", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
return NULL;
}
@@ -516,11 +504,9 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
}
/* 13. setDamping */
-PyObject* KX_ObjectActuator::PySetDamping(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ObjectActuator::PySetDamping(PyObject* args) {
int damping = 0;
- if (!PyArg_ParseTuple(args, "i", &damping) || damping < 0 || damping > 1000) {
+ if (!PyArg_ParseTuple(args, "i:setDamping", &damping) || damping < 0 || damping > 1000) {
return NULL;
}
m_damping = damping;
@@ -528,11 +514,11 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* self,
}
/* 13. getVelocityDamping */
-PyObject* KX_ObjectActuator::PyGetDamping(PyObject* self) {
+PyObject* KX_ObjectActuator::PyGetDamping() {
return Py_BuildValue("i",m_damping);
}
/* 6. getForceLimitX */
-PyObject* KX_ObjectActuator::PyGetForceLimitX(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetForceLimitX()
{
PyObject *retVal = PyList_New(3);
@@ -543,13 +529,11 @@ PyObject* KX_ObjectActuator::PyGetForceLimitX(PyObject* self)
return retVal;
}
/* 7. setForceLimitX */
-PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* args)
{
float vecArg[2];
int bToggle = 0;
- if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
+ if(!PyArg_ParseTuple(args, "ffi:setForceLimitX", &vecArg[0], &vecArg[1], &bToggle)) {
return NULL;
}
m_drot[0] = vecArg[0];
@@ -559,7 +543,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self,
}
/* 6. getForceLimitY */
-PyObject* KX_ObjectActuator::PyGetForceLimitY(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetForceLimitY()
{
PyObject *retVal = PyList_New(3);
@@ -570,13 +554,11 @@ PyObject* KX_ObjectActuator::PyGetForceLimitY(PyObject* self)
return retVal;
}
/* 7. setForceLimitY */
-PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* args)
{
float vecArg[2];
int bToggle = 0;
- if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
+ if(!PyArg_ParseTuple(args, "ffi:setForceLimitY", &vecArg[0], &vecArg[1], &bToggle)) {
return NULL;
}
m_drot[1] = vecArg[0];
@@ -586,7 +568,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self,
}
/* 6. getForceLimitZ */
-PyObject* KX_ObjectActuator::PyGetForceLimitZ(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetForceLimitZ()
{
PyObject *retVal = PyList_New(3);
@@ -597,13 +579,11 @@ PyObject* KX_ObjectActuator::PyGetForceLimitZ(PyObject* self)
return retVal;
}
/* 7. setForceLimitZ */
-PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* args)
{
float vecArg[2];
int bToggle = 0;
- if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
+ if(!PyArg_ParseTuple(args, "ffi:setForceLimitZ", &vecArg[0], &vecArg[1], &bToggle)) {
return NULL;
}
m_drot[2] = vecArg[0];
@@ -613,7 +593,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self,
}
/* 4. getPID */
-PyObject* KX_ObjectActuator::PyGetPID(PyObject* self)
+PyObject* KX_ObjectActuator::PyGetPID()
{
PyObject *retVal = PyList_New(3);
@@ -624,12 +604,10 @@ PyObject* KX_ObjectActuator::PyGetPID(PyObject* self)
return retVal;
}
/* 5. setPID */
-PyObject* KX_ObjectActuator::PySetPID(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_ObjectActuator::PySetPID(PyObject* args)
{
float vecArg[3];
- if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2])) {
+ if (!PyArg_ParseTuple(args, "fff:setPID", &vecArg[0], &vecArg[1], &vecArg[2])) {
return NULL;
}
m_torque.setValue(vecArg);
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index 0331c67617c..a812942a0ae 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -153,30 +153,30 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce);
- KX_PYMETHOD(KX_ObjectActuator,SetForce);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForce);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetTorque);
- KX_PYMETHOD(KX_ObjectActuator,SetTorque);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetTorque);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetDLoc);
- KX_PYMETHOD(KX_ObjectActuator,SetDLoc);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetDLoc);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetDRot);
- KX_PYMETHOD(KX_ObjectActuator,SetDRot);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetDRot);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetLinearVelocity);
- KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetLinearVelocity);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetAngularVelocity);
- KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity);
- KX_PYMETHOD(KX_ObjectActuator,SetDamping);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetAngularVelocity);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetDamping);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetDamping);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForceLimitX);
- KX_PYMETHOD(KX_ObjectActuator,SetForceLimitX);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForceLimitX);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForceLimitY);
- KX_PYMETHOD(KX_ObjectActuator,SetForceLimitY);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForceLimitY);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForceLimitZ);
- KX_PYMETHOD(KX_ObjectActuator,SetForceLimitZ);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForceLimitZ);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetPID);
- KX_PYMETHOD(KX_ObjectActuator,SetPID);
+ KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetPID);
};
#endif //__KX_OBJECTACTUATOR
diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h
index e3b5336c0b5..21b7e632d83 100644
--- a/source/gameengine/Ketsji/KX_OdePhysicsController.h
+++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h
@@ -82,6 +82,10 @@ public:
virtual SG_Controller* GetReplica(class SG_Node* destnode);
+ virtual float GetLinVelocityMin() { return ODEPhysicsController::GetLinVelocityMin(); }
+ virtual void SetLinVelocityMin(float val) { ODEPhysicsController::SetLinVelocityMin(val); }
+ virtual float GetLinVelocityMax() { return ODEPhysicsController::GetLinVelocityMax(); }
+ virtual void SetLinVelocityMax(float val) { ODEPhysicsController::SetLinVelocityMax(val); }
virtual void SetSumoTransform(bool nondynaonly);
// todo: remove next line !
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 84d7ccb9c05..0093cf5f313 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -1,7 +1,7 @@
/**
* Set or remove an objects parent
*
- * $Id: SCA_ParentActuator.cpp 13932 2008-03-01 19:05:41Z ben2610 $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -139,22 +139,22 @@ bool KX_ParentActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_ParentActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_ParentActuator",
- sizeof(KX_ParentActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_ParentActuator::Parents[] = {
@@ -166,59 +166,67 @@ PyParentObject KX_ParentActuator::Parents[] = {
};
PyMethodDef KX_ParentActuator::Methods[] = {
- // ---> deprecated (all)
- {"setObject", (PyCFunction) KX_ParentActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
- {"getObject", (PyCFunction) KX_ParentActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
+ // Deprecated ----->
+ {"setObject", (PyCFunction) KX_ParentActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
+ {"getObject", (PyCFunction) KX_ParentActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
+ // <-----
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_ParentActuator::Attributes[] = {
+ KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object),
{ NULL } //Sentinel
};
-PyObject* KX_ParentActuator::_getattr(const char *attr) {
-
- if (!strcmp(attr, "object")) {
- if (!m_ob) Py_RETURN_NONE;
- else return m_ob->AddRef();
- }
-
- _getattr_up(SCA_IActuator);
+PyObject* KX_ParentActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
+ if (!actuator->m_ob)
+ Py_RETURN_NONE;
+ else
+ return actuator->m_ob->GetProxy();
}
-int KX_ParentActuator::_setattr(const char *attr, PyObject* value) {
-
- if (!strcmp(attr, "object")) {
- KX_GameObject *gameobj;
+int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
+ KX_GameObject *gameobj;
- if (!ConvertPythonToGameObject(value, &gameobj, true))
- return 1; // ConvertPythonToGameObject sets the error
+ if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator"))
+ return 1; // ConvertPythonToGameObject sets the error
- if (m_ob != NULL)
- m_ob->UnregisterActuator(this);
+ if (actuator->m_ob != NULL)
+ actuator->m_ob->UnregisterActuator(actuator);
- m_ob = (SCA_IObject*)gameobj;
+ actuator->m_ob = (SCA_IObject*) gameobj;
- if (m_ob)
- m_ob->RegisterActuator(this);
+ if (actuator->m_ob)
+ actuator->m_ob->RegisterActuator(actuator);
- return 0;
- }
-
- return SCA_IActuator::_setattr(attr, value);
+ return 0;
+}
+
+
+PyObject* KX_ParentActuator::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_IActuator);
+}
+
+int KX_ParentActuator::py_setattro(PyObject *attr, PyObject* value) {
+ py_setattro_up(SCA_IActuator);
}
+/* Deprecated -----> */
/* 1. setObject */
const char KX_ParentActuator::SetObject_doc[] =
"setObject(object)\n"
"\t- object: KX_GameObject, string or None\n"
"\tSet the object to set as parent.\n";
-PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* value) {
+PyObject* KX_ParentActuator::PySetObject(PyObject* value) {
KX_GameObject *gameobj;
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
if (m_ob != NULL)
@@ -238,13 +246,13 @@ const char KX_ParentActuator::GetObject_doc[] =
"getObject(name_only = 1)\n"
"name_only - optional arg, when true will return the KX_GameObject rather then its name\n"
"\tReturns the object that is set to.\n";
-PyObject* KX_ParentActuator::PyGetObject(PyObject* self, PyObject* args)
+PyObject* KX_ParentActuator::PyGetObject(PyObject* args)
{
int ret_name_only = 1;
ShowDeprecationWarning("getObject()", "the object property");
- if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
+ if (!PyArg_ParseTuple(args, "|i:getObject", &ret_name_only))
return NULL;
if (!m_ob)
@@ -253,7 +261,8 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* self, PyObject* args)
if (ret_name_only)
return PyString_FromString(m_ob->GetName());
else
- return m_ob->AddRef();
+ return m_ob->GetProxy();
}
+/* <----- */
/* eof */
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h
index c974001c0d0..f9f0b73b876 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.h
+++ b/source/gameengine/Ketsji/KX_ParentActuator.h
@@ -2,7 +2,7 @@
* Set or remove an objects parent
*
*
- * $Id: KX_ParentActuator.h 3271 2004-10-16 11:41:50Z kester $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -76,13 +76,17 @@ class KX_ParentActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject* value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
- /* 1. setObject */
+ /* These are used to get and set m_ob */
+ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+ // Deprecated ----->
KX_PYMETHOD_DOC_O(KX_ParentActuator,SetObject);
- /* 2. getObject */
KX_PYMETHOD_DOC_VARARGS(KX_ParentActuator,GetObject);
+ // <-----
}; /* end of class KX_ParentActuator : public SCA_PropertyActuator */
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
index 246c63feb21..fda639c09e0 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
@@ -51,12 +51,10 @@ KX_PhysicsObjectWrapper::~KX_PhysicsObjectWrapper()
}
-PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* args)
{
float x,y,z;
- if (PyArg_ParseTuple(args,"fff",&x,&y,&z))
+ if (PyArg_ParseTuple(args,"fff:setPosition",&x,&y,&z))
{
m_ctrl->setPosition(x,y,z);
}
@@ -67,13 +65,11 @@ PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* self,
}
-PyObject* KX_PhysicsObjectWrapper::PySetLinearVelocity(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_PhysicsObjectWrapper::PySetLinearVelocity(PyObject* args)
{
float x,y,z;
int local;
- if (PyArg_ParseTuple(args,"fffi",&x,&y,&z,&local))
+ if (PyArg_ParseTuple(args,"fffi:setLinearVelocity",&x,&y,&z,&local))
{
m_ctrl->SetLinearVelocity(x,y,z,local != 0);
}
@@ -83,13 +79,11 @@ PyObject* KX_PhysicsObjectWrapper::PySetLinearVelocity(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_PhysicsObjectWrapper::PySetAngularVelocity(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_PhysicsObjectWrapper::PySetAngularVelocity(PyObject* args)
{
float x,y,z;
int local;
- if (PyArg_ParseTuple(args,"fffi",&x,&y,&z,&local))
+ if (PyArg_ParseTuple(args,"fffi:setAngularVelocity",&x,&y,&z,&local))
{
m_ctrl->SetAngularVelocity(x,y,z,local != 0);
}
@@ -99,12 +93,10 @@ PyObject* KX_PhysicsObjectWrapper::PySetAngularVelocity(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_PhysicsObjectWrapper::PySetActive(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_PhysicsObjectWrapper::PySetActive(PyObject* args)
{
int active;
- if (PyArg_ParseTuple(args,"i",&active))
+ if (PyArg_ParseTuple(args,"i:setActive",&active))
{
m_ctrl->SetActive(active!=0);
}
@@ -115,26 +107,28 @@ PyObject* KX_PhysicsObjectWrapper::PySetActive(PyObject* self,
}
-
+PyAttributeDef KX_PhysicsObjectWrapper::Attributes[] = {
+ { NULL } //Sentinel
+};
//python specific stuff
PyTypeObject KX_PhysicsObjectWrapper::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_PhysicsObjectWrapper",
- sizeof(KX_PhysicsObjectWrapper),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_PhysicsObjectWrapper::Parents[] = {
@@ -142,13 +136,13 @@ PyParentObject KX_PhysicsObjectWrapper::Parents[] = {
NULL
};
-PyObject* KX_PhysicsObjectWrapper::_getattr(const char *attr)
+PyObject* KX_PhysicsObjectWrapper::py_getattro(PyObject *attr)
{
- _getattr_up(PyObjectPlus);
+ py_getattro_up(PyObjectPlus);
}
-int KX_PhysicsObjectWrapper::_setattr(const char *attr,PyObject *pyobj)
+int KX_PhysicsObjectWrapper::py_setattro(PyObject *attr,PyObject *pyobj)
{
int result = 1;
@@ -161,7 +155,7 @@ int KX_PhysicsObjectWrapper::_setattr(const char *attr,PyObject *pyobj)
result = 0;
}
if (result)
- result = PyObjectPlus::_setattr(attr,pyobj);
+ result = PyObjectPlus::py_setattro(attr,pyobj);
return result;
};
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
index 95560698896..7e10dc3ccf4 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
@@ -36,16 +36,16 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus
{
Py_Header;
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
public:
KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
virtual ~KX_PhysicsObjectWrapper();
- KX_PYMETHOD(KX_PhysicsObjectWrapper , SetPosition);
- KX_PYMETHOD(KX_PhysicsObjectWrapper,SetLinearVelocity);
- KX_PYMETHOD(KX_PhysicsObjectWrapper,SetAngularVelocity);
- KX_PYMETHOD(KX_PhysicsObjectWrapper,SetActive);
+ KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetPosition);
+ KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetLinearVelocity);
+ KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetAngularVelocity);
+ KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetActive);
private:
class PHY_IPhysicsController* m_ctrl;
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp
index b4bdd77fb66..2e5dd72db0e 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.cpp
+++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp
@@ -39,22 +39,22 @@
#include "KX_PyMath.h"
PyTypeObject KX_PolyProxy::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_PolyProxy",
- sizeof(KX_PolyProxy),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_PolyProxy::Parents[] = {
@@ -78,42 +78,52 @@ PyMethodDef KX_PolyProxy::Methods[] = {
};
PyAttributeDef KX_PolyProxy::Attributes[] = {
+ /* All dummy's so they come up in a dir() */
+ KX_PYATTRIBUTE_DUMMY("matname"),
+ KX_PYATTRIBUTE_DUMMY("texture"),
+ KX_PYATTRIBUTE_DUMMY("material"),
+ KX_PYATTRIBUTE_DUMMY("matid"),
+ KX_PYATTRIBUTE_DUMMY("v1"),
+ KX_PYATTRIBUTE_DUMMY("v2"),
+ KX_PYATTRIBUTE_DUMMY("v3"),
+ KX_PYATTRIBUTE_DUMMY("v4"),
+ KX_PYATTRIBUTE_DUMMY("visible"),
+ KX_PYATTRIBUTE_DUMMY("collide"),
{ NULL } //Sentinel
};
-PyObject* KX_PolyProxy::_getattr(const char *attr)
+PyObject* KX_PolyProxy::py_getattro(PyObject *attr)
{
- if (!strcmp(attr, "matname"))
+ char *attr_str= PyString_AsString(attr);
+ if (!strcmp(attr_str, "matname"))
{
return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
}
- if (!strcmp(attr, "texture"))
+ if (!strcmp(attr_str, "texture"))
{
return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
}
- if (!strcmp(attr, "material"))
+ if (!strcmp(attr_str, "material"))
{
RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
if(polymat->GetFlag() & RAS_BLENDERMAT)
{
KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
- Py_INCREF(mat);
- return mat;
+ return mat->GetProxy();
}
else
{
KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
- Py_INCREF(mat);
- return mat;
+ return mat->GetProxy();
}
}
- if (!strcmp(attr, "matid"))
+ if (!strcmp(attr_str, "matid"))
{
// we'll have to scan through the material bucket of the mes and compare with
// the one of the polygon
RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
unsigned int matid;
- for (matid=0; matid<m_mesh->NumMaterials(); matid++)
+ for (matid=0; matid<(unsigned int)m_mesh->NumMaterials(); matid++)
{
RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
if (meshMat->m_bucket == polyBucket)
@@ -122,31 +132,31 @@ PyObject* KX_PolyProxy::_getattr(const char *attr)
}
return PyInt_FromLong(matid);
}
- if (!strcmp(attr, "v1"))
+ if (!strcmp(attr_str, "v1"))
{
return PyInt_FromLong(m_polygon->GetVertexOffset(0));
}
- if (!strcmp(attr, "v2"))
+ if (!strcmp(attr_str, "v2"))
{
return PyInt_FromLong(m_polygon->GetVertexOffset(1));
}
- if (!strcmp(attr, "v3"))
+ if (!strcmp(attr_str, "v3"))
{
return PyInt_FromLong(m_polygon->GetVertexOffset(2));
}
- if (!strcmp(attr, "v4"))
+ if (!strcmp(attr_str, "v4"))
{
return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0));
}
- if (!strcmp(attr, "visible"))
+ if (!strcmp(attr_str, "visible"))
{
return PyInt_FromLong(m_polygon->IsVisible());
}
- if (!strcmp(attr, "collide"))
+ if (!strcmp(attr_str, "collide"))
{
return PyInt_FromLong(m_polygon->IsCollider());
}
- _getattr_up(SCA_IObject);
+ py_getattro_up(SCA_IObject);
}
KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
@@ -165,7 +175,7 @@ CValue* KX_PolyProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
CValue* KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}
STR_String sPolyName="polygone";
const STR_String & KX_PolyProxy::GetText() {return sPolyName;};
-float KX_PolyProxy::GetNumber() { return -1;}
+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;}
@@ -179,7 +189,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex,
{
RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
unsigned int matid;
- for (matid=0; matid<m_mesh->NumMaterials(); matid++)
+ for (matid=0; matid<(unsigned int)m_mesh->NumMaterials(); matid++)
{
RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
if (meshMat->m_bucket == polyBucket)
@@ -226,13 +236,13 @@ KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex,
"Note: getVertexIndex(3) on a triangle polygon returns 0\n")
{
int index;
- if (!PyArg_ParseTuple(args,"i",&index))
+ if (!PyArg_ParseTuple(args,"i:getVertexIndex",&index))
{
return NULL;
}
if (index < 0 || index > 3)
{
- PyErr_SetString(PyExc_AttributeError, "Valid range for index is 0-3");
+ PyErr_SetString(PyExc_AttributeError, "poly.getVertexIndex(int): KX_PolyProxy, expected an index between 0-3");
return NULL;
}
if (index < m_polygon->VertexCount())
@@ -246,7 +256,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh,
"getMesh() : returns a mesh proxy\n")
{
KX_MeshProxy* meshproxy = new KX_MeshProxy((RAS_MeshObject*)m_mesh);
- return meshproxy;
+ return meshproxy->NewProxy(true);
}
KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial,
@@ -256,13 +266,11 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial,
if(polymat->GetFlag() & RAS_BLENDERMAT)
{
KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
- Py_INCREF(mat);
- return mat;
+ return mat->GetProxy();
}
else
{
KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
- Py_INCREF(mat);
- return mat;
+ return mat->GetProxy();
}
}
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h
index 9b548f9490d..275e65da810 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.h
+++ b/source/gameengine/Ketsji/KX_PolyProxy.h
@@ -45,7 +45,7 @@ public:
CValue* Calc(VALUE_OPERATOR op, CValue *val) ;
CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
const STR_String & GetText();
- float GetNumber();
+ double GetNumber();
STR_String GetName();
void SetName(STR_String name); // Set the name of the value
void ReplicaSetName(STR_String name);
@@ -53,7 +53,7 @@ public:
// stuff for python integration
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialIndex)
KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getNumVertex)
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index bbaf697b168..46d04486cc6 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -98,8 +98,7 @@ bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingI
{
PyObject *pyRasty = PyCObject_FromVoidPtr((void*)rasty, NULL); /* new reference */
PyObject *pyCachingInfo = PyCObject_FromVoidPtr((void*) &cachingInfo, NULL); /* new reference */
-
- PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this);
+ PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this->m_proxy);
if (ret)
{
bool value = PyInt_AsLong(ret);
@@ -109,6 +108,8 @@ bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingI
else
{
PyErr_Print();
+ PyErr_Clear();
+ PySys_SetObject( (char *)"last_traceback", NULL);
}
}
else
@@ -181,181 +182,70 @@ PyMethodDef KX_PolygonMaterial::Methods[] = {
};
PyAttributeDef KX_PolygonMaterial::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("texture", KX_PolygonMaterial, pyattr_get_texture),
+ KX_PYATTRIBUTE_RO_FUNCTION("material", KX_PolygonMaterial, pyattr_get_material), /* should probably be .name ? */
+
+ KX_PYATTRIBUTE_INT_RW("tile", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tile),
+ 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_BOOL_RW("transparent", KX_PolygonMaterial, m_alpha),
+ KX_PYATTRIBUTE_BOOL_RW("zsort", KX_PolygonMaterial, m_zsort),
+
+ KX_PYATTRIBUTE_FLOAT_RW("shininess", 0.0f, 1000.0f, KX_PolygonMaterial, m_shininess),
+ KX_PYATTRIBUTE_FLOAT_RW("specularity", 0.0f, 1000.0f, KX_PolygonMaterial, m_specularity),
+
+ KX_PYATTRIBUTE_RW_FUNCTION("diffuse", KX_PolygonMaterial, pyattr_get_texture, pyattr_set_diffuse),
+ KX_PYATTRIBUTE_RW_FUNCTION("specular",KX_PolygonMaterial, pyattr_get_specular, pyattr_set_specular),
+
+ KX_PYATTRIBUTE_RO_FUNCTION("tface", KX_PolygonMaterial, pyattr_get_tface), /* How the heck is this even useful??? - Campbell */
+ KX_PYATTRIBUTE_RO_FUNCTION("gl_texture", KX_PolygonMaterial, pyattr_get_gl_texture), /* could be called 'bindcode' */
+
+ /* triangle used to be an attribute, removed for 2.49, nobody should be using it */
{ NULL } //Sentinel
};
PyTypeObject KX_PolygonMaterial::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_PolygonMaterial",
- sizeof(KX_PolygonMaterial),
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
0,
- PyDestructor,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0 //&cvalue_as_number,
+ 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 KX_PolygonMaterial::Parents[] = {
- &PyObjectPlus::Type,
&KX_PolygonMaterial::Type,
+ &PyObjectPlus::Type,
NULL
};
-PyObject* KX_PolygonMaterial::_getattr(const char *attr)
-{
- if (!strcmp(attr, "texture"))
- return PyString_FromString(m_texturename.ReadPtr());
- if (!strcmp(attr, "material"))
- return PyString_FromString(m_materialname.ReadPtr());
-
- if (!strcmp(attr, "tface"))
- return PyCObject_FromVoidPtr(m_tface, NULL);
-
- if (!strcmp(attr, "gl_texture"))
- {
- Image *ima = m_tface->tpage;
- int bind = 0;
- if (ima)
- bind = ima->bindcode;
-
- return PyInt_FromLong(bind);
- }
-
- if (!strcmp(attr, "tile"))
- return PyInt_FromLong(m_tile);
- if (!strcmp(attr, "tilexrep"))
- return PyInt_FromLong(m_tilexrep);
- if (!strcmp(attr, "tileyrep"))
- return PyInt_FromLong(m_tileyrep);
-
- if (!strcmp(attr, "drawingmode"))
- return PyInt_FromLong(m_drawingmode);
- if (!strcmp(attr, "transparent"))
- return PyInt_FromLong(m_alpha);
- if (!strcmp(attr, "zsort"))
- return PyInt_FromLong(m_zsort);
- if (!strcmp(attr, "lightlayer"))
- return PyInt_FromLong(m_lightlayer);
- if (!strcmp(attr, "triangle"))
- // deprecated, triangle/quads shouldn't have been a material property
- return 0;
-
- if (!strcmp(attr, "diffuse"))
- return PyObjectFrom(m_diffuse);
- if (!strcmp(attr, "shininess"))
- return PyFloat_FromDouble(m_shininess);
- if (!strcmp(attr, "specular"))
- return PyObjectFrom(m_specular);
- if (!strcmp(attr, "specularity"))
- return PyFloat_FromDouble(m_specularity);
-
- _getattr_up(PyObjectPlus);
+PyObject* KX_PolygonMaterial::py_getattro(PyObject *attr)
+{
+ py_getattro_up(PyObjectPlus);
}
-int KX_PolygonMaterial::_setattr(const char *attr, PyObject *pyvalue)
+int KX_PolygonMaterial::py_setattro(PyObject *attr, PyObject *value)
{
- if (PyFloat_Check(pyvalue))
- {
- float value = PyFloat_AsDouble(pyvalue);
- if (!strcmp(attr, "shininess"))
- {
- m_shininess = value;
- return 0;
- }
-
- if (!strcmp(attr, "specularity"))
- {
- m_specularity = value;
- return 0;
- }
- }
-
- if (PyInt_Check(pyvalue))
- {
- int value = PyInt_AsLong(pyvalue);
- if (!strcmp(attr, "tile"))
- {
- m_tile = value;
- return 0;
- }
-
- if (!strcmp(attr, "tilexrep"))
- {
- m_tilexrep = value;
- return 0;
- }
-
- if (!strcmp(attr, "tileyrep"))
- {
- m_tileyrep = value;
- return 0;
- }
-
- if (!strcmp(attr, "drawingmode"))
- {
- m_drawingmode = value;
- return 0;
- }
-
- if (!strcmp(attr, "transparent"))
- {
- m_alpha = value;
- return 0;
- }
-
- if (!strcmp(attr, "zsort"))
- {
- m_zsort = value;
- return 0;
- }
-
- if (!strcmp(attr, "lightlayer"))
- {
- m_lightlayer = value;
- return 0;
- }
-
- // This probably won't work...
- if (!strcmp(attr, "triangle"))
- {
- // deprecated, triangle/quads shouldn't have been a material property
- return 0;
- }
- }
-
- if (PySequence_Check(pyvalue))
- {
- if (PySequence_Size(pyvalue) == 3)
- {
- MT_Vector3 value;
- if (PyVecTo(pyvalue, value))
- {
- if (!strcmp(attr, "diffuse"))
- {
- m_diffuse = value;
- return 0;
- }
-
- if (!strcmp(attr, "specular"))
- {
- m_specular = value;
- return 0;
- }
- }
- }
- }
-
- return PyObjectPlus::_setattr(attr, pyvalue);
+ py_setattro_up(PyObjectPlus);
}
KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(material)")
{
PyObject *material;
- if (PyArg_ParseTuple(args, "O", &material))
+ if (PyArg_ParseTuple(args, "O:setCustomMaterial", &material))
{
if (m_pymaterial) {
Py_DECREF(m_pymaterial);
@@ -371,7 +261,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(mat
KX_PYMETHODDEF_DOC(KX_PolygonMaterial, updateTexture, "updateTexture(tface, rasty)")
{
PyObject *pyrasty, *pytface;
- if (PyArg_ParseTuple(args, "O!O!", &PyCObject_Type, &pytface, &PyCObject_Type, &pyrasty))
+ if (PyArg_ParseTuple(args, "O!O!:updateTexture", &PyCObject_Type, &pytface, &PyCObject_Type, &pyrasty))
{
MTFace *tface = (MTFace*) PyCObject_AsVoidPtr(pytface);
RAS_IRasterizer *rasty = (RAS_IRasterizer*) PyCObject_AsVoidPtr(pyrasty);
@@ -387,7 +277,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, updateTexture, "updateTexture(tface, rast
KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)")
{
PyObject *pytface;
- if (PyArg_ParseTuple(args, "O!", &PyCObject_Type, &pytface))
+ if (PyArg_ParseTuple(args, "O!:setTexture", &PyCObject_Type, &pytface))
{
MTFace *tface = (MTFace*) PyCObject_AsVoidPtr(pytface);
GPU_set_tpage(tface);
@@ -400,7 +290,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)")
KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)")
{
PyObject *pyrasty, *pyCachingInfo;
- if (PyArg_ParseTuple(args, "O!O!", &PyCObject_Type, &pyrasty, &PyCObject_Type, &pyCachingInfo))
+ if (PyArg_ParseTuple(args, "O!O!:activate", &PyCObject_Type, &pyrasty, &PyCObject_Type, &pyCachingInfo))
{
RAS_IRasterizer *rasty = static_cast<RAS_IRasterizer*>(PyCObject_AsVoidPtr(pyrasty));
TCachingInfo *cachingInfo = static_cast<TCachingInfo*>(PyCObject_AsVoidPtr(pyCachingInfo));
@@ -413,3 +303,69 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)")
return NULL;
}
+
+PyObject* KX_PolygonMaterial::pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ return PyString_FromString(self->m_texturename.ReadPtr());
+}
+
+PyObject* KX_PolygonMaterial::pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ return PyString_FromString(self->m_materialname.ReadPtr());
+}
+
+/* this does not seem useful */
+PyObject* KX_PolygonMaterial::pyattr_get_tface(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ return PyCObject_FromVoidPtr(self->m_tface, NULL);
+}
+
+PyObject* KX_PolygonMaterial::pyattr_get_gl_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ int bindcode= 0;
+ if (self->m_tface && self->m_tface->tpage)
+ bindcode= self->m_tface->tpage->bindcode;
+
+ return PyInt_FromLong(bindcode);
+}
+
+
+PyObject* KX_PolygonMaterial::pyattr_get_diffuse(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ return PyObjectFrom(self->m_diffuse);
+}
+
+int KX_PolygonMaterial::pyattr_set_diffuse(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ MT_Vector3 vec;
+
+ if (!PyVecTo(value, vec))
+ return -1;
+
+ self->m_diffuse= vec;
+ return 0;
+}
+
+PyObject* KX_PolygonMaterial::pyattr_get_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ return PyObjectFrom(self->m_specular);
+}
+
+int KX_PolygonMaterial::pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
+ MT_Vector3 vec;
+
+ if (!PyVecTo(value, vec))
+ return -1;
+
+ self->m_specular= vec;
+ return 0;
+}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index a3ef4ca51ef..9865a66e836 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -33,6 +33,7 @@
#include "RAS_MaterialBucket.h"
#include "RAS_IRasterizer.h"
+#include "DNA_ID.h"
struct MTFace;
struct Material;
@@ -115,8 +116,20 @@ public:
KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial);
KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram);
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *pyvalue);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
+ virtual PyObject* py_repr(void) { return PyString_FromString(m_material ? ((ID *)m_material)->name+2 : ""); }
+
+ static PyObject* pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
+ static PyObject* pyattr_get_tface(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_gl_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
+ static PyObject* pyattr_get_diffuse(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_diffuse(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_specular(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
};
#endif // __KX_POLYGONMATERIAL_H__
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index fb37eded450..2c65c184a9c 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -381,7 +381,7 @@ static PyObject* gPyGetVehicleConstraint(PyObject* self,
if (vehicle)
{
KX_VehicleWrapper* pyWrapper = new KX_VehicleWrapper(vehicle,PHY_GetActiveEnvironment());
- return pyWrapper;
+ return pyWrapper->NewProxy(true);
}
}
@@ -440,7 +440,7 @@ static PyObject* gPyCreateConstraint(PyObject* self,
KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment());
- return wrap;
+ return wrap->NewProxy(true);
}
@@ -582,6 +582,7 @@ PyObject* initPythonConstraintBinding()
d = PyModule_GetDict(m);
ErrorObject = PyString_FromString("PhysicsConstraints.error");
PyDict_SetItemString(d, "error", ErrorObject);
+ Py_DECREF(ErrorObject);
// XXXX Add constants here
diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp
index 92f18590a7e..0093a72808e 100644
--- a/source/gameengine/Ketsji/KX_PyMath.cpp
+++ b/source/gameengine/Ketsji/KX_PyMath.cpp
@@ -44,6 +44,7 @@
#include "ListValue.h"
#include "KX_Python.h"
+#include "KX_PyMath.h"
bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
{
@@ -74,6 +75,39 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
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)
{
@@ -93,7 +127,7 @@ PyObject* PyObjectFrom(const MT_Matrix4x4 &mat)
PyList_SET_ITEM(sublist, 0, PyFloat_FromDouble(mat[i][0]));
PyList_SET_ITEM(sublist, 1, PyFloat_FromDouble(mat[i][1]));
PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][2]));
- PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][3]));
+ PyList_SET_ITEM(sublist, 3, PyFloat_FromDouble(mat[i][3]));
PyList_SET_ITEM(list, i, sublist);
}
diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h
index 39c9c358792..00f7c5cad93 100644
--- a/source/gameengine/Ketsji/KX_PyMath.h
+++ b/source/gameengine/Ketsji/KX_PyMath.h
@@ -92,18 +92,35 @@ bool PyMatTo(PyObject* pymat, T& mat)
}
/**
- * Converts a python list to a MT class.
+ * Converts a python sequence to a MT class.
*/
template<class T>
bool PyVecTo(PyObject* pyval, T& vec)
{
- if (PySequence_Check(pyval))
+
+ if(PyTuple_Check(pyval))
+ {
+ unsigned int numitems = PyTuple_GET_SIZE(pyval);
+ if (numitems != Size(vec)) {
+ PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", numitems, Size(vec));
+ return false;
+ }
+
+ for (unsigned int x = 0; x < numitems; x++)
+ vec[x] = PyFloat_AsDouble(PyTuple_GET_ITEM(pyval, x)); /* borrow ref */
+
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_AttributeError, "one or more of the items in the sequence was not a float");
+ return false;
+ }
+
+ return true;
+ }
+ else if (PySequence_Check(pyval))
{
unsigned int numitems = PySequence_Size(pyval);
if (numitems != Size(vec)) {
- char err[128];
- sprintf(err, "error setting vector, %d args, should be %d", numitems, Size(vec));
- PyErr_SetString(PyExc_AttributeError, err);
+ PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", numitems, Size(vec));
return false;
}
@@ -122,14 +139,14 @@ bool PyVecTo(PyObject* pyval, T& vec)
return true;
} else
{
- char err[128];
- sprintf(err, "not a sequence type, expected a sequence of numbers size %d", Size(vec));
- PyErr_SetString(PyExc_AttributeError, err);
+ PyErr_Format(PyExc_AttributeError, "not a sequence type, expected a sequence of numbers size %d", Size(vec));
}
return false;
}
+bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix);
+
/**
* Converts an MT_Matrix4x4 to a python object.
*/
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 965c4ed2ba3..ffcf7d7162e 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -48,33 +48,45 @@
#include "KX_KetsjiEngine.h"
#include "KX_RadarSensor.h"
+#include "KX_RaySensor.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"
-#include "PyObjectPlus.h"
+#include "PyObjectPlus.h"
//XXX
#if 0
+
+#include "KX_PythonInitTypes.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! */
+ #include "BGL.h"
}
#endif
@@ -94,7 +106,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;
@@ -111,9 +123,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 !
@@ -156,7 +168,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);
@@ -164,6 +176,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;
@@ -240,7 +274,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);
@@ -255,7 +289,7 @@ static PyObject* gPyGetLogicTicRate(PyObject*)
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);
@@ -265,7 +299,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);
@@ -293,7 +327,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);
@@ -329,8 +363,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 =
@@ -339,7 +372,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();
@@ -350,13 +382,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 *)
@@ -433,6 +462,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__},
@@ -478,7 +508,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);
@@ -490,7 +520,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)
@@ -511,7 +541,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)
@@ -523,11 +553,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;
}
@@ -536,10 +566,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;
}
@@ -549,11 +579,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;
}
@@ -565,7 +595,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;
}
@@ -598,7 +628,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]);
@@ -612,11 +642,11 @@ 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;
}
@@ -631,11 +661,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;
}
@@ -653,7 +683,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]);
@@ -667,7 +697,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)
@@ -681,11 +711,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;
}
@@ -697,7 +727,7 @@ static PyObject* gPyEnableMotionBlur(PyObject*, PyObject* args)
static PyObject* gPyDisableMotionBlur(PyObject*, PyObject* args)
{
if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer not available");
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.disableMotionBlur(), Rasterizer not available");
return NULL;
}
@@ -731,13 +761,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;
}
@@ -772,13 +802,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;
}
@@ -796,7 +826,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)
@@ -806,7 +836,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;
}
@@ -837,11 +867,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;
@@ -882,7 +912,7 @@ static struct PyMethodDef rasterizer_methods[] = {
{"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,
@@ -914,7 +944,8 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
{
PyObject* m;
PyObject* d;
-
+ PyObject* item; /* temp PyObject* storage */
+
gp_KetsjiEngine = engine;
gp_KetsjiScene = scene;
@@ -930,10 +961,12 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
// 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 */
@@ -966,6 +999,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);
@@ -973,6 +1012,7 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_IPOACT_FLIPPER, KX_IpoActuator::KX_ACT_IPO_FLIPPER);
KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPSTOP, KX_IpoActuator::KX_ACT_IPO_LOOPSTOP);
KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPEND, KX_IpoActuator::KX_ACT_IPO_LOOPEND);
+ KX_MACRO_addTypesToDict(d, KX_IPOACT_FROM_PROP,KX_IpoActuator::KX_ACT_IPO_FROM_PROP);
/* 5. Random distribution types */
KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_CONST, SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST);
@@ -1072,6 +1112,66 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Y, KX_RadarSensor::KX_RADAR_AXIS_NEG_X);
KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Z, KX_RadarSensor::KX_RADAR_AXIS_NEG_Z);
+ /* Ray Sensor */
+ KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_POS_X, KX_RaySensor::KX_RAY_AXIS_POS_X);
+ KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_POS_Y, KX_RaySensor::KX_RAY_AXIS_POS_Y);
+ KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_POS_Z, KX_RaySensor::KX_RAY_AXIS_POS_Z);
+ KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_X, KX_RaySensor::KX_RAY_AXIS_NEG_Y);
+ KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Y, KX_RaySensor::KX_RAY_AXIS_NEG_X);
+ KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Z, KX_RaySensor::KX_RAY_AXIS_NEG_Z);
+
+ /* Dynamic actuator */
+ KX_MACRO_addTypesToDict(d, KX_DYN_RESTORE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_RESTORE_DYNAMICS);
+ KX_MACRO_addTypesToDict(d, KX_DYN_DISABLE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_DISABLE_DYNAMICS);
+ KX_MACRO_addTypesToDict(d, KX_DYN_ENABLE_RIGID_BODY, KX_SCA_DynamicActuator::KX_DYN_ENABLE_RIGID_BODY);
+ 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);
+
// Check for errors
if (PyErr_Occurred())
{
@@ -1090,11 +1190,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;
@@ -1113,6 +1208,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;
@@ -1142,16 +1238,48 @@ 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")) {
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 */
+ /* XXX 2.5
+ * 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;
+
+ /* XXX 2.5 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 */
#if 0
static int
@@ -1184,18 +1312,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));
@@ -1224,6 +1352,9 @@ void setSandbox(TPythonSecurityLevel level)
}
*/
default:
+ /* Allow importing internal text, from bpy_internal_import.py */
+ /* XXX 2.5 PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item); */
+ /* XXX 2.5 PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item); */
break;
}
}
@@ -1231,31 +1362,39 @@ void setSandbox(TPythonSecurityLevel level)
/**
* 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)
{
STR_String pname = progname;
Py_SetProgramName(pname.Ptr());
Py_NoSiteFlag=1;
Py_FrozenFlag=1;
Py_Initialize();
-
+
+ if(argv) /* browser plugins dont currently set this */
+ PySys_SetArgv(argc, argv);
+
//importBlenderModules()
setSandbox(level);
-
+ /* XXX 2.5 initPyTypes(); */
+
+ /* XXX 2.5 bpy_import_main_set(maggie); */
+
PyObject* moduleobj = PyImport_AddModule("__main__");
return PyModule_GetDict(moduleobj);
}
void exitGamePlayerPythonScripting()
{
+ //clearGameModules(); // were closing python anyway
Py_Finalize();
+ /* XXX 2.5 bpy_import_main_set(NULL); */
}
/**
* Python is already initialized.
*/
-PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level)
+PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie)
{
STR_String pname = progname;
Py_SetProgramName(pname.Ptr());
@@ -1263,15 +1402,54 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev
Py_FrozenFlag=1;
setSandbox(level);
+ /* XXX 2.5 initPyTypes(); */
+
+ /* XXX 2.5 bpy_import_main_set(maggie); */
+
+ /* run this to clear game modules and user modules which
+ * may contain references to in game data */
+ clearGameModules();
PyObject* moduleobj = PyImport_AddModule("__main__");
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()
+{
+ /* 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, "BGL");
+ PyErr_Clear(); // incase some of these were alredy removed.
+
+ /* clear user defined modules */
+ /* XXX 2.5 bpy_text_clear_modules(); */
+}
void exitGamePythonScripting()
{
+ clearGameModules();
+ /* XXX 2.5 bpy_import_main_set(NULL); */
}
@@ -1284,6 +1462,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
PyObject* m;
PyObject* d;
+ PyObject* item;
// Create the module and add the functions
m = Py_InitModule4("Rasterizer", rasterizer_methods,
@@ -1294,6 +1473,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
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);
@@ -1322,7 +1502,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)
@@ -1345,13 +1525,35 @@ 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 }
};
@@ -1362,6 +1564,7 @@ PyObject* initGameKeys()
{
PyObject* m;
PyObject* d;
+ PyObject* item;
// Create the module and add the functions
m = Py_InitModule4("GameKeys", gamekeys_methods,
@@ -1486,7 +1689,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())
{
@@ -1501,6 +1703,11 @@ PyObject* initMathutils()
return NULL; //XXX Mathutils_Init("Mathutils"); // Use as a top level module in BGE
}
+PyObject* initBGL()
+{
+ return NULL; // XXX 2.5 BGL_Init("BGL"); // Use as a top level module in BGE
+}
+
void KX_SetActiveScene(class KX_Scene* scene)
{
gp_KetsjiScene = scene;
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index 57ee0be9400..11360197b95 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -43,11 +43,12 @@ extern bool gUseVisibilityTemp;
PyObject* initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene* ketsjiscene);
PyObject* initGameKeys();
PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
-PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level);
+PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie, int argc, char** argv);
PyObject* initMathutils();
+PyObject* initBGL();
PyObject* initVideoTexture(void);
void exitGamePlayerPythonScripting();
-PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level);
+PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie);
void exitGamePythonScripting();
void setGamePythonPath(char *path);
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
new file mode 100644
index 00000000000..dcd11b551a1
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -0,0 +1,233 @@
+/**
+ * $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 *****
+ */
+
+
+
+#ifndef _adr_py_init_types_h_ // only process once,
+#define _adr_py_init_types_h_ // even if multiply included
+
+/* Only for Class::Parents */
+#include "BL_BlenderShader.h"
+#include "BL_ShapeActionActuator.h"
+#include "KX_BlenderMaterial.h"
+#include "KX_CDActuator.h"
+#include "KX_CameraActuator.h"
+#include "KX_ConstraintActuator.h"
+#include "KX_ConstraintWrapper.h"
+#include "KX_GameActuator.h"
+#include "KX_Light.h"
+#include "KX_MeshProxy.h"
+#include "KX_MouseFocusSensor.h"
+#include "KX_NetworkMessageActuator.h"
+#include "KX_NetworkMessageSensor.h"
+#include "KX_ObjectActuator.h"
+#include "KX_ParentActuator.h"
+#include "KX_PhysicsObjectWrapper.h"
+#include "KX_PolyProxy.h"
+#include "KX_PolygonMaterial.h"
+#include "KX_SCA_AddObjectActuator.h"
+#include "KX_SCA_EndObjectActuator.h"
+#include "KX_SCA_ReplaceMeshActuator.h"
+#include "KX_SceneActuator.h"
+#include "KX_StateActuator.h"
+#include "KX_TrackToActuator.h"
+#include "KX_VehicleWrapper.h"
+#include "KX_VertexProxy.h"
+#include "SCA_2DFilterActuator.h"
+#include "SCA_ANDController.h"
+#include "SCA_ActuatorSensor.h"
+#include "SCA_AlwaysSensor.h"
+#include "SCA_DelaySensor.h"
+#include "SCA_JoystickSensor.h"
+#include "SCA_KeyboardSensor.h"
+#include "SCA_MouseSensor.h"
+#include "SCA_NANDController.h"
+#include "SCA_NORController.h"
+#include "SCA_ORController.h"
+#include "SCA_RandomSensor.h"
+#include "SCA_XNORController.h"
+#include "SCA_XORController.h"
+#include "KX_IpoActuator.h"
+#include "KX_NearSensor.h"
+#include "KX_RadarSensor.h"
+#include "KX_RaySensor.h"
+#include "KX_SCA_DynamicActuator.h"
+#include "KX_SoundActuator.h"
+#include "KX_TouchSensor.h"
+#include "KX_VisibilityActuator.h"
+#include "SCA_PropertySensor.h"
+#include "SCA_PythonController.h"
+#include "SCA_RandomActuator.h"
+
+
+void initPyObjectPlusType(PyTypeObject **parents)
+{
+ int i;
+
+ for (i=0; parents[i]; i++) {
+ if(PyType_Ready(parents[i]) < 0) {
+ /* This is very very unlikely */
+ printf("Error, pytype could not initialize, Blender may crash \"%s\"\n", parents[i]->tp_name);
+ return;
+ }
+
+#if 0
+ PyObject_Print(reinterpret_cast<PyObject *>parents[i], stderr, 0);
+ fprintf(stderr, "\n");
+ PyObject_Print(parents[i]->tp_dict, stderr, 0);
+ fprintf(stderr, "\n\n");
+#endif
+
+ }
+
+ PyObject *dict= NULL;
+
+ while(i) {
+ i--;
+
+ if (dict) {
+ PyDict_Update(parents[i]->tp_dict, dict);
+ }
+ dict= parents[i]->tp_dict;
+
+#if 1
+ PyObject_Print(reinterpret_cast<PyObject *>(parents[i]), stderr, 0);
+ fprintf(stderr, "\n");
+ PyObject_Print(parents[i]->tp_dict, stderr, 0);
+ fprintf(stderr, "\n\n");
+#endif
+
+ }
+}
+
+
+
+
+static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes)
+{
+ PyAttributeDef *attr;
+ PyObject *item;
+
+ PyType_Ready(tp);
+ PyDict_SetItemString(dict, tp->tp_name, reinterpret_cast<PyObject *>(tp));
+
+ /* store attr defs in the tp_dict for to avoid string lookups */
+ for(attr= attributes; attr->m_name; attr++) {
+ item= PyCObject_FromVoidPtr(attr, NULL);
+ PyDict_SetItemString(tp->tp_dict, attr->m_name, item);
+ Py_DECREF(item);
+ }
+
+}
+
+
+#define PyType_Ready_Attr(d, n) PyType_Ready_ADD(d, &n::Type, n::Attributes)
+
+void initPyTypes(void)
+{
+
+/*
+ initPyObjectPlusType(BL_ActionActuator::Parents);
+ .....
+*/
+
+ /* For now just do PyType_Ready */
+ PyObject *mod= PyModule_New("GameTypes");
+ PyObject *dict= PyModule_GetDict(mod);
+ PyDict_SetItemString(PySys_GetObject((char *)"modules"), (char *)"GameTypes", mod);
+ Py_DECREF(mod);
+
+ PyType_Ready_Attr(dict, BL_ActionActuator);
+ PyType_Ready_Attr(dict, BL_Shader);
+ PyType_Ready_Attr(dict, BL_ShapeActionActuator);
+ PyType_Ready_Attr(dict, CListValue);
+ PyType_Ready_Attr(dict, CValue);
+ PyType_Ready_Attr(dict, KX_BlenderMaterial);
+ PyType_Ready_Attr(dict, KX_CDActuator);
+ PyType_Ready_Attr(dict, KX_Camera);
+ PyType_Ready_Attr(dict, KX_CameraActuator);
+ PyType_Ready_Attr(dict, KX_ConstraintActuator);
+ PyType_Ready_Attr(dict, KX_ConstraintWrapper);
+ PyType_Ready_Attr(dict, KX_GameActuator);
+ PyType_Ready_Attr(dict, KX_GameObject);
+ PyType_Ready_Attr(dict, KX_IpoActuator);
+ PyType_Ready_Attr(dict, KX_LightObject);
+ PyType_Ready_Attr(dict, KX_MeshProxy);
+ PyType_Ready_Attr(dict, KX_MouseFocusSensor);
+ PyType_Ready_Attr(dict, KX_NearSensor);
+ PyType_Ready_Attr(dict, KX_NetworkMessageActuator);
+ PyType_Ready_Attr(dict, KX_NetworkMessageSensor);
+ PyType_Ready_Attr(dict, KX_ObjectActuator);
+ PyType_Ready_Attr(dict, KX_ParentActuator);
+ PyType_Ready_Attr(dict, KX_PhysicsObjectWrapper);
+ PyType_Ready_Attr(dict, KX_PolyProxy);
+ PyType_Ready_Attr(dict, KX_PolygonMaterial);
+ PyType_Ready_Attr(dict, KX_RadarSensor);
+ PyType_Ready_Attr(dict, KX_RaySensor);
+ PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator);
+ PyType_Ready_Attr(dict, KX_SCA_DynamicActuator);
+ PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator);
+ PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator);
+ PyType_Ready_Attr(dict, KX_Scene);
+ PyType_Ready_Attr(dict, KX_SceneActuator);
+ PyType_Ready_Attr(dict, KX_SoundActuator);
+ PyType_Ready_Attr(dict, KX_StateActuator);
+ PyType_Ready_Attr(dict, KX_TouchSensor);
+ PyType_Ready_Attr(dict, KX_TrackToActuator);
+ PyType_Ready_Attr(dict, KX_VehicleWrapper);
+ PyType_Ready_Attr(dict, KX_VertexProxy);
+ PyType_Ready_Attr(dict, KX_VisibilityActuator);
+ PyType_Ready_Attr(dict, PyObjectPlus);
+ PyType_Ready_Attr(dict, SCA_2DFilterActuator);
+ PyType_Ready_Attr(dict, SCA_ANDController);
+ PyType_Ready_Attr(dict, SCA_ActuatorSensor);
+ PyType_Ready_Attr(dict, SCA_AlwaysSensor);
+ PyType_Ready_Attr(dict, SCA_DelaySensor);
+ PyType_Ready_Attr(dict, SCA_ILogicBrick);
+ PyType_Ready_Attr(dict, SCA_IObject);
+ PyType_Ready_Attr(dict, SCA_ISensor);
+ PyType_Ready_Attr(dict, SCA_JoystickSensor);
+ PyType_Ready_Attr(dict, SCA_KeyboardSensor);
+ PyType_Ready_Attr(dict, SCA_MouseSensor);
+ PyType_Ready_Attr(dict, SCA_NANDController);
+ PyType_Ready_Attr(dict, SCA_NORController);
+ PyType_Ready_Attr(dict, SCA_ORController);
+ PyType_Ready_Attr(dict, SCA_PropertyActuator);
+ PyType_Ready_Attr(dict, SCA_PropertySensor);
+ PyType_Ready_Attr(dict, SCA_PythonController);
+ PyType_Ready_Attr(dict, SCA_RandomActuator);
+ PyType_Ready_Attr(dict, SCA_RandomSensor);
+ PyType_Ready_Attr(dict, SCA_XNORController);
+ PyType_Ready_Attr(dict, SCA_XORController);
+
+
+
+}
+
+#endif \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.h b/source/gameengine/Ketsji/KX_PythonInitTypes.h
new file mode 100644
index 00000000000..6da79be9301
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.h
@@ -0,0 +1,35 @@
+/**
+ * $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 *****
+ */
+
+#ifndef _adr_py_init_types_h_ // only process once,
+#define _adr_py_init_types_h_ // even if multiply included
+
+void initPyTypes(void);
+
+#endif
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index fa8998cd81d..8277e7ef19c 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -100,8 +100,9 @@ CValue* KX_RadarSensor::GetReplica()
//>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);
-
- ((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
+ //Wrong: see KX_TouchSensor
+ //bool parentUpdated = false;
+ //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
replica->SynchronizeTransform();
return replica;
@@ -206,7 +207,7 @@ const char KX_RadarSensor::GetConeOrigin_doc[] =
"getConeOrigin()\n"
"\tReturns the origin of the cone with which to test. The origin\n"
"\tis in the middle of the cone.";
-PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self) {
+PyObject* KX_RadarSensor::PyGetConeOrigin() {
ShowDeprecationWarning("getConeOrigin()", "the coneOrigin property");
PyObject *retVal = PyList_New(3);
@@ -222,7 +223,7 @@ PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self) {
const char KX_RadarSensor::GetConeTarget_doc[] =
"getConeTarget()\n"
"\tReturns the center of the bottom face of the cone with which to test.\n";
-PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self) {
+PyObject* KX_RadarSensor::PyGetConeTarget() {
ShowDeprecationWarning("getConeTarget()", "the coneTarget property");
PyObject *retVal = PyList_New(3);
@@ -238,7 +239,7 @@ PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self) {
const char KX_RadarSensor::GetConeHeight_doc[] =
"getConeHeight()\n"
"\tReturns the height of the cone with which to test.\n";
-PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self) {
+PyObject* KX_RadarSensor::PyGetConeHeight() {
ShowDeprecationWarning("getConeHeight()", "the distance property");
@@ -250,22 +251,22 @@ PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self) {
/* Python Integration Hooks */
/* ------------------------------------------------------------------------- */
PyTypeObject KX_RadarSensor::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_RadarSensor",
- sizeof(KX_RadarSensor),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_RadarSensor::Parents[] = {
@@ -298,20 +299,12 @@ PyAttributeDef KX_RadarSensor::Attributes[] = {
{NULL} //Sentinel
};
-PyObject* KX_RadarSensor::_getattr(const char *attr)
+PyObject* KX_RadarSensor::py_getattro(PyObject *attr)
{
- PyObject* object = _getattr_self(Attributes, this, attr);
- if (object != NULL)
- return object;
-
- _getattr_up(KX_NearSensor);
+ py_getattro_up(KX_NearSensor);
}
-int KX_RadarSensor::_setattr(const char *attr, PyObject* value)
+int KX_RadarSensor::py_setattro(PyObject *attr, PyObject* value)
{
- int ret = _setattr_self(Attributes, this, attr, value);
- if (ret >= 0)
- return ret;
-
- return KX_NearSensor::_setattr(attr, value);
+ py_setattro_up(KX_NearSensor);
}
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h
index 6dfe0c42f5d..c3a941696ce 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.h
+++ b/source/gameengine/Ketsji/KX_RadarSensor.h
@@ -89,8 +89,8 @@ public:
KX_RADAR_AXIS_NEG_Z
};
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject* value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
//Deprecated ----->
KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin);
diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp
index 974d4b992a6..8c7612bf663 100644
--- a/source/gameengine/Ketsji/KX_RayCast.cpp
+++ b/source/gameengine/Ketsji/KX_RayCast.cpp
@@ -56,12 +56,15 @@ void KX_RayCast::reportHit(PHY_RayCastResult* result)
bool KX_RayCast::RayTest(PHY_IPhysicsEnvironment* physics_environment, const MT_Point3& _frompoint, const MT_Point3& topoint, KX_RayCast& callback)
{
+ if(physics_environment==NULL) return false; /* prevents crashing in some cases */
+
// Loops over all physics objects between frompoint and topoint,
// calling callback.RayHit for each one.
//
// callback.RayHit should return true to stop looking, or false to continue.
//
// returns true if an object was found, false if not.
+
MT_Point3 frompoint(_frompoint);
const MT_Vector3 todir( (topoint - frompoint).safe_normalized() );
MT_Point3 prevpoint(_frompoint+todir*(-1.f));
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index ce12b983147..06c04dbf10d 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -136,8 +136,13 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void
{
m_rayHit = true;
m_hitObject = hitKXObj;
- m_hitPosition = result->m_hitPoint;
- m_hitNormal = result->m_hitNormal;
+ m_hitPosition[0] = result->m_hitPoint[0];
+ m_hitPosition[1] = result->m_hitPoint[1];
+ m_hitPosition[2] = result->m_hitPoint[2];
+
+ m_hitNormal[0] = result->m_hitNormal[0];
+ m_hitNormal[1] = result->m_hitNormal[1];
+ m_hitNormal[2] = result->m_hitNormal[2];
}
// no multi-hit search yet
@@ -180,8 +185,13 @@ bool KX_RaySensor::Evaluate(CValue* event)
bool reset = m_reset && m_level;
m_rayHit = false;
m_hitObject = NULL;
- m_hitPosition.setValue(0,0,0);
- m_hitNormal.setValue(1,0,0);
+ m_hitPosition[0] = 0;
+ m_hitPosition[1] = 0;
+ m_hitPosition[2] = 0;
+
+ m_hitNormal[0] = 1;
+ m_hitNormal[1] = 0;
+ m_hitNormal[2] = 0;
KX_GameObject* obj = (KX_GameObject*)GetParent();
MT_Point3 frompoint = obj->NodeGetWorldPosition();
@@ -236,7 +246,9 @@ bool KX_RaySensor::Evaluate(CValue* event)
}
}
todir.normalize();
- m_rayDirection = todir;
+ m_rayDirection[0] = todir[0];
+ m_rayDirection[1] = todir[1];
+ m_rayDirection[2] = todir[2];
MT_Point3 topoint = frompoint + (m_distance) * todir;
PHY_IPhysicsEnvironment* pe = m_scene->GetPhysicsEnvironment();
@@ -309,22 +321,23 @@ bool KX_RaySensor::Evaluate(CValue* event)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_RaySensor::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_RaySensor",
- sizeof(KX_RaySensor),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_RaySensor::Parents[] = {
@@ -336,25 +349,47 @@ PyParentObject KX_RaySensor::Parents[] = {
};
PyMethodDef KX_RaySensor::Methods[] = {
+ // Deprecated ----->
{"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc},
{"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_NOARGS, (PY_METHODCHAR)GetHitPosition_doc},
{"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_NOARGS, (PY_METHODCHAR)GetHitNormal_doc},
{"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_NOARGS, (PY_METHODCHAR)GetRayDirection_doc},
+ // <-----
{NULL,NULL} //Sentinel
};
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_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),
+ KX_PYATTRIBUTE_FLOAT_ARRAY_RO("hitNormal", KX_RaySensor, m_hitNormal, 3),
+ KX_PYATTRIBUTE_RO_FUNCTION("hitObject", KX_RaySensor, pyattr_get_hitobject),
{ NULL } //Sentinel
};
+PyObject* KX_RaySensor::pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_RaySensor* self = static_cast<KX_RaySensor*>(self_v);
+ if (self->m_hitObject)
+ return self->m_hitObject->GetProxy();
+
+ Py_RETURN_NONE;
+}
+
+// Deprecated ----->
const char KX_RaySensor::GetHitObject_doc[] =
"getHitObject()\n"
"\tReturns the name of the object that was hit by this ray.\n";
-PyObject* KX_RaySensor::PyGetHitObject(PyObject* self)
+PyObject* KX_RaySensor::PyGetHitObject()
{
+ ShowDeprecationWarning("getHitObject()", "the hitObject property");
if (m_hitObject)
{
- return m_hitObject->AddRef();
+ return m_hitObject->GetProxy();
}
Py_RETURN_NONE;
}
@@ -363,29 +398,59 @@ PyObject* KX_RaySensor::PyGetHitObject(PyObject* self)
const char KX_RaySensor::GetHitPosition_doc[] =
"getHitPosition()\n"
"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
-PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self)
+PyObject* KX_RaySensor::PyGetHitPosition()
{
- return PyObjectFrom(m_hitPosition);
+ ShowDeprecationWarning("getHitPosition()", "the hitPosition property");
+
+ 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]));
+
+ return retVal;
}
const char KX_RaySensor::GetRayDirection_doc[] =
"getRayDirection()\n"
"\tReturns the direction from the ray (in worldcoordinates) .\n";
-PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self)
+PyObject* KX_RaySensor::PyGetRayDirection()
{
- return PyObjectFrom(m_rayDirection);
+ ShowDeprecationWarning("getRayDirection()", "the rayDirection property");
+
+ 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]));
+
+ return retVal;
}
const char KX_RaySensor::GetHitNormal_doc[] =
"getHitNormal()\n"
"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
-PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self)
+PyObject* KX_RaySensor::PyGetHitNormal()
{
- return PyObjectFrom(m_hitNormal);
+ ShowDeprecationWarning("getHitNormal()", "the hitNormal property");
+
+ 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]));
+
+ return retVal;
}
-PyObject* KX_RaySensor::_getattr(const char *attr) {
- _getattr_up(SCA_ISensor);
+PyObject* KX_RaySensor::py_getattro(PyObject *attr) {
+ py_getattro_up(SCA_ISensor);
}
+
+int KX_RaySensor::py_setattro(PyObject *attr, PyObject *value) {
+ py_setattro_up(SCA_ISensor);
+}
+
+// <----- Deprecated
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index 09d8bc1369a..a5d7d15c60c 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -44,15 +44,15 @@ class KX_RaySensor : public SCA_ISensor
STR_String m_propertyname;
bool m_bFindMaterial;
bool m_bXRay;
- double m_distance;
+ float m_distance;
class KX_Scene* m_scene;
bool m_bTriggered;
int m_axis;
bool m_rayHit;
- MT_Point3 m_hitPosition;
+ float m_hitPosition[3];
SCA_IObject* m_hitObject;
- MT_Vector3 m_hitNormal;
- MT_Vector3 m_rayDirection;
+ float m_hitNormal[3];
+ float m_rayDirection[3];
public:
KX_RaySensor(class SCA_EventManager* eventmgr,
@@ -73,13 +73,31 @@ public:
bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
bool NeedRayCast(KX_ClientObjectInfo* client);
+
+
+ //Python Interface
+ enum RayAxis {
+ KX_RAY_AXIS_POS_Y = 0,
+ KX_RAY_AXIS_POS_X,
+ KX_RAY_AXIS_POS_Z,
+ KX_RAY_AXIS_NEG_X,
+ KX_RAY_AXIS_NEG_Y,
+ KX_RAY_AXIS_NEG_Z
+ };
+
+
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+ // Deprecated ----->
KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitObject);
KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitPosition);
KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitNormal);
KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetRayDirection);
+ // <-----
- virtual PyObject* _getattr(const char *attr);
+ /* Attributes */
+ static PyObject* pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
};
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 68b704f4889..c45d89a2815 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -38,7 +38,6 @@
#include "SCA_IScene.h"
#include "KX_GameObject.h"
#include "KX_IPhysicsController.h"
-
#include "PyObjectPlus.h"
#ifdef HAVE_CONFIG_H
@@ -53,9 +52,9 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
SCA_IObject *original,
int time,
SCA_IScene* scene,
- const MT_Vector3& linvel,
+ const float *linvel,
bool linv_local,
- const MT_Vector3& angvel,
+ const float *angvel,
bool angv_local,
PyTypeObject* T)
:
@@ -63,12 +62,16 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
m_OriginalObject(original),
m_scene(scene),
- m_linear_velocity(linvel),
m_localLinvFlag(linv_local),
-
- m_angular_velocity(angvel),
m_localAngvFlag(angv_local)
{
+ m_linear_velocity[0] = linvel[0];
+ m_linear_velocity[1] = linvel[1];
+ m_linear_velocity[2] = linvel[2];
+ m_angular_velocity[0] = angvel[0];
+ m_angular_velocity[1] = angvel[1];
+ m_angular_velocity[2] = angvel[2];
+
if (m_OriginalObject)
m_OriginalObject->RegisterActuator(this);
@@ -163,31 +166,33 @@ void KX_SCA_AddObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_SCA_AddObjectActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SCA_AddObjectActuator",
- sizeof(KX_SCA_AddObjectActuator),
- 0,
- PyDestructor,
+ sizeof(PyObjectPlus_Proxy),
0,
- __getattr,
- __setattr,
- 0,
- __repr,
+ py_base_dealloc,
0,
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 KX_SCA_AddObjectActuator::Parents[] = {
+ &KX_SCA_AddObjectActuator::Type,
&SCA_IActuator::Type,
&SCA_ILogicBrick::Type,
&CValue::Type,
NULL
};
PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
+ // ---> deprecated
{"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, (PY_METHODCHAR)SetTime_doc},
{"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_NOARGS, (PY_METHODCHAR)GetTime_doc},
{"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_NOARGS, (PY_METHODCHAR)GetLinearVelocity_doc},
@@ -196,8 +201,6 @@ PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
{"setAngularVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetAngularVelocity, METH_VARARGS, (PY_METHODCHAR)SetAngularVelocity_doc},
{"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_NOARGS,"getLastCreatedObject() : get the object handle to the last created object\n"},
{"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_NOARGS,"instantAddObject() : immediately add object without delay\n"},
-
- // ---> deprecated
{"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
{"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
@@ -205,42 +208,60 @@ PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
};
PyAttributeDef KX_SCA_AddObjectActuator::Attributes[] = {
+ KX_PYATTRIBUTE_RW_FUNCTION("object",KX_SCA_AddObjectActuator,pyattr_get_object,pyattr_set_object),
+ KX_PYATTRIBUTE_RO_FUNCTION("objectLastCreated",KX_SCA_AddObjectActuator,pyattr_get_objectLastCreated),
+ KX_PYATTRIBUTE_INT_RW("time",0,2000,true,KX_SCA_AddObjectActuator,m_timeProp),
+ KX_PYATTRIBUTE_FLOAT_ARRAY_RW("linearVelocity",-FLT_MAX,FLT_MAX,KX_SCA_AddObjectActuator,m_linear_velocity,3),
+ KX_PYATTRIBUTE_FLOAT_ARRAY_RW("angularVelocity",-FLT_MAX,FLT_MAX,KX_SCA_AddObjectActuator,m_angular_velocity,3),
{ NULL } //Sentinel
};
-PyObject* KX_SCA_AddObjectActuator::_getattr(const char *attr)
+PyObject* KX_SCA_AddObjectActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
- if (!strcmp(attr, "object")) {
- if (!m_OriginalObject) Py_RETURN_NONE;
- else return m_OriginalObject->AddRef();
- } else if (!strcmp(attr, "objectLastCreated")) {
- if (!m_OriginalObject) Py_RETURN_NONE;
- else return m_lastCreatedObject->AddRef();
- }
-
- _getattr_up(SCA_IActuator);
+ KX_SCA_AddObjectActuator* actuator = static_cast<KX_SCA_AddObjectActuator*>(self);
+ if (!actuator->m_OriginalObject)
+ Py_RETURN_NONE;
+ else
+ return actuator->m_OriginalObject->GetProxy();
}
-int KX_SCA_AddObjectActuator::_setattr(const char *attr, PyObject* value) {
-
- if (!strcmp(attr, "object")) {
- KX_GameObject *gameobj;
+int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_SCA_AddObjectActuator* actuator = static_cast<KX_SCA_AddObjectActuator*>(self);
+ KX_GameObject *gameobj;
- if (!ConvertPythonToGameObject(value, &gameobj, true))
- return 1; // ConvertPythonToGameObject sets the error
+ if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SCA_AddObjectActuator"))
+ return 1; // ConvertPythonToGameObject sets the error
- if (m_OriginalObject != NULL)
- m_OriginalObject->UnregisterActuator(this);
+ if (actuator->m_OriginalObject != NULL)
+ actuator->m_OriginalObject->UnregisterActuator(actuator);
- m_OriginalObject = (SCA_IObject*)gameobj;
+ actuator->m_OriginalObject = (SCA_IObject*)gameobj;
- if (m_OriginalObject)
- m_OriginalObject->RegisterActuator(this);
+ if (actuator->m_OriginalObject)
+ actuator->m_OriginalObject->RegisterActuator(actuator);
- return 0;
- }
-
- return SCA_IActuator::_setattr(attr, value);
+ return 0;
+}
+
+PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SCA_AddObjectActuator* actuator = static_cast<KX_SCA_AddObjectActuator*>(self);
+ if (!actuator->m_lastCreatedObject)
+ Py_RETURN_NONE;
+ else
+ return actuator->m_lastCreatedObject->GetProxy();
+}
+
+
+PyObject* KX_SCA_AddObjectActuator::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_IActuator);
+}
+
+int KX_SCA_AddObjectActuator::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IActuator);
}
/* 1. setObject */
@@ -249,13 +270,13 @@ const char KX_SCA_AddObjectActuator::SetObject_doc[] =
"\t- object: KX_GameObject, string or None\n"
"\tSets the object that will be added. There has to be an object\n"
"\tof this name. If not, this function does nothing.\n";
-PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self, PyObject* value)
+PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* value)
{
KX_GameObject *gameobj;
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
if (m_OriginalObject != NULL)
@@ -278,8 +299,9 @@ const char KX_SCA_AddObjectActuator::SetTime_doc[] =
"\tIf the duration is negative, it is set to 0.\n";
-PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self, PyObject* value)
+PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* value)
{
+ ShowDeprecationWarning("setTime()", "the time property");
int deltatime = PyInt_AsLong(value);
if (deltatime==-1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "expected an int");
@@ -296,12 +318,13 @@ PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self, PyObject* value)
/* 3. getTime */
const char KX_SCA_AddObjectActuator::GetTime_doc[] =
-"GetTime()\n"
+"getTime()\n"
"\tReturns the lifetime of the object that will be added.\n";
-PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self)
+PyObject* KX_SCA_AddObjectActuator::PyGetTime()
{
+ ShowDeprecationWarning("getTime()", "the time property");
return PyInt_FromLong(m_timeProp);
}
@@ -311,13 +334,13 @@ const char KX_SCA_AddObjectActuator::GetObject_doc[] =
"getObject(name_only = 1)\n"
"name_only - optional arg, when true will return the KX_GameObject rather then its name\n"
"\tReturns the name of the object that will be added.\n";
-PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, PyObject* args)
+PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* args)
{
int ret_name_only = 1;
ShowDeprecationWarning("getObject()", "the object property");
- if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
+ if (!PyArg_ParseTuple(args, "|i:getObject", &ret_name_only))
return NULL;
if (!m_OriginalObject)
@@ -326,7 +349,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, PyObject* args)
if (ret_name_only)
return PyString_FromString(m_OriginalObject->GetName());
else
- return m_OriginalObject->AddRef();
+ return m_OriginalObject->GetProxy();
}
@@ -337,8 +360,9 @@ const char KX_SCA_AddObjectActuator::GetLinearVelocity_doc[] =
"\tReturns the linear velocity that will be assigned to \n"
"\tthe created object.\n";
-PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self)
+PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity()
{
+ ShowDeprecationWarning("getLinearVelocity()", "the linearVelocity property");
PyObject *retVal = PyList_New(3);
PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
@@ -359,14 +383,17 @@ const char KX_SCA_AddObjectActuator::SetLinearVelocity_doc[] =
"\t- local: bool\n"
"\tAssign this velocity to the created object. \n";
-PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self, PyObject* args)
+PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* args)
{
+ ShowDeprecationWarning("setLinearVelocity()", "the linearVelocity property");
float vecArg[3];
- if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2]))
+ if (!PyArg_ParseTuple(args, "fff:setLinearVelocity", &vecArg[0], &vecArg[1], &vecArg[2]))
return NULL;
- m_linear_velocity.setValue(vecArg);
+ m_linear_velocity[0] = vecArg[0];
+ m_linear_velocity[1] = vecArg[1];
+ m_linear_velocity[2] = vecArg[2];
Py_RETURN_NONE;
}
@@ -376,8 +403,9 @@ const char KX_SCA_AddObjectActuator::GetAngularVelocity_doc[] =
"\tReturns the angular velocity that will be assigned to \n"
"\tthe created object.\n";
-PyObject* KX_SCA_AddObjectActuator::PyGetAngularVelocity(PyObject* self)
+PyObject* KX_SCA_AddObjectActuator::PyGetAngularVelocity()
{
+ ShowDeprecationWarning("getAngularVelocity()", "the angularVelocity property");
PyObject *retVal = PyList_New(3);
PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
@@ -398,14 +426,17 @@ const char KX_SCA_AddObjectActuator::SetAngularVelocity_doc[] =
"\t- local: bool\n"
"\tAssign this angular velocity to the created object. \n";
-PyObject* KX_SCA_AddObjectActuator::PySetAngularVelocity(PyObject* self, PyObject* args)
+PyObject* KX_SCA_AddObjectActuator::PySetAngularVelocity(PyObject* args)
{
+ ShowDeprecationWarning("setAngularVelocity()", "the angularVelocity property");
float vecArg[3];
- if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2]))
+ if (!PyArg_ParseTuple(args, "fff:setAngularVelocity", &vecArg[0], &vecArg[1], &vecArg[2]))
return NULL;
- m_angular_velocity.setValue(vecArg);
+ m_angular_velocity[0] = vecArg[0];
+ m_angular_velocity[1] = vecArg[1];
+ m_angular_velocity[2] = vecArg[2];
Py_RETURN_NONE;
}
@@ -417,7 +448,7 @@ void KX_SCA_AddObjectActuator::InstantAddObject()
// Now it needs to be added to the current scene.
SCA_IObject* replica = m_scene->AddReplicaObject(m_OriginalObject,GetParent(),m_timeProp );
KX_GameObject * game_obj = static_cast<KX_GameObject *>(replica);
- game_obj->setLinearVelocity(m_linear_velocity,m_localLinvFlag);
+ game_obj->setLinearVelocity(m_linear_velocity ,m_localLinvFlag);
game_obj->setAngularVelocity(m_angular_velocity,m_localAngvFlag);
game_obj->ResolveCombinedVelocities(m_linear_velocity, m_angular_velocity, m_localLinvFlag, m_localAngvFlag);
@@ -436,7 +467,7 @@ void KX_SCA_AddObjectActuator::InstantAddObject()
}
}
-PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject(PyObject* self)
+PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject()
{
InstantAddObject();
@@ -451,16 +482,16 @@ const char KX_SCA_AddObjectActuator::GetLastCreatedObject_doc[] =
"\tReturn the last created object. \n";
-PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self)
+PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject()
{
+ ShowDeprecationWarning("getLastCreatedObject()", "the objectLastCreated property");
SCA_IObject* result = this->GetLastCreatedObject();
// if result->GetSGNode() is NULL
// it means the object has ended, The BGE python api crashes in many places if the object is returned.
if (result && (static_cast<KX_GameObject *>(result))->GetSGNode())
{
- result->AddRef();
- return result;
+ return result->GetProxy();
}
// don't return NULL to python anymore, it gives trouble in the scripts
Py_RETURN_NONE;
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 18298cbcb0c..4ece5a6d83b 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -59,12 +59,12 @@ class KX_SCA_AddObjectActuator : public SCA_IActuator
SCA_IScene* m_scene;
/// Linear velocity upon creation of the object.
- MT_Vector3 m_linear_velocity;
+ float m_linear_velocity[3];
/// Apply the velocity locally
bool m_localLinvFlag;
/// Angular velocity upon creation of the object.
- MT_Vector3 m_angular_velocity;
+ float m_angular_velocity[3];
/// Apply the velocity locally
bool m_localAngvFlag;
@@ -85,9 +85,9 @@ public:
SCA_IObject *original,
int time,
SCA_IScene* scene,
- const MT_Vector3& linvel,
+ const float *linvel,
bool linv_local,
- const MT_Vector3& angvel,
+ const float *angvel,
bool angv_local,
PyTypeObject* T=&Type
);
@@ -110,8 +110,8 @@ public:
virtual bool
Update();
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject* value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
SCA_IObject*
GetLastCreatedObject(
@@ -140,6 +140,9 @@ public:
/* 10. instantAddObject*/
KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,InstantAddObject);
+ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
}; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
index 394bb667728..83dfdc2484c 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
@@ -49,25 +49,23 @@
PyTypeObject
-KX_SCA_DynamicActuator::
-
-Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+KX_SCA_DynamicActuator::Type = {
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SCA_DynamicActuator",
- sizeof(KX_SCA_DynamicActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0,
- __repr,
- 0,
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 KX_SCA_DynamicActuator::Parents[] = {
@@ -80,21 +78,28 @@ PyParentObject KX_SCA_DynamicActuator::Parents[] = {
PyMethodDef KX_SCA_DynamicActuator::Methods[] = {
+ // ---> deprecated
KX_PYMETHODTABLE(KX_SCA_DynamicActuator, setOperation),
KX_PYMETHODTABLE(KX_SCA_DynamicActuator, getOperation),
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = {
+ KX_PYATTRIBUTE_SHORT_RW("operation",0,4,false,KX_SCA_DynamicActuator,m_dyn_operation),
+ KX_PYATTRIBUTE_FLOAT_RW("mass",0.0,FLT_MAX,KX_SCA_DynamicActuator,m_setmass),
{ NULL } //Sentinel
};
-PyObject* KX_SCA_DynamicActuator::_getattr(const char *attr)
+PyObject* KX_SCA_DynamicActuator::py_getattro(PyObject *attr)
{
- _getattr_up(SCA_IActuator);
+ py_getattro_up(SCA_IActuator);
}
+int KX_SCA_DynamicActuator::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IActuator);
+}
/* 1. setOperation */
@@ -107,9 +112,10 @@ 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");
int dyn_operation;
- if (!PyArg_ParseTuple(args, "i", &dyn_operation))
+ if (!PyArg_ParseTuple(args, "i:setOperation", &dyn_operation))
{
return NULL;
}
@@ -126,6 +132,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation,
"Returns the operation type of this actuator.\n"
)
{
+ ShowDeprecationWarning("getOperation()", "the operation property");
return PyInt_FromLong((long)m_dyn_operation);
}
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
index a82cddd66a7..99855124bdb 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
@@ -64,7 +64,18 @@ class KX_SCA_DynamicActuator : public SCA_IActuator
virtual bool
Update();
- virtual PyObject* _getattr(const char *attr);
+ //Python Interface
+ enum DynamicOperation {
+ KX_DYN_RESTORE_DYNAMICS = 0,
+ KX_DYN_DISABLE_DYNAMICS,
+ KX_DYN_ENABLE_RIGID_BODY,
+ KX_DYN_DISABLE_RIGID_BODY,
+ KX_DYN_SET_MASS,
+ };
+
+
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
/* 1. setOperation */
KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,setOperation);
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
index 9268a1df5f0..3b42577810e 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
@@ -94,22 +94,22 @@ CValue* KX_SCA_EndObjectActuator::GetReplica()
/* ------------------------------------------------------------------------- */
PyTypeObject KX_SCA_EndObjectActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SCA_EndObjectActuator",
- sizeof(KX_SCA_EndObjectActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -131,9 +131,9 @@ PyAttributeDef KX_SCA_EndObjectActuator::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* KX_SCA_EndObjectActuator::_getattr(const char *attr)
+PyObject* KX_SCA_EndObjectActuator::py_getattro(PyObject *attr)
{
- _getattr_up(SCA_IActuator);
+ py_getattro_up(SCA_IActuator);
}
/* eof */
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
index 12118743f0a..2940246f443 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
@@ -64,7 +64,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
}; /* 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 502990b2b27..38f8d581d55 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
@@ -36,6 +36,7 @@
// Please look here for revision history.
#include "KX_SCA_ReplaceMeshActuator.h"
+#include "KX_MeshProxy.h"
#include "PyObjectPlus.h"
@@ -51,28 +52,27 @@
PyTypeObject
-KX_SCA_ReplaceMeshActuator::
-
-Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+KX_SCA_ReplaceMeshActuator::Type = {
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SCA_ReplaceMeshActuator",
- sizeof(KX_SCA_ReplaceMeshActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0,
- __repr,
- 0,
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 KX_SCA_ReplaceMeshActuator::Parents[] = {
+ &KX_SCA_ReplaceMeshActuator::Type,
&SCA_IActuator::Type,
&SCA_ILogicBrick::Type,
&CValue::Type,
@@ -82,23 +82,48 @@ PyParentObject KX_SCA_ReplaceMeshActuator::Parents[] = {
PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = {
- {"setMesh", (PyCFunction) KX_SCA_ReplaceMeshActuator::sPySetMesh, METH_O, (PY_METHODCHAR)SetMesh_doc},
-
KX_PYMETHODTABLE(KX_SCA_ReplaceMeshActuator, instantReplaceMesh),
+ // Deprecated ----->
+ {"setMesh", (PyCFunction) KX_SCA_ReplaceMeshActuator::sPySetMesh, METH_O, (PY_METHODCHAR)SetMesh_doc},
KX_PYMETHODTABLE(KX_SCA_ReplaceMeshActuator, getMesh),
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_SCA_ReplaceMeshActuator::Attributes[] = {
+ KX_PYATTRIBUTE_RW_FUNCTION("mesh", KX_SCA_ReplaceMeshActuator, pyattr_get_mesh, pyattr_set_mesh),
{ NULL } //Sentinel
};
-PyObject* KX_SCA_ReplaceMeshActuator::_getattr(const char *attr)
+PyObject* KX_SCA_ReplaceMeshActuator::py_getattro(PyObject *attr)
{
- _getattr_up(SCA_IActuator);
+ py_getattro_up(SCA_IActuator);
}
+int KX_SCA_ReplaceMeshActuator::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IActuator);
+}
+
+PyObject* KX_SCA_ReplaceMeshActuator::pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SCA_ReplaceMeshActuator* actuator = static_cast<KX_SCA_ReplaceMeshActuator*>(self);
+ if (!actuator->m_mesh)
+ Py_RETURN_NONE;
+ KX_MeshProxy* meshproxy = new KX_MeshProxy(actuator->m_mesh);
+ return meshproxy->NewProxy(true);
+}
+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);
+ RAS_MeshObject* new_mesh;
+
+ if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator"))
+ return 1;
+
+ actuator->m_mesh = new_mesh;
+ return 0;
+}
/* 1. setMesh */
const char KX_SCA_ReplaceMeshActuator::SetMesh_doc[] =
@@ -106,25 +131,15 @@ const char KX_SCA_ReplaceMeshActuator::SetMesh_doc[] =
"\t- name: string or None\n"
"\tSet the mesh that will be substituted for the current one.\n";
-PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* self, PyObject* value)
+PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* value)
{
- if (value == Py_None) {
- 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;
- }
+ ShowDeprecationWarning("setMesh()", "the mesh property");
+ RAS_MeshObject* new_mesh;
+
+ if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator"))
+ return NULL;
+ m_mesh = new_mesh;
Py_RETURN_NONE;
}
@@ -133,6 +148,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, getMesh,
"Returns the name of the mesh to be substituted.\n"
)
{
+ ShowDeprecationWarning("getMesh()", "the mesh property");
if (!m_mesh)
Py_RETURN_NONE;
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
index 0ba60650683..7a18df2356d 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -69,9 +69,14 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
virtual bool
Update();
- virtual PyObject* _getattr(const char *attr);
void InstantReplaceMesh();
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
+
+ static PyObject* pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
/* 1. setMesh */
KX_PYMETHOD_DOC_O(KX_SCA_ReplaceMeshActuator,SetMesh);
KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,getMesh);
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
index 151270cbd68..0e7571031e8 100644
--- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
+++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
@@ -57,7 +57,8 @@ New(Bone* bone
KX_BoneParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
@@ -67,6 +68,8 @@ UpdateChildCoordinates(
const MT_Vector3 & child_scale = child->GetLocalScale();
const MT_Point3 & child_pos = child->GetLocalPosition();
const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
+ // we don't know if the armature has been updated or not, assume yes
+ parentUpdated = true;
// the childs world locations which we will update.
@@ -122,7 +125,7 @@ UpdateChildCoordinates(
else {
child->SetWorldFromLocalTransform();
}
-
+ child->SetModified(false);
return valid_parent_transform;
}
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
index 2a19d8a1784..c9baf228855 100644
--- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
+++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
@@ -82,7 +82,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
index 0729ec8a902..c3b0c21c8e0 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
@@ -51,13 +51,20 @@ New(
KX_NormalParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
+ if (!parentUpdated && !child->IsModified())
+ return false;
+
+ parentUpdated = true;
+
if (parent==NULL) { /* Simple case */
child->SetWorldFromLocalTransform();
- return false;
+ child->SetModified(false);
+ return true; //false;
}
else {
// the childs world locations which we will update.
@@ -68,6 +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);
return true;
}
}
@@ -112,10 +120,15 @@ New(
KX_VertexParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
+
+ if (!parentUpdated && !child->IsModified())
+ return false;
+
child->SetWorldScale(child->GetLocalScale());
if (parent)
@@ -124,7 +137,8 @@ UpdateChildCoordinates(
child->SetWorldPosition(child->GetLocalPosition());
child->SetWorldOrientation(child->GetLocalOrientation());
- return parent != NULL;
+ child->SetModified(false);
+ return true; //parent != NULL;
}
/**
@@ -172,10 +186,14 @@ New(
KX_SlowParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
+ // the child will move even if the parent is not
+ parentUpdated = true;
+
const MT_Vector3 & child_scale = child->GetLocalScale();
const MT_Point3 & child_pos = child->GetLocalPosition();
const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
@@ -217,23 +235,12 @@ UpdateChildCoordinates(
// now 'interpolate' the normal coordinates with the last
// world coordinates to get the new world coordinates.
- // problem 1:
- // The child world scale needs to be initialized in some way for this
- // to make sense
- // problem 2:
- // This is way of doing interpolation is nonsense
-
- int i;
-
MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
- for (i=0;i <3 ;i++) {
- child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
- child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
- child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
- child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
- child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
- }
-
+ child_w_scale = (m_relax * child_w_scale + child_n_scale) * weight;
+ child_w_pos = (m_relax * child_w_pos + child_n_pos) * weight;
+ // for rotation we must go through quaternion
+ MT_Quaternion child_w_quat = child_w_rotation.getRotation().slerp(child_n_rotation.getRotation(), weight);
+ child_w_rotation.setRotation(child_w_quat);
//FIXME: update physics controller.
} else {
child_w_scale = child_n_scale;
@@ -252,8 +259,9 @@ UpdateChildCoordinates(
child->SetWorldScale(child_w_scale);
child->SetWorldPosition(child_w_pos);
child->SetWorldOrientation(child_w_rotation);
+ child->SetModified(false);
- return parent != NULL;
+ return true; //parent != NULL;
}
/**
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
index faa650106c8..d8fb9211f21 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
@@ -71,7 +71,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
@@ -115,7 +116,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
@@ -166,7 +168,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 0fded15f1a1..aa7bd65f240 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -32,7 +32,6 @@
#pragma warning (disable : 4786)
#endif //WIN32
-
#include "KX_Scene.h"
#include "MT_assert.h"
@@ -77,7 +76,9 @@
#include "NG_NetworkScene.h"
#include "PHY_IPhysicsEnvironment.h"
#include "KX_IPhysicsController.h"
+#include "PHY_IGraphicController.h"
#include "KX_BlenderSceneConverter.h"
+#include "KX_MotionState.h"
#include "BL_ShapeDeformer.h"
#include "BL_DeformableGameObject.h"
@@ -90,6 +91,8 @@
#include "CcdPhysicsController.h"
#endif
+#include "KX_Light.h"
+
void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
{
KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
@@ -134,6 +137,8 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_suspendedtime = 0.0;
m_suspendeddelta = 0.0;
+ m_dbvt_culling = false;
+ m_dbvt_occlusion_res = 0;
m_activity_culling = false;
m_suspend = false;
m_isclearingZbuffer = true;
@@ -191,7 +196,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_canvasDesignWidth = 0;
m_canvasDesignHeight = 0;
- m_attrlist = PyDict_New(); /* new ref */
+ m_attr_dict = PyDict_New(); /* new ref */
}
@@ -245,7 +250,8 @@ KX_Scene::~KX_Scene()
{
delete m_bucketmanager;
}
- //Py_DECREF(m_attrlist);
+ PyDict_Clear(m_attr_dict);
+ Py_DECREF(m_attr_dict);
}
void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
@@ -408,6 +414,13 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam
// 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)
orgobj->SetSGNode(NULL);
+ PHY_IGraphicController* ctrl = orgobj->GetGraphicController();
+ if (ctrl)
+ {
+ // a graphic controller is set, we must delete it as the node will be deleted
+ delete ctrl;
+ orgobj->SetGraphicController(NULL);
+ }
}
if (node)
delete node;
@@ -486,7 +499,14 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
replicanode->AddSGController(replicacontroller);
}
}
-
+ // replicate graphic controller
+ if (orgobj->GetGraphicController())
+ {
+ PHY_IMotionState* motionstate = new KX_MotionState(newobj->GetSGNode());
+ PHY_IGraphicController* newctrl = orgobj->GetGraphicController()->GetReplica(motionstate);
+ newctrl->setNewClientInfo(newobj->getClientInfo());
+ newobj->SetGraphicController(newctrl);
+ }
return newobj;
}
@@ -698,9 +718,9 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
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());
+ newscale*(groupobj->NodeGetWorldOrientation() * (gameobj->NodeGetWorldPosition()-offset));
replica->NodeSetLocalPosition(newpos);
replica->GetSGNode()->UpdateWorldData(0);
@@ -725,6 +745,12 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
(*git)->Relink(&m_map_gameobject_to_replica);
// add the object in the layer of the parent
(*git)->SetLayer(groupobj->GetLayer());
+ // If the object was a light, we need to update it's RAS_LightObject as well
+ if ((*git)->IsLight())
+ {
+ KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
+ lightobj->GetLightData()->m_layer = groupobj->GetLayer();
+ }
}
// replicate crosslinks etc. between logic bricks
@@ -793,6 +819,24 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->AddChild(childreplicanode);
}
+ // At this stage all the objects in the hierarchy have been duplicated,
+ // we can update the scenegraph, we need it for the duplication of logic
+ MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
+ replica->NodeSetLocalPosition(newpos);
+
+ MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+
+ // get the rootnode's scale
+ MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
+
+ // set the replica's relative scale with the rootnode's scale
+ replica->NodeSetRelativeScale(newscale);
+
+ replica->GetSGNode()->UpdateWorldData(0);
+ replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
+ replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
+
// now replicate logic
vector<KX_GameObject*>::iterator git;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
@@ -807,6 +851,12 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
(*git)->Relink(&m_map_gameobject_to_replica);
// add the object in the layer of the parent
(*git)->SetLayer(parentobj->GetLayer());
+ // If the object was a light, we need to update it's RAS_LightObject as well
+ if ((*git)->IsLight())
+ {
+ KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
+ lightobj->GetLightData()->m_layer = parentobj->GetLayer();
+ }
}
// replicate crosslinks etc. between logic bricks
@@ -815,21 +865,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
ReplicateLogic((*git));
}
- MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
- replica->NodeSetLocalPosition(newpos);
-
- MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
- replica->NodeSetLocalOrientation(newori);
-
- // get the rootnode's scale
- MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
-
- // set the replica's relative scale with the rootnode's scale
- replica->NodeSetRelativeScale(newscale);
-
- replica->GetSGNode()->UpdateWorldData(0);
- replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
- replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
// check if there are objects with dupligroup in the hierarchy
vector<KX_GameObject*> duplilist;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
@@ -937,7 +972,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
newobj->RemoveMeshes();
ret = 1;
- if (m_lightlist->RemoveValue(newobj)) // TODO - use newobj->IsLight() test when its merged in from apricot. - Campbell
+ if (newobj->IsLight() && m_lightlist->RemoveValue(newobj))
ret = newobj->Release();
if (m_objectlist->RemoveValue(newobj))
ret = newobj->Release();
@@ -963,6 +998,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
if (m_sceneConverter)
m_sceneConverter->UnregisterGameObject(newobj);
// return value will be 0 if the object is actually deleted (all reference gone)
+
return ret;
}
@@ -1164,7 +1200,6 @@ void KX_Scene::UpdateMeshTransformations()
{
KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
gameobj->GetOpenGLMatrix();
-// gameobj->UpdateNonDynas();
}
}
@@ -1299,21 +1334,47 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
}
}
+void KX_Scene::PhysicsCullingCallback(KX_ClientObjectInfo* objectInfo, void* cullingInfo)
+{
+ KX_GameObject* gameobj = objectInfo->m_gameobject;
+ if (!gameobj->GetVisible())
+ // ideally, invisible objects should be removed from the culling tree temporarily
+ return;
+ if(((CullingInfo*)cullingInfo)->m_layer && !(gameobj->GetLayer() & ((CullingInfo*)cullingInfo)->m_layer))
+ // used for shadow: object is not in shadow layer
+ return;
+
+ // make object visible
+ gameobj->SetCulled(false);
+ gameobj->UpdateBuckets(false);
+}
+
void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer)
{
-// FIXME: When tree is operational
-#if 1
- // do this incrementally in the future
- for (int i = 0; i < m_objectlist->GetCount(); i++)
+ bool dbvt_culling = false;
+ if (m_dbvt_culling)
{
- MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
+ // test culling through Bullet
+ PHY__Vector4 planes[6];
+ // get the clip planes
+ MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
+ // and convert
+ planes[0].setValue(cplanes[4].getValue()); // near
+ planes[1].setValue(cplanes[5].getValue()); // far
+ planes[2].setValue(cplanes[0].getValue()); // left
+ planes[3].setValue(cplanes[1].getValue()); // right
+ planes[4].setValue(cplanes[2].getValue()); // top
+ planes[5].setValue(cplanes[3].getValue()); // bottom
+ CullingInfo info(layer);
+ dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res);
+ }
+ if (!dbvt_culling) {
+ // the physics engine couldn't help us, do it the hard way
+ for (int i = 0; i < m_objectlist->GetCount(); i++)
+ {
+ MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
+ }
}
-#else
- if (cam->GetFrustumCulling())
- MarkVisible(m_objecttree, rasty, cam, layer);
- else
- MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer);
-#endif
}
// logic stuff
@@ -1394,7 +1455,7 @@ void KX_Scene::UpdateParents(double curtime)
for (int i=0; i<GetRootParentList()->GetCount(); i++)
{
KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
- parentobj->NodeUpdateGS(curtime,true);
+ parentobj->NodeUpdateGS(curtime);
}
}
@@ -1518,22 +1579,22 @@ double KX_Scene::getSuspendedDelta()
//Python
PyTypeObject KX_Scene::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_Scene",
- sizeof(KX_Scene),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
0,
0,
0,
- 0, 0, 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 KX_Scene::Parents[] = {
@@ -1551,52 +1612,102 @@ PyMethodDef KX_Scene::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self= static_cast<KX_Scene*>(self_v);
+ return PyString_FromString(self->GetName().ReadPtr());
+}
+
+PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self= static_cast<KX_Scene*>(self_v);
+ return self->GetObjectList()->GetProxy();
+}
+
+PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self= static_cast<KX_Scene*>(self_v);
+ 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<KX_Scene*>(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),
+ 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_RO_FUNCTION("__dict__", KX_Scene, pyattr_get_dir_dict),
{ NULL } //Sentinel
};
-PyObject* KX_Scene::_getattr(const char *attr)
+
+PyObject* KX_Scene::py_getattro__internal(PyObject *attr)
+{
+ py_getattro_up(PyObjectPlus);
+}
+
+int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *pyvalue)
{
- if (!strcmp(attr, "name"))
- return PyString_FromString(GetName());
-
- if (!strcmp(attr, "objects"))
- return (PyObject*) m_objectlist->AddRef();
-
- if (!strcmp(attr, "active_camera"))
- return (PyObject*) GetActiveCamera()->AddRef();
-
- if (!strcmp(attr, "suspended"))
- return PyInt_FromLong(m_suspend);
-
- if (!strcmp(attr, "activity_culling"))
- return PyInt_FromLong(m_activity_culling);
-
- if (!strcmp(attr, "activity_culling_radius"))
- return PyFloat_FromDouble(m_activity_box_radius);
+ return PyObjectPlus::py_setattro(attr, pyvalue);
+}
+
+PyObject* KX_Scene::py_getattro(PyObject *attr)
+{
+ PyObject *object = py_getattro__internal(attr);
- PyObject* value = PyDict_GetItemString(m_attrlist, attr);
- if (value)
+ if (object==NULL)
{
- Py_INCREF(value);
- return value;
+ PyErr_Clear();
+ object = PyDict_GetItem(m_attr_dict, attr);
+ if(object) {
+ Py_INCREF(object);
+ }
+ else {
+ PyErr_Format(PyExc_AttributeError, "value = scene.myAttr: KX_Scene, attribute \"%s\" not found", PyString_AsString(attr));
+ }
}
- _getattr_up(PyObjectPlus);
+ return object;
}
-int KX_Scene::_delattr(const char *attr)
+
+int KX_Scene::py_setattro(PyObject *attr, PyObject *value)
{
- PyDict_DelItemString(m_attrlist, attr);
- return 0;
+ int ret= py_setattro__internal(attr, value);
+
+ if (ret==PY_SET_ATTR_MISSING) {
+ if (PyDict_SetItem(m_attr_dict, attr, value)==0) {
+ PyErr_Clear();
+ ret= PY_SET_ATTR_SUCCESS;
+ }
+ else {
+ PyErr_SetString(PyExc_AttributeError, "scene.UserAttr = value: KX_Scenes, failed assigning value to internal dictionary");
+ ret= PY_SET_ATTR_FAIL;
+ }
+ }
+
+ return ret;
}
-int KX_Scene::_setattr(const char *attr, PyObject *pyvalue)
+int KX_Scene::py_delattro(PyObject *attr)
{
- if (!PyDict_SetItemString(m_attrlist, attr, pyvalue))
- return 0;
-
- return PyObjectPlus::_setattr(attr, pyvalue);
+ PyDict_DelItem(m_attr_dict, attr);
+ return 0;
}
KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
@@ -1604,7 +1715,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
"Returns a list of all lights in the scene.\n"
)
{
- return (PyObject*) m_lightlist->AddRef();
+ return m_lightlist->GetProxy();
}
KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList,
@@ -1613,7 +1724,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList,
)
{
// ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work?
- return (PyObject*) m_objectlist->AddRef();
+ return m_objectlist->GetProxy();
}
KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName,
@@ -1633,15 +1744,14 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject,
int time = 0;
- if (!PyArg_ParseTuple(args, "OO|i", &pyob, &pyother, &time))
+ if (!PyArg_ParseTuple(args, "OO|i:addObject", &pyob, &pyother, &time))
return NULL;
- if (!ConvertPythonToGameObject(pyob, &ob, false)
- || !ConvertPythonToGameObject(pyother, &other, false))
+ if ( !ConvertPythonToGameObject(pyob, &ob, false, "scene.addObject(object, other, time): KX_Scene (first argument)") ||
+ !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") )
return NULL;
SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
- replica->AddRef();
- return replica;
+ return replica->GetProxy();
} \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 962db1a9b96..a06c66ec5dd 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -85,6 +85,8 @@ class RAS_IRenderTools;
class SCA_JoystickManager;
class btCollisionShape;
class KX_BlenderSceneConverter;
+struct KX_ClientObjectInfo;
+
/**
* The KX_Scene holds all data for an independent scene. It relates
* KX_Objects to the specific objects in the modules.
@@ -92,6 +94,12 @@ class KX_BlenderSceneConverter;
class KX_Scene : public PyObjectPlus, public SCA_IScene
{
Py_Header;
+
+ struct CullingInfo {
+ int m_layer;
+ CullingInfo(int layer) : m_layer(layer) {}
+ };
+
protected:
RAS_BucketManager* m_bucketmanager;
CListValue* m_tempObjectList;
@@ -252,6 +260,16 @@ protected:
bool m_activity_culling;
/**
+ * Toggle to enable or disable culling via DBVT broadphase of Bullet.
+ */
+ bool m_dbvt_culling;
+
+ /**
+ * Occlusion culling resolution
+ */
+ int m_dbvt_occlusion_res;
+
+ /**
* The framing settings used by this scene
*/
@@ -269,6 +287,7 @@ protected:
void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam,int layer=0);
void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam,int layer=0);
void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam, int layer=0);
+ static void PhysicsCullingCallback(KX_ClientObjectInfo* objectInfo, void* cullingInfo);
double m_suspendedtime;
double m_suspendeddelta;
@@ -276,7 +295,7 @@ protected:
/**
* This stores anything from python
*/
- PyObject* m_attrlist;
+ PyObject* m_attr_dict;
struct Scene* m_blenderScene;
@@ -530,6 +549,11 @@ public:
bool IsSuspended();
bool IsClearingZBuffer();
void EnableZBufferClearing(bool isclearingZbuffer);
+ // use of DBVT tree for camera culling
+ void SetDbvtCulling(bool b) { m_dbvt_culling = b; };
+ bool GetDbvtCulling() { return m_dbvt_culling; };
+ void SetDbvtOcclusionRes(int i) { m_dbvt_occlusion_res = i; };
+ int GetDbvtOcclusionRes() { return m_dbvt_occlusion_res; };
void SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter);
@@ -565,11 +589,22 @@ public:
KX_PYMETHOD_DOC(KX_Scene, setSceneViewport);
*/
- virtual PyObject* _getattr(const char *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
- virtual int _setattr(const char *attr, PyObject *pyvalue);
- virtual int _delattr(const char *attr);
- virtual PyObject* _repr(void) { return PyString_FromString(GetName().ReadPtr()); }
+ /* 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_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 int py_setattro(PyObject *attr, PyObject *pyvalue);
+ virtual int py_delattro(PyObject *attr);
+ virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); }
+ PyObject* py_getattro__internal(PyObject *attr);
+ int py_setattro__internal(PyObject *attr, PyObject *pyvalue);
/**
* Sets the time the scene was suspended
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp
index 1cad4e21352..f54d8542260 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp
@@ -226,22 +226,22 @@ KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_SceneActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SceneActuator",
- sizeof(KX_SceneActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -259,24 +259,93 @@ PyParentObject KX_SceneActuator::Parents[] =
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},
- {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_VARARGS, (PY_METHODCHAR)GetUseRestart_doc},
- {"getScene", (PyCFunction) KX_SceneActuator::sPyGetScene, METH_VARARGS, (PY_METHODCHAR)GetScene_doc},
- {"getCamera", (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_VARARGS, (PY_METHODCHAR)GetCamera_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},
+ //<----- Deprecated
{NULL,NULL} //Sentinel
};
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),
{ NULL } //Sentinel
};
-PyObject* KX_SceneActuator::_getattr(const char *attr)
+PyObject* KX_SceneActuator::py_getattro(PyObject *attr)
{
- _getattr_up(SCA_IActuator);
+ py_getattro_up(SCA_IActuator);
}
+int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(SCA_IActuator);
+}
+
+PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
+ if (!actuator->m_camera)
+ Py_RETURN_NONE;
+
+ return actuator->m_camera->GetProxy();
+}
+
+int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
+ KX_Camera *camOb;
+
+ if(value==Py_None)
+ {
+ if (actuator->m_camera)
+ actuator->m_camera->UnregisterActuator(actuator);
+
+ actuator->m_camera= NULL;
+ return 0;
+ }
+
+ if (PyObject_TypeCheck(value, &KX_Camera::Type))
+ {
+ KX_Camera *camOb= static_cast<KX_Camera*>BGE_PROXY_REF(value);
+
+ if(camOb==NULL)
+ {
+ PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
+ return 1;
+ }
+
+ if (actuator->m_camera)
+ actuator->m_camera->UnregisterActuator(actuator);
+
+ 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;
+}
/* 2. setUseRestart--------------------------------------------------------- */
@@ -284,13 +353,12 @@ const char KX_SceneActuator::SetUseRestart_doc[] =
"setUseRestart(flag)\n"
"\t- flag: 0 or 1.\n"
"\tSet flag to 1 to restart the scene.\n" ;
-PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
{
+ ShowDeprecationWarning("setUseRestart()", "(no replacement)");
int boolArg;
- if (!PyArg_ParseTuple(args, "i", &boolArg))
+ if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
{
return NULL;
}
@@ -306,10 +374,9 @@ PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self,
const char KX_SceneActuator::GetUseRestart_doc[] =
"getUseRestart()\n"
"\tReturn whether the scene will be restarted.\n" ;
-PyObject* KX_SceneActuator::PyGetUseRestart(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_SceneActuator::PyGetUseRestart()
{
+ ShowDeprecationWarning("getUseRestart()", "(no replacement)");
return PyInt_FromLong(!(m_restart == 0));
}
@@ -320,14 +387,13 @@ const char KX_SceneActuator::SetScene_doc[] =
"setScene(scene)\n"
"\t- scene: string\n"
"\tSet the name of scene the actuator will switch to.\n" ;
-PyObject* KX_SceneActuator::PySetScene(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_SceneActuator::PySetScene(PyObject* args)
{
+ ShowDeprecationWarning("setScene()", "the scene property");
/* one argument: a scene, ignore the rest */
char *scene_name;
- if(!PyArg_ParseTuple(args, "s", &scene_name))
+ if(!PyArg_ParseTuple(args, "s:setScene", &scene_name))
{
return NULL;
}
@@ -344,10 +410,9 @@ PyObject* KX_SceneActuator::PySetScene(PyObject* self,
const char KX_SceneActuator::GetScene_doc[] =
"getScene()\n"
"\tReturn the name of the scene the actuator wants to switch to.\n" ;
-PyObject* KX_SceneActuator::PyGetScene(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_SceneActuator::PyGetScene()
{
+ ShowDeprecationWarning("getScene()", "the scene property");
return PyString_FromString(m_nextSceneName);
}
@@ -358,25 +423,34 @@ 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* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_SceneActuator::PySetCamera(PyObject* args)
{
+ ShowDeprecationWarning("setCamera()", "the camera property");
PyObject *cam;
- if (PyArg_ParseTuple(args, "O!", &KX_Camera::Type, &cam))
+ if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam))
{
+ KX_Camera *new_camera;
+
+ new_camera = static_cast<KX_Camera*>BGE_PROXY_REF(cam);
+ if(new_camera==NULL)
+ {
+ PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
if (m_camera)
m_camera->UnregisterActuator(this);
- m_camera = (KX_Camera*) cam;
- if (m_camera)
- m_camera->RegisterActuator(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", &camName))
+ if(!PyArg_ParseTuple(args, "s:setCamera", &camName))
{
return NULL;
}
@@ -399,10 +473,14 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
const char KX_SceneActuator::GetCamera_doc[] =
"getCamera()\n"
"\tReturn the name of the camera to switch to.\n" ;
-PyObject* KX_SceneActuator::PyGetCamera(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_SceneActuator::PyGetCamera()
{
- return PyString_FromString(m_camera->GetName());
+ ShowDeprecationWarning("getCamera()", "the camera property");
+ if (m_camera) {
+ return PyString_FromString(m_camera->GetName());
+ }
+ else {
+ Py_RETURN_NONE;
+ }
}
/* eof */
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index af11af955bf..803c5106a60 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -92,24 +92,28 @@ class KX_SceneActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
/* 1. set */
/* Removed */
/* 2. setUseRestart: */
- KX_PYMETHOD_DOC(KX_SceneActuator,SetUseRestart);
+ KX_PYMETHOD_DOC_VARARGS(KX_SceneActuator,SetUseRestart);
/* 3. getUseRestart: */
- KX_PYMETHOD_DOC(KX_SceneActuator,GetUseRestart);
+ KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetUseRestart);
/* 4. setScene: */
- KX_PYMETHOD_DOC(KX_SceneActuator,SetScene);
+ KX_PYMETHOD_DOC_VARARGS(KX_SceneActuator,SetScene);
/* 5. getScene: */
- KX_PYMETHOD_DOC(KX_SceneActuator,GetScene);
+ KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetScene);
/* 6. setCamera: */
- KX_PYMETHOD_DOC(KX_SceneActuator,SetCamera);
+ KX_PYMETHOD_DOC_VARARGS(KX_SceneActuator,SetCamera);
/* 7. getCamera: */
- KX_PYMETHOD_DOC(KX_SceneActuator,GetCamera);
+ KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetCamera);
+ static PyObject* pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
}; /* end of class KXSceneActuator */
#endif
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 6de1d67bfdb..412be497c5a 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -35,6 +35,7 @@
#include "KX_GameObject.h"
#include "SND_SoundObject.h"
#include "SND_Scene.h" // needed for replication
+#include "KX_PyMath.h" // needed for PyObjectFrom()
#include <iostream>
#ifdef HAVE_CONFIG_H
@@ -233,22 +234,22 @@ void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_SoundActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_SoundActuator",
- sizeof(KX_SoundActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -264,104 +265,328 @@ PyParentObject KX_SoundActuator::Parents[] = {
PyMethodDef KX_SoundActuator::Methods[] = {
+ // Deprecated ----->
{"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL},
- {"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_VARARGS,NULL},
- {"startSound",(PyCFunction) KX_SoundActuator::sPyStartSound,METH_VARARGS,NULL},
- {"pauseSound",(PyCFunction) KX_SoundActuator::sPyPauseSound,METH_VARARGS,NULL},
- {"stopSound",(PyCFunction) KX_SoundActuator::sPyStopSound,METH_VARARGS,NULL},
+ {"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_NOARGS,NULL},
{"setGain",(PyCFunction) KX_SoundActuator::sPySetGain,METH_VARARGS,NULL},
- {"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_VARARGS,NULL},
+ {"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_NOARGS,NULL},
{"setPitch",(PyCFunction) KX_SoundActuator::sPySetPitch,METH_VARARGS,NULL},
- {"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_VARARGS,NULL},
+ {"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_NOARGS,NULL},
{"setRollOffFactor",(PyCFunction) KX_SoundActuator::sPySetRollOffFactor,METH_VARARGS,NULL},
- {"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_VARARGS,NULL},
+ {"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_NOARGS,NULL},
{"setLooping",(PyCFunction) KX_SoundActuator::sPySetLooping,METH_VARARGS,NULL},
- {"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_VARARGS,NULL},
+ {"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_NOARGS,NULL},
{"setPosition",(PyCFunction) KX_SoundActuator::sPySetPosition,METH_VARARGS,NULL},
{"setVelocity",(PyCFunction) KX_SoundActuator::sPySetVelocity,METH_VARARGS,NULL},
{"setOrientation",(PyCFunction) KX_SoundActuator::sPySetOrientation,METH_VARARGS,NULL},
{"setType",(PyCFunction) KX_SoundActuator::sPySetType,METH_VARARGS,NULL},
- {"getType",(PyCFunction) KX_SoundActuator::sPyGetType,METH_VARARGS,NULL},
+ {"getType",(PyCFunction) KX_SoundActuator::sPyGetType,METH_NOARGS,NULL},
+ // <-----
+
+ KX_PYMETHODTABLE_NOARGS(KX_SoundActuator, startSound),
+ KX_PYMETHODTABLE_NOARGS(KX_SoundActuator, pauseSound),
+ KX_PYMETHODTABLE_NOARGS(KX_SoundActuator, stopSound),
{NULL,NULL,NULL,NULL} //Sentinel
};
PyAttributeDef KX_SoundActuator::Attributes[] = {
+ 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),
+ KX_PYATTRIBUTE_RW_FUNCTION("looping", KX_SoundActuator, pyattr_get_looping, pyattr_set_looping),
+ 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),
{ NULL } //Sentinel
};
-PyObject* KX_SoundActuator::_getattr(const char *attr)
+/* Methods ----------------------------------------------------------------- */
+KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, startSound,
+"startSound()\n"
+"\tStarts the sound.\n")
{
- _getattr_up(SCA_IActuator);
-}
-
-
+ if (m_soundObject)
+ // This has no effect if the actuator is not active.
+ // To start the sound you must activate the actuator.
+ // This function is to restart the sound.
+ m_soundObject->StartSound();
+ Py_RETURN_NONE;
+}
-PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObject* kwds)
+KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, pauseSound,
+"pauseSound()\n"
+"\tPauses the sound.\n")
{
- char *soundName = NULL;
- // void *soundPointer = NULL; /*unused*/
-
- if (!PyArg_ParseTuple(args, "s", &soundName))
- return NULL;
+ if (m_soundObject)
+ // unfortunately, openal does not implement pause correctly, it is equivalent to a stop
+ m_soundObject->PauseSound();
+ Py_RETURN_NONE;
+}
+KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound,
+"stopSound()\n"
+"\tStops the sound.\n")
+{
+ if (m_soundObject)
+ m_soundObject->StopSound();
Py_RETURN_NONE;
}
+/* Atribute setting and getting -------------------------------------------- */
+PyObject* KX_SoundActuator::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_IActuator);
+}
+int KX_SoundActuator::py_setattro(PyObject *attr, PyObject* value) {
+ py_setattro_up(SCA_IActuator);
+}
-PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
- if (!m_soundObject)
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ if (!actuator->m_soundObject)
{
return PyString_FromString("");
}
- STR_String objectname = m_soundObject->GetObjectName();
+ STR_String objectname = actuator->m_soundObject->GetObjectName();
char* name = objectname.Ptr();
if (!name) {
- PyErr_SetString(PyExc_RuntimeError, "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);
}
+PyObject* KX_SoundActuator::pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ float gain = (actuator->m_soundObject) ? actuator->m_soundObject->GetGain() : 1.0f;
+ PyObject* result = PyFloat_FromDouble(gain);
+
+ return result;
+}
-PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
- if (m_soundObject)
- // This has no effect if the actuator is not active.
- // To start the sound you must activate the actuator.
- // This function is to restart the sound.
- m_soundObject->StartSound();
- Py_RETURN_NONE;
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ float pitch = (actuator->m_soundObject) ? actuator->m_soundObject->GetPitch() : 1.0;
+ PyObject* result = PyFloat_FromDouble(pitch);
+
+ return result;
+}
+
+PyObject* KX_SoundActuator::pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ float rollofffactor = (actuator->m_soundObject) ? actuator->m_soundObject->GetRollOffFactor() : 1.0;
+ PyObject* result = PyFloat_FromDouble(rollofffactor);
+
+ return result;
+}
+
+PyObject* KX_SoundActuator::pyattr_get_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ int looping = (actuator->m_soundObject) ? actuator->m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
+ PyObject* result = PyInt_FromLong(looping);
+
+ return result;
+}
+
+PyObject* KX_SoundActuator::pyattr_get_position(void * self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ MT_Vector3 pos(0.0, 0.0, 0.0);
+
+ if (actuator->m_soundObject)
+ pos = actuator->m_soundObject->GetPosition();
+
+ PyObject * result = PyObjectFrom(pos);
+ return result;
+}
+
+PyObject* KX_SoundActuator::pyattr_get_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ MT_Vector3 vel;
+
+ if (actuator->m_soundObject)
+ vel = actuator->m_soundObject->GetVelocity();
+
+ PyObject * result = PyObjectFrom(vel);
+ return result;
+}
+
+PyObject* KX_SoundActuator::pyattr_get_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ MT_Matrix3x3 ori;
+
+ if (actuator->m_soundObject)
+ ori = actuator->m_soundObject->GetOrientation();
+
+ PyObject * result = PyObjectFrom(ori);
+ return result;
+}
+
+int KX_SoundActuator::pyattr_set_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ char *soundName = NULL;
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator*> (self);
+ // void *soundPointer = NULL; /*unused*/
+
+ if (!PyArg_Parse(value, "s", &soundName))
+ return 1;
+
+ if (actuator->m_soundObject) {
+ actuator->m_soundObject->SetObjectName(soundName);
+ }
+
+ return 0;
+}
+
+
+int KX_SoundActuator::pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ float gain = 1.0;
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ if (!PyArg_Parse(value, "f", &gain))
+ return 1;
+
+ if (actuator->m_soundObject)
+ actuator->m_soundObject->SetGain(gain);
+
+ return 0;
}
+int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ float pitch = 1.0;
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ if (!PyArg_Parse(value, "f", &pitch))
+ return 1;
+
+ if (actuator->m_soundObject)
+ actuator->m_soundObject->SetPitch(pitch);
+
+ return 0;
+}
+int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ float rollofffactor = 1.0;
+ if (!PyArg_Parse(value, "f", &rollofffactor))
+ return 1;
+
+ if (actuator->m_soundObject)
+ actuator->m_soundObject->SetRollOffFactor(rollofffactor);
-PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds)
+ return 0;
+}
+
+int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
- if (m_soundObject)
- // unfortunately, openal does not implement pause correctly, it is equivalent to a stop
- m_soundObject->PauseSound();
- Py_RETURN_NONE;
-}
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+ int looping = 1;
+ if (!PyArg_Parse(value, "i", &looping))
+ return 1;
+
+ if (actuator->m_soundObject)
+ actuator->m_soundObject->SetLoopMode(looping);
+
+ return 0;
+}
+int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ float pos[3];
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
-PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject* kwds)
+ if (!PyArg_ParseTuple(value, "fff", &pos[0], &pos[1], &pos[2]))
+ return 1;
+
+ if (actuator->m_soundObject)
+ actuator->m_soundObject->SetPosition(MT_Vector3(pos));
+
+ return 0;
+}
+
+int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
- if (m_soundObject)
- m_soundObject->StopSound();
- Py_RETURN_NONE;
+ float vel[3];
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+
+
+ if (!PyArg_ParseTuple(value, "fff", &vel[0], &vel[1], &vel[2]))
+ return 1;
+
+ if (actuator->m_soundObject)
+ actuator->m_soundObject->SetVelocity(MT_Vector3(vel));
+
+ return 0;
+
+}
+
+int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+
+ MT_Matrix3x3 rot;
+ KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+
+ /* if value is not a sequence PyOrientationTo makes an error */
+ if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator"))
+ return NULL;
+
+ 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 */
+
+ actuator->m_soundObject->SetOrientation(rot);
+ return 0;
}
+// Deprecated ----->
+PyObject* KX_SoundActuator::PySetFilename(PyObject* args)
+{
+ char *soundName = NULL;
+ ShowDeprecationWarning("setFilename()", "the filename property");
+ // void *soundPointer = NULL; /*unused*/
+
+ if (!PyArg_ParseTuple(args, "s", &soundName))
+ return NULL;
+ Py_RETURN_NONE;
+}
-PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PyGetFilename()
{
+ ShowDeprecationWarning("getFilename()", "the filename property");
+ if (!m_soundObject)
+ {
+ return PyString_FromString("");
+ }
+ STR_String objectname = m_soundObject->GetObjectName();
+ char* name = objectname.Ptr();
+
+ if (!name) {
+ PyErr_SetString(PyExc_RuntimeError, "Unable to get sound filename");
+ return NULL;
+ } else
+ return PyString_FromString(name);
+}
+
+PyObject* KX_SoundActuator::PySetGain(PyObject* args)
+{
+ ShowDeprecationWarning("setGain()", "the volume property");
float gain = 1.0;
- if (!PyArg_ParseTuple(args, "f", &gain))
+ if (!PyArg_ParseTuple(args, "f:setGain", &gain))
return NULL;
if (m_soundObject)
@@ -372,8 +597,9 @@ PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject*
-PyObject* KX_SoundActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PyGetGain()
{
+ ShowDeprecationWarning("getGain()", "the volume property");
float gain = (m_soundObject) ? m_soundObject->GetGain() : 1.0f;
PyObject* result = PyFloat_FromDouble(gain);
@@ -382,10 +608,11 @@ PyObject* KX_SoundActuator::PyGetGain(PyObject* self, PyObject* args, PyObject*
-PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetPitch(PyObject* args)
{
+ ShowDeprecationWarning("setPitch()", "the pitch property");
float pitch = 1.0;
- if (!PyArg_ParseTuple(args, "f", &pitch))
+ if (!PyArg_ParseTuple(args, "f:setPitch", &pitch))
return NULL;
if (m_soundObject)
@@ -396,8 +623,9 @@ PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject*
-PyObject* KX_SoundActuator::PyGetPitch(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PyGetPitch()
{
+ ShowDeprecationWarning("getPitch()", "the pitch property");
float pitch = (m_soundObject) ? m_soundObject->GetPitch() : 1.0;
PyObject* result = PyFloat_FromDouble(pitch);
@@ -406,10 +634,11 @@ PyObject* KX_SoundActuator::PyGetPitch(PyObject* self, PyObject* args, PyObject*
-PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* args)
{
+ ShowDeprecationWarning("setRollOffFactor()", "the rollOffFactor property");
float rollofffactor = 1.0;
- if (!PyArg_ParseTuple(args, "f", &rollofffactor))
+ if (!PyArg_ParseTuple(args, "f:setRollOffFactor", &rollofffactor))
return NULL;
if (m_soundObject)
@@ -420,8 +649,9 @@ PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, P
-PyObject* KX_SoundActuator::PyGetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PyGetRollOffFactor()
{
+ ShowDeprecationWarning("getRollOffFactor()", "the rollOffFactor property");
float rollofffactor = (m_soundObject) ? m_soundObject->GetRollOffFactor() : 1.0;
PyObject* result = PyFloat_FromDouble(rollofffactor);
@@ -430,10 +660,11 @@ PyObject* KX_SoundActuator::PyGetRollOffFactor(PyObject* self, PyObject* args, P
-PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetLooping(PyObject* args)
{
+ ShowDeprecationWarning("setLooping()", "the looping property");
bool looping = 1;
- if (!PyArg_ParseTuple(args, "i", &looping))
+ if (!PyArg_ParseTuple(args, "i:setLooping", &looping))
return NULL;
if (m_soundObject)
@@ -444,8 +675,9 @@ PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObjec
-PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PyGetLooping()
{
+ ShowDeprecationWarning("getLooping()", "the looping property");
int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
PyObject* result = PyInt_FromLong(looping);
@@ -454,14 +686,15 @@ PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObjec
-PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetPosition(PyObject* args)
{
MT_Point3 pos;
+ ShowDeprecationWarning("setPosition()", "the position property");
pos[0] = 0.0;
pos[1] = 0.0;
pos[2] = 0.0;
- if (!PyArg_ParseTuple(args, "fff", &pos[0], &pos[1], &pos[2]))
+ if (!PyArg_ParseTuple(args, "fff:setPosition", &pos[0], &pos[1], &pos[2]))
return NULL;
if (m_soundObject)
@@ -472,14 +705,15 @@ PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObje
-PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetVelocity(PyObject* args)
{
MT_Vector3 vel;
+ ShowDeprecationWarning("setVelocity()", "the velocity property");
vel[0] = 0.0;
vel[1] = 0.0;
vel[2] = 0.0;
- if (!PyArg_ParseTuple(args, "fff", &vel[0], &vel[1], &vel[2]))
+ if (!PyArg_ParseTuple(args, "fff:setVelocity", &vel[0], &vel[1], &vel[2]))
return NULL;
if (m_soundObject)
@@ -490,9 +724,10 @@ PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObje
-PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetOrientation(PyObject* args)
{
MT_Matrix3x3 ori;
+ ShowDeprecationWarning("setOrientation()", "the orientation property");
ori[0][0] = 1.0;
ori[0][1] = 0.0;
ori[0][2] = 0.0;
@@ -503,7 +738,7 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyO
ori[2][1] = 0.0;
ori[2][2] = 1.0;
- if (!PyArg_ParseTuple(args, "fffffffff", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
+ if (!PyArg_ParseTuple(args, "fffffffff:setOrientation", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
return NULL;
if (m_soundObject)
@@ -512,11 +747,12 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyO
Py_RETURN_NONE;
}
-PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PySetType(PyObject* args)
{
int typeArg;
+ ShowDeprecationWarning("setType()", "the type property");
- if (!PyArg_ParseTuple(args, "i", &typeArg)) {
+ if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
return NULL;
}
@@ -528,10 +764,10 @@ PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject*
Py_RETURN_NONE;
}
-PyObject* KX_SoundActuator::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_SoundActuator::PyGetType()
{
+ ShowDeprecationWarning("getType()", "the type property");
return PyInt_FromLong(m_type);
}
-
-
+// <-----
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index 68d5b792729..d5e678bbecd 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -80,26 +80,51 @@ public:
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
-
- KX_PYMETHOD(KX_SoundActuator,SetFilename);
- KX_PYMETHOD(KX_SoundActuator,GetFilename);
- KX_PYMETHOD(KX_SoundActuator,StartSound);
- KX_PYMETHOD(KX_SoundActuator,PauseSound);
- KX_PYMETHOD(KX_SoundActuator,StopSound);
- KX_PYMETHOD(KX_SoundActuator,SetGain);
- KX_PYMETHOD(KX_SoundActuator,GetGain);
- KX_PYMETHOD(KX_SoundActuator,SetPitch);
- KX_PYMETHOD(KX_SoundActuator,GetPitch);
- KX_PYMETHOD(KX_SoundActuator,SetRollOffFactor);
- KX_PYMETHOD(KX_SoundActuator,GetRollOffFactor);
- KX_PYMETHOD(KX_SoundActuator,SetLooping);
- KX_PYMETHOD(KX_SoundActuator,GetLooping);
- KX_PYMETHOD(KX_SoundActuator,SetPosition);
- KX_PYMETHOD(KX_SoundActuator,SetVelocity);
- KX_PYMETHOD(KX_SoundActuator,SetOrientation);
- KX_PYMETHOD(KX_SoundActuator,SetType);
- KX_PYMETHOD(KX_SoundActuator,GetType);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
+
+ KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, startSound);
+ KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, pauseSound);
+ KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, stopSound);
+
+ static int pyattr_set_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+ static PyObject* pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+
+ // Deprecated ----->
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetFilename);
+ KX_PYMETHOD_NOARGS(KX_SoundActuator,GetFilename);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetGain);
+ KX_PYMETHOD_NOARGS(KX_SoundActuator,GetGain);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetPitch);
+ KX_PYMETHOD_NOARGS(KX_SoundActuator,GetPitch);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetRollOffFactor);
+ KX_PYMETHOD_NOARGS(KX_SoundActuator,GetRollOffFactor);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetLooping);
+ KX_PYMETHOD_NOARGS(KX_SoundActuator,GetLooping);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetPosition);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetVelocity);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetOrientation);
+ KX_PYMETHOD_VARARGS(KX_SoundActuator,SetType);
+ KX_PYMETHOD_NOARGS(KX_SoundActuator,GetType);
+ // <-----
+
};
#endif //__KX_SOUNDACTUATOR
diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp
index 0de4da79bd8..976e7ea5204 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.cpp
+++ b/source/gameengine/Ketsji/KX_StateActuator.cpp
@@ -108,24 +108,23 @@ KX_StateActuator::Update()
/* Integration hooks ------------------------------------------------------- */
-PyTypeObject
-KX_StateActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+PyTypeObject KX_StateActuator::Type = {
+ PyObject_HEAD_INIT(NULL)
0,
"KX_StateActuator",
- sizeof(KX_StateActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
@@ -139,22 +138,30 @@ KX_StateActuator::Parents[] = {
PyMethodDef
KX_StateActuator::Methods[] = {
+ // deprecated -->
{"setOperation", (PyCFunction) KX_StateActuator::sPySetOperation,
METH_VARARGS, (PY_METHODCHAR)SetOperation_doc},
{"setMask", (PyCFunction) KX_StateActuator::sPySetMask,
METH_VARARGS, (PY_METHODCHAR)SetMask_doc},
+ // <--
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_StateActuator::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RW("operation",KX_StateActuator::OP_NOP+1,KX_StateActuator::OP_COUNT-1,false,KX_StateActuator,m_operation),
+ KX_PYATTRIBUTE_INT_RW("mask",0,0x3FFFFFFF,false,KX_StateActuator,m_mask),
{ NULL } //Sentinel
};
-PyObject* KX_StateActuator::_getattr(const char *attr)
+PyObject* KX_StateActuator::py_getattro(PyObject *attr)
{
- _getattr_up(SCA_IActuator);
+ py_getattro_up(SCA_IActuator);
};
+int KX_StateActuator::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IActuator);
+}
/* set operation ---------------------------------------------------------- */
@@ -166,12 +173,11 @@ KX_StateActuator::SetOperation_doc[] =
"\tUse setMask() to specify the bits that will be modified.\n";
PyObject*
-KX_StateActuator::PySetOperation(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+KX_StateActuator::PySetOperation(PyObject* args) {
+ ShowDeprecationWarning("setOperation()", "the operation property");
int oper;
- if(!PyArg_ParseTuple(args, "i", &oper)) {
+ if(!PyArg_ParseTuple(args, "i:setOperation", &oper)) {
return NULL;
}
@@ -191,12 +197,11 @@ KX_StateActuator::SetMask_doc[] =
"\twhich copies the value to the object state.\n";
PyObject*
-KX_StateActuator::PySetMask(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+KX_StateActuator::PySetMask(PyObject* args) {
+ ShowDeprecationWarning("setMask()", "the mask property");
int mask;
- if(!PyArg_ParseTuple(args, "i", &mask)) {
+ if(!PyArg_ParseTuple(args, "i:setMask", &mask)) {
return NULL;
}
diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h
index 023b8993d7c..4a64894259d 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.h
+++ b/source/gameengine/Ketsji/KX_StateActuator.h
@@ -39,13 +39,15 @@ class KX_StateActuator : public SCA_IActuator
/** Make visible? */
enum {
+ OP_NOP = -1,
OP_CPY = 0,
OP_SET,
OP_CLR,
- OP_NEG
+ OP_NEG,
+ OP_COUNT
};
int m_operation;
- unsigned int m_mask;
+ int m_mask;
public:
@@ -73,10 +75,11 @@ class KX_StateActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
//KX_PYMETHOD_DOC
- KX_PYMETHOD_DOC(KX_StateActuator,SetOperation);
- KX_PYMETHOD_DOC(KX_StateActuator,SetMask);
+ KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetOperation);
+ KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetMask);
};
#endif
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
index 7631ee05b0b..fc053f05e63 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
@@ -209,6 +209,11 @@ void KX_SumoPhysicsController::SetMass(MT_Scalar newmass)
{
}
+MT_Vector3 KX_SumoPhysicsController::GetLocalInertia()
+{
+ return MT_Vector3(0.f, 0.f, 0.f); // \todo
+}
+
MT_Scalar KX_SumoPhysicsController::GetRadius()
{
return SumoPhysicsController::GetRadius();
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
index 46c8ba6df45..083d89896f6 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
@@ -88,10 +88,15 @@ public:
virtual void setScaling(const MT_Vector3& scaling);
virtual MT_Scalar GetMass();
virtual void SetMass(MT_Scalar newmass);
+ virtual MT_Vector3 GetLocalInertia();
virtual MT_Scalar GetRadius();
virtual MT_Vector3 getReactionForce();
virtual void setRigidBody(bool rigid);
+ virtual float GetLinVelocityMin() { return SumoPhysicsController::GetLinVelocityMin(); }
+ virtual void SetLinVelocityMin(float val) { SumoPhysicsController::SetLinVelocityMin(val); }
+ virtual float GetLinVelocityMax() { return SumoPhysicsController::GetLinVelocityMax(); }
+ virtual void SetLinVelocityMax(float val) { SumoPhysicsController::SetLinVelocityMax(val); }
virtual SG_Controller* GetReplica(class SG_Node* destnode);
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 705b54edd37..5a6e8e6f501 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -242,22 +242,22 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
/* ------------------------------------------------------------------------- */
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_TouchSensor::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_TouchSensor",
- sizeof(KX_TouchSensor),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_TouchSensor::Parents[] = {
@@ -286,34 +286,19 @@ PyAttributeDef KX_TouchSensor::Attributes[] = {
KX_PYATTRIBUTE_STRING_RW("property",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_DUMMY("objectHit"),
- KX_PYATTRIBUTE_DUMMY("objectHitList"),
+ KX_PYATTRIBUTE_RO_FUNCTION("objectHit", KX_TouchSensor, pyattr_get_object_hit),
+ KX_PYATTRIBUTE_RO_FUNCTION("objectHitList", KX_TouchSensor, pyattr_get_object_hit_list),
{ NULL } //Sentinel
};
-PyObject* KX_TouchSensor::_getattr(const char *attr)
-{
- if (!strcmp(attr, "objectHit")) {
- if (m_hitObject) return m_hitObject->AddRef();
- else Py_RETURN_NONE;
- }
- if (!strcmp(attr, "objectHitList")) {
- return m_colliders->AddRef();
- }
-
- PyObject* object= _getattr_self(Attributes, this, attr);
- if (object != NULL)
- return object;
- _getattr_up(SCA_ISensor);
+PyObject* KX_TouchSensor::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_ISensor);
}
-int KX_TouchSensor::_setattr(const char *attr, PyObject *value)
+int KX_TouchSensor::py_setattro(PyObject *attr, PyObject *value)
{
- int ret = _setattr_self(Attributes, this, attr, value);
- if (ret >= 0)
- return ret;
-
- return SCA_ISensor::_setattr(attr, value);
+ py_setattro_up(SCA_ISensor);
}
/* Python API */
@@ -325,7 +310,7 @@ const char KX_TouchSensor::SetProperty_doc[] =
"\tSet the property or material to collide with. Use\n"
"\tsetTouchMaterial() to switch between properties and\n"
"\tmaterials.";
-PyObject* KX_TouchSensor::PySetProperty(PyObject* self, PyObject* value)
+PyObject* KX_TouchSensor::PySetProperty(PyObject* value)
{
ShowDeprecationWarning("setProperty()", "the propertyName property");
char *nameArg= PyString_AsString(value);
@@ -343,21 +328,21 @@ const char KX_TouchSensor::GetProperty_doc[] =
"\tReturns the property or material to collide with. Use\n"
"\tgetTouchMaterial() to find out whether this sensor\n"
"\tlooks for properties or materials.";
-PyObject* KX_TouchSensor::PyGetProperty(PyObject* self) {
+PyObject* KX_TouchSensor::PyGetProperty() {
return PyString_FromString(m_touchedpropname);
}
const char KX_TouchSensor::GetHitObject_doc[] =
"getHitObject()\n"
;
-PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self)
+PyObject* KX_TouchSensor::PyGetHitObject()
{
ShowDeprecationWarning("getHitObject()", "the objectHit property");
/* to do: do Py_IncRef if the object is already known in Python */
/* otherwise, this leaks memory */
if (m_hitObject)
{
- return m_hitObject->AddRef();
+ return m_hitObject->GetProxy();
}
Py_RETURN_NONE;
}
@@ -366,12 +351,12 @@ const char KX_TouchSensor::GetHitObjectList_doc[] =
"getHitObjectList()\n"
"\tReturn a list of the objects this object collided with,\n"
"\tbut only those matching the property/material condition.\n";
-PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self)
+PyObject* KX_TouchSensor::PyGetHitObjectList()
{
ShowDeprecationWarning("getHitObjectList()", "the objectHitList 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->AddRef();
+ return m_colliders->GetProxy();
}
/*getTouchMaterial and setTouchMaterial were never added to the api,
@@ -382,9 +367,9 @@ const char KX_TouchSensor::GetTouchMaterial_doc[] =
"getTouchMaterial()\n"
"\tReturns KX_TRUE if this sensor looks for a specific material,\n"
"\tKX_FALSE if it looks for a specific property.\n" ;
-PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self)
+PyObject* KX_TouchSensor::PyGetTouchMaterial()
{
- ShowDeprecationWarning("getTouchMaterial()", "the materialCheck property");
+ ShowDeprecationWarning("getTouchMaterial()", "the useMaterial property");
return PyInt_FromLong(m_bFindMaterial);
}
@@ -395,8 +380,9 @@ const char KX_TouchSensor::SetTouchMaterial_doc[] =
"\t- flag: KX_TRUE or KX_FALSE.\n"
"\tSet flag to KX_TRUE to switch on positive pulse mode,\n"
"\tKX_FALSE to switch off positive pulse mode.\n" ;
-PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject *value)
+PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject *value)
{
+ ShowDeprecationWarning("setTouchMaterial()", "the useMaterial property");
int pulseArg = PyInt_AsLong(value);
if(pulseArg ==-1 && PyErr_Occurred()) {
@@ -410,4 +396,21 @@ PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject *value)
}
#endif
+PyObject* KX_TouchSensor::pyattr_get_object_hit(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_TouchSensor* self= static_cast<KX_TouchSensor*>(self_v);
+
+ if (self->m_hitObject)
+ return self->m_hitObject->GetProxy();
+ else
+ Py_RETURN_NONE;
+}
+
+PyObject* KX_TouchSensor::pyattr_get_object_hit_list(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_TouchSensor* self= static_cast<KX_TouchSensor*>(self_v);
+ return self->m_colliders->GetProxy();
+}
+
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index 18ce9406a9b..15ef653c1b2 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -120,8 +120,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
//Deprecated ----->
/* 1. setProperty */
@@ -140,6 +140,10 @@ public:
#endif
//<-----
+ static PyObject* pyattr_get_object_hit(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_object_hit_list(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+
+
};
#endif //__KX_TOUCHSENSOR
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index 8637bc92d39..fbf43de6cf4 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -402,7 +402,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
// set the models tranformation properties
curobj->NodeSetLocalOrientation(mat);
curobj->NodeSetLocalPosition(localpos);
- curobj->UpdateTransform();
+ //curobj->UpdateTransform();
}
else
{
@@ -425,22 +425,22 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_TrackToActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_TrackToActuator",
- sizeof(KX_TrackToActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
};
@@ -456,12 +456,11 @@ PyParentObject KX_TrackToActuator::Parents[] = {
PyMethodDef KX_TrackToActuator::Methods[] = {
+ // ---> deprecated
{"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, (PY_METHODCHAR)SetTime_doc},
- {"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_VARARGS, (PY_METHODCHAR)GetTime_doc},
+ {"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_NOARGS, (PY_METHODCHAR)GetTime_doc},
{"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, (PY_METHODCHAR)SetUse3D_doc},
- {"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_VARARGS, (PY_METHODCHAR)GetUse3D_doc},
-
- // ---> deprecated
+ {"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_NOARGS, (PY_METHODCHAR)GetUse3D_doc},
{"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
{"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
@@ -469,40 +468,50 @@ PyMethodDef KX_TrackToActuator::Methods[] = {
};
PyAttributeDef KX_TrackToActuator::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_TrackToActuator,m_time),
+ KX_PYATTRIBUTE_BOOL_RW("use3D",KX_TrackToActuator,m_allow3D),
+ KX_PYATTRIBUTE_RW_FUNCTION("object", KX_TrackToActuator, pyattr_get_object, pyattr_set_object),
+
{ NULL } //Sentinel
};
-
-PyObject* KX_TrackToActuator::_getattr(const char *attr)
+PyObject* KX_TrackToActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
- if (!strcmp(attr, "object")) {
- if (!m_object) Py_RETURN_NONE;
- else return m_object->AddRef();
- }
-
- _getattr_up(SCA_IActuator);
+ KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self);
+ if (!actuator->m_object)
+ Py_RETURN_NONE;
+ else
+ return actuator->m_object->GetProxy();
}
-int KX_TrackToActuator::_setattr(const char *attr, PyObject* value)
+int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
- if (!strcmp(attr, "object")) {
- KX_GameObject *gameobj;
+ KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self);
+ KX_GameObject *gameobj;
- if (!ConvertPythonToGameObject(value, &gameobj, true))
- return 1; // ConvertPythonToGameObject sets the error
+ if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_TrackToActuator"))
+ return 1; // ConvertPythonToGameObject sets the error
- if (m_object != NULL)
- m_object->UnregisterActuator(this);
+ if (actuator->m_object != NULL)
+ actuator->m_object->UnregisterActuator(actuator);
- m_object = (SCA_IObject*)gameobj;
+ actuator->m_object = (SCA_IObject*) gameobj;
- if (m_object)
- m_object->RegisterActuator(this);
+ if (actuator->m_object)
+ actuator->m_object->RegisterActuator(actuator);
- return 0;
- }
-
- return SCA_IActuator::_setattr(attr, value);
+ return 0;
+}
+
+
+PyObject* KX_TrackToActuator::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_IActuator);
+}
+
+int KX_TrackToActuator::py_setattro(PyObject *attr, PyObject* value)
+{
+ py_setattro_up(SCA_IActuator);
}
/* 1. setObject */
@@ -510,13 +519,13 @@ const char KX_TrackToActuator::SetObject_doc[] =
"setObject(object)\n"
"\t- object: KX_GameObject, string or None\n"
"\tSet the object to track with the parent of this actuator.\n";
-PyObject* KX_TrackToActuator::PySetObject(PyObject* self, PyObject* value)
+PyObject* KX_TrackToActuator::PySetObject(PyObject* value)
{
KX_GameObject *gameobj;
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
if (m_object != NULL)
@@ -536,13 +545,13 @@ const char KX_TrackToActuator::GetObject_doc[] =
"getObject(name_only = 1)\n"
"name_only - optional arg, when true will return the KX_GameObject rather then its name\n"
"\tReturns the object to track with the parent of this actuator\n";
-PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args)
+PyObject* KX_TrackToActuator::PyGetObject(PyObject* args)
{
int ret_name_only = 1;
ShowDeprecationWarning("getObject()", "the object property");
- if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
+ if (!PyArg_ParseTuple(args, "|i:getObject", &ret_name_only))
return NULL;
if (!m_object)
@@ -551,7 +560,7 @@ PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args)
if (ret_name_only)
return PyString_FromString(m_object->GetName());
else
- return m_object->AddRef();
+ return m_object->GetProxy();
}
@@ -561,11 +570,12 @@ const char KX_TrackToActuator::SetTime_doc[] =
"setTime(time)\n"
"\t- time: integer\n"
"\tSet the time in frames with which to delay the tracking motion.\n";
-PyObject* KX_TrackToActuator::PySetTime(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_TrackToActuator::PySetTime(PyObject* args)
{
+ ShowDeprecationWarning("setTime()", "the timer property");
int timeArg;
- if (!PyArg_ParseTuple(args, "i", &timeArg))
+ if (!PyArg_ParseTuple(args, "i:setTime", &timeArg))
{
return NULL;
}
@@ -582,8 +592,9 @@ const char KX_TrackToActuator::GetTime_doc[] =
"getTime()\n"
"\t- time: integer\n"
"\tReturn the time in frames with which the tracking motion is delayed.\n";
-PyObject* KX_TrackToActuator::PyGetTime(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_TrackToActuator::PyGetTime()
{
+ ShowDeprecationWarning("getTime()", "the timer property");
return PyInt_FromLong(m_time);
}
@@ -593,8 +604,9 @@ PyObject* KX_TrackToActuator::PyGetTime(PyObject* self, PyObject* args, PyObject
const char KX_TrackToActuator::GetUse3D_doc[] =
"getUse3D()\n"
"\tReturns 1 if the motion is allowed to extend in the z-direction.\n";
-PyObject* KX_TrackToActuator::PyGetUse3D(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_TrackToActuator::PyGetUse3D()
{
+ ShowDeprecationWarning("setTime()", "the use3D property");
return PyInt_FromLong(!(m_allow3D == 0));
}
@@ -606,11 +618,12 @@ const char KX_TrackToActuator::SetUse3D_doc[] =
"\t- value: 0 or 1\n"
"\tSet to 1 to allow the tracking motion to extend in the z-direction,\n"
"\tset to 0 to lock the tracking motion to the x-y plane.\n";
-PyObject* KX_TrackToActuator::PySetUse3D(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_TrackToActuator::PySetUse3D(PyObject* args)
{
+ ShowDeprecationWarning("setTime()", "the use3D property");
int boolArg;
- if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ if (!PyArg_ParseTuple(args, "i:setUse3D", &boolArg)) {
return NULL;
}
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
index 392e55402f1..99505f93cfe 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.h
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -72,21 +72,25 @@ class KX_TrackToActuator : public SCA_IActuator
virtual bool Update(double curtime, bool frame);
/* Python part */
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject* value);
-
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject* value);
+
+ /* These are used to get and set m_ob */
+ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
/* 1. setObject */
KX_PYMETHOD_DOC_O(KX_TrackToActuator,SetObject);
/* 2. getObject */
KX_PYMETHOD_DOC_VARARGS(KX_TrackToActuator,GetObject);
/* 3. setTime */
- KX_PYMETHOD_DOC(KX_TrackToActuator,SetTime);
+ KX_PYMETHOD_DOC_VARARGS(KX_TrackToActuator,SetTime);
/* 4. getTime */
- KX_PYMETHOD_DOC(KX_TrackToActuator,GetTime);
+ KX_PYMETHOD_DOC_NOARGS(KX_TrackToActuator,GetTime);
/* 5. getUse3D */
- KX_PYMETHOD_DOC(KX_TrackToActuator,GetUse3D);
+ KX_PYMETHOD_DOC_NOARGS(KX_TrackToActuator,GetUse3D);
/* 6. setUse3D */
- KX_PYMETHOD_DOC(KX_TrackToActuator,SetUse3D);
+ KX_PYMETHOD_DOC_VARARGS(KX_TrackToActuator,SetUse3D);
}; /* end of class KX_TrackToActuator : public KX_EditObjectActuator */
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index 8d5af1b9216..1a6fb196db5 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -35,9 +35,7 @@ KX_VehicleWrapper::~KX_VehicleWrapper()
}
-PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* args)
{
PyObject* pylistPos,*pylistDir,*pylistAxleDir;
@@ -46,14 +44,18 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self,
int hasSteering;
- if (PyArg_ParseTuple(args,"OOOOffi",&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*) wheelGameObject;
+ KX_GameObject *gameOb;
+ if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false, "vehicle.addWheel(...): KX_VehicleWrapper (first argument)"))
+ return NULL;
+
if (gameOb->GetSGNode())
{
PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
-
+
+ /* TODO - no error checking here! - bad juju */
MT_Vector3 attachPos,attachDir,attachAxle;
PyVecTo(pylistPos,attachPos);
PyVecTo(pylistDir,attachDir);
@@ -82,14 +84,12 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self,
-PyObject* KX_VehicleWrapper::PyGetWheelPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyGetWheelPosition(PyObject* args)
{
int wheelIndex;
- if (PyArg_ParseTuple(args,"i",&wheelIndex))
+ if (PyArg_ParseTuple(args,"i:getWheelPosition",&wheelIndex))
{
float position[3];
m_vehicle->GetWheelPosition(wheelIndex,position[0],position[1],position[2]);
@@ -99,24 +99,20 @@ PyObject* KX_VehicleWrapper::PyGetWheelPosition(PyObject* self,
return NULL;
}
-PyObject* KX_VehicleWrapper::PyGetWheelRotation(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyGetWheelRotation(PyObject* args)
{
int wheelIndex;
- if (PyArg_ParseTuple(args,"i",&wheelIndex))
+ if (PyArg_ParseTuple(args,"i:getWheelRotation",&wheelIndex))
{
return PyFloat_FromDouble(m_vehicle->GetWheelRotation(wheelIndex));
}
return NULL;
}
-PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* args)
{
int wheelIndex;
- if (PyArg_ParseTuple(args,"i",&wheelIndex))
+ if (PyArg_ParseTuple(args,"i:getWheelOrientationQuaternion",&wheelIndex))
{
float orn[4];
m_vehicle->GetWheelOrientationQuaternion(wheelIndex,orn[0],orn[1],orn[2],orn[3]);
@@ -129,31 +125,25 @@ PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* self,
}
-PyObject* KX_VehicleWrapper::PyGetNumWheels(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyGetNumWheels(PyObject* args)
{
return PyInt_FromLong(m_vehicle->GetNumWheels());
}
-PyObject* KX_VehicleWrapper::PyGetConstraintId(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyGetConstraintId(PyObject* args)
{
return PyInt_FromLong(m_vehicle->GetUserConstraintId());
}
-PyObject* KX_VehicleWrapper::PyApplyEngineForce(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyApplyEngineForce(PyObject* args)
{
float force;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&force,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:applyEngineForce",&force,&wheelIndex))
{
force *= -1.f;//someone reverse some conventions inside Bullet (axle winding)
m_vehicle->ApplyEngineForce(force,wheelIndex);
@@ -164,14 +154,12 @@ PyObject* KX_VehicleWrapper::PyApplyEngineForce(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_VehicleWrapper::PySetTyreFriction(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PySetTyreFriction(PyObject* args)
{
float wheelFriction;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&wheelFriction,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:setTyreFriction",&wheelFriction,&wheelIndex))
{
m_vehicle->SetWheelFriction(wheelFriction,wheelIndex);
}
@@ -181,14 +169,12 @@ PyObject* KX_VehicleWrapper::PySetTyreFriction(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_VehicleWrapper::PySetSuspensionStiffness(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PySetSuspensionStiffness(PyObject* args)
{
float suspensionStiffness;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&suspensionStiffness,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:setSuspensionStiffness",&suspensionStiffness,&wheelIndex))
{
m_vehicle->SetSuspensionStiffness(suspensionStiffness,wheelIndex);
}
@@ -198,14 +184,12 @@ PyObject* KX_VehicleWrapper::PySetSuspensionStiffness(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_VehicleWrapper::PySetSuspensionDamping(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PySetSuspensionDamping(PyObject* args)
{
float suspensionDamping;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&suspensionDamping,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:setSuspensionDamping",&suspensionDamping,&wheelIndex))
{
m_vehicle->SetSuspensionDamping(suspensionDamping,wheelIndex);
} else {
@@ -214,14 +198,12 @@ PyObject* KX_VehicleWrapper::PySetSuspensionDamping(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_VehicleWrapper::PySetSuspensionCompression(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PySetSuspensionCompression(PyObject* args)
{
float suspensionCompression;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&suspensionCompression,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:setSuspensionCompression",&suspensionCompression,&wheelIndex))
{
m_vehicle->SetSuspensionCompression(suspensionCompression,wheelIndex);
} else {
@@ -230,14 +212,12 @@ PyObject* KX_VehicleWrapper::PySetSuspensionCompression(PyObject* self,
Py_RETURN_NONE;
}
-PyObject* KX_VehicleWrapper::PySetRollInfluence(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PySetRollInfluence(PyObject* args)
{
float rollInfluence;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&rollInfluence,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:setRollInfluence",&rollInfluence,&wheelIndex))
{
m_vehicle->SetRollInfluence(rollInfluence,wheelIndex);
}
@@ -248,14 +228,12 @@ PyObject* KX_VehicleWrapper::PySetRollInfluence(PyObject* self,
}
-PyObject* KX_VehicleWrapper::PyApplyBraking(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyApplyBraking(PyObject* args)
{
float braking;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&braking,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:applyBraking",&braking,&wheelIndex))
{
m_vehicle->ApplyBraking(braking,wheelIndex);
}
@@ -268,14 +246,12 @@ PyObject* KX_VehicleWrapper::PyApplyBraking(PyObject* self,
-PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* args)
{
float steeringValue;
int wheelIndex;
- if (PyArg_ParseTuple(args,"fi",&steeringValue,&wheelIndex))
+ if (PyArg_ParseTuple(args,"fi:setSteeringValue",&steeringValue,&wheelIndex))
{
m_vehicle->SetSteeringValue(steeringValue,wheelIndex);
}
@@ -286,9 +262,7 @@ PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* self,
}
-PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* args)
{
return PyInt_FromLong(m_vehicle->GetUserConstraintType());
}
@@ -299,38 +273,39 @@ PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* self,
//python specific stuff
PyTypeObject KX_VehicleWrapper::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_VehicleWrapper",
- sizeof(KX_VehicleWrapper),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_VehicleWrapper::Parents[] = {
&KX_VehicleWrapper::Type,
+ &PyObjectPlus::Type,
NULL
};
-PyObject* KX_VehicleWrapper::_getattr(const char *attr)
+PyObject* KX_VehicleWrapper::py_getattro(PyObject *attr)
{
//here you can search for existing data members (like mass,friction etc.)
- _getattr_up(PyObjectPlus);
+ py_getattro_up(PyObjectPlus);
}
-int KX_VehicleWrapper::_setattr(const char *attr,PyObject* pyobj)
+int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* pyobj)
{
-
+ /* TODO - strange setattr, needs updating */
PyTypeObject* type = pyobj->ob_type;
int result = 1;
@@ -352,7 +327,7 @@ int KX_VehicleWrapper::_setattr(const char *attr,PyObject* pyobj)
result = 0;
}
if (result)
- result = PyObjectPlus::_setattr(attr,pyobj);
+ result = PyObjectPlus::py_setattro(attr,pyobj);
return result;
};
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h
index cad926ce85a..de7fe75cfba 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.h
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h
@@ -12,8 +12,8 @@ class PHY_IMotionState;
class KX_VehicleWrapper : public PyObjectPlus
{
Py_Header;
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *value);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
std::vector<PHY_IMotionState*> m_motionStates;
@@ -23,31 +23,31 @@ public:
int getConstraintId();
- KX_PYMETHOD(KX_VehicleWrapper,AddWheel);
- KX_PYMETHOD(KX_VehicleWrapper,GetNumWheels);
- KX_PYMETHOD(KX_VehicleWrapper,GetWheelOrientationQuaternion);
- KX_PYMETHOD(KX_VehicleWrapper,GetWheelRotation);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,AddWheel);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetNumWheels);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetWheelOrientationQuaternion);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetWheelRotation);
- KX_PYMETHOD(KX_VehicleWrapper,GetWheelPosition);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetWheelPosition);
- KX_PYMETHOD(KX_VehicleWrapper,GetConstraintId);
- KX_PYMETHOD(KX_VehicleWrapper,GetConstraintType);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetConstraintId);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,GetConstraintType);
- KX_PYMETHOD(KX_VehicleWrapper,SetSteeringValue);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSteeringValue);
- KX_PYMETHOD(KX_VehicleWrapper,ApplyEngineForce);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,ApplyEngineForce);
- KX_PYMETHOD(KX_VehicleWrapper,ApplyBraking);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,ApplyBraking);
- KX_PYMETHOD(KX_VehicleWrapper,SetTyreFriction);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetTyreFriction);
- KX_PYMETHOD(KX_VehicleWrapper,SetSuspensionStiffness);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSuspensionStiffness);
- KX_PYMETHOD(KX_VehicleWrapper,SetSuspensionDamping);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSuspensionDamping);
- KX_PYMETHOD(KX_VehicleWrapper,SetSuspensionCompression);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSuspensionCompression);
- KX_PYMETHOD(KX_VehicleWrapper,SetRollInfluence);
+ KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetRollInfluence);
private:
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index da0e3dbdd8d..88f63334285 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -37,22 +37,22 @@
#include "KX_PyMath.h"
PyTypeObject KX_VertexProxy::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"KX_VertexProxy",
- sizeof(KX_VertexProxy),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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 KX_VertexProxy::Parents[] = {
@@ -79,47 +79,71 @@ PyMethodDef KX_VertexProxy::Methods[] = {
};
PyAttributeDef KX_VertexProxy::Attributes[] = {
+
+ KX_PYATTRIBUTE_DUMMY("x"),
+ KX_PYATTRIBUTE_DUMMY("y"),
+ KX_PYATTRIBUTE_DUMMY("z"),
+
+ KX_PYATTRIBUTE_DUMMY("r"),
+ KX_PYATTRIBUTE_DUMMY("g"),
+ KX_PYATTRIBUTE_DUMMY("b"),
+ KX_PYATTRIBUTE_DUMMY("a"),
+
+ KX_PYATTRIBUTE_DUMMY("u"),
+ KX_PYATTRIBUTE_DUMMY("v"),
+
+ KX_PYATTRIBUTE_DUMMY("u2"),
+ KX_PYATTRIBUTE_DUMMY("v2"),
+
+ KX_PYATTRIBUTE_DUMMY("XYZ"),
+ KX_PYATTRIBUTE_DUMMY("UV"),
+
+ KX_PYATTRIBUTE_DUMMY("color"),
+ KX_PYATTRIBUTE_DUMMY("colour"),
+
+ KX_PYATTRIBUTE_DUMMY("normal"),
+
{ NULL } //Sentinel
};
PyObject*
-KX_VertexProxy::_getattr(const char *attr)
+KX_VertexProxy::py_getattro(PyObject *attr)
{
-
- if (attr[1]=='\0') { // Group single letters
+ char *attr_str= PyString_AsString(attr);
+ if (attr_str[1]=='\0') { // Group single letters
// pos
- if (attr[0]=='x')
+ if (attr_str[0]=='x')
return PyFloat_FromDouble(m_vertex->getXYZ()[0]);
- if (attr[0]=='y')
+ if (attr_str[0]=='y')
return PyFloat_FromDouble(m_vertex->getXYZ()[1]);
- if (attr[0]=='z')
+ if (attr_str[0]=='z')
return PyFloat_FromDouble(m_vertex->getXYZ()[2]);
// Col
- if (attr[0]=='r')
+ if (attr_str[0]=='r')
return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0);
- if (attr[0]=='g')
+ if (attr_str[0]=='g')
return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0);
- if (attr[0]=='b')
+ if (attr_str[0]=='b')
return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0);
- if (attr[0]=='a')
+ if (attr_str[0]=='a')
return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0);
// UV
- if (attr[0]=='u')
+ if (attr_str[0]=='u')
return PyFloat_FromDouble(m_vertex->getUV1()[0]);
- if (attr[0]=='v')
+ if (attr_str[0]=='v')
return PyFloat_FromDouble(m_vertex->getUV1()[1]);
}
- if (!strcmp(attr, "XYZ"))
+ if (!strcmp(attr_str, "XYZ"))
return PyObjectFrom(MT_Vector3(m_vertex->getXYZ()));
- if (!strcmp(attr, "UV"))
+ if (!strcmp(attr_str, "UV"))
return PyObjectFrom(MT_Point2(m_vertex->getUV1()));
- if (!strcmp(attr, "color") || !strcmp(attr, "colour"))
+ if (!strcmp(attr_str, "color") || !strcmp(attr_str, "colour"))
{
const unsigned char *colp = m_vertex->getRGBA();
MT_Vector4 color(colp[0], colp[1], colp[2], colp[3]);
@@ -127,64 +151,65 @@ KX_VertexProxy::_getattr(const char *attr)
return PyObjectFrom(color);
}
- if (!strcmp(attr, "normal"))
+ if (!strcmp(attr_str, "normal"))
{
return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
}
- _getattr_up(SCA_IObject);
+ py_getattro_up(SCA_IObject);
}
-int KX_VertexProxy::_setattr(const char *attr, PyObject *pyvalue)
+int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue)
{
+ char *attr_str= PyString_AsString(attr);
if (PySequence_Check(pyvalue))
{
- if (!strcmp(attr, "XYZ"))
+ if (!strcmp(attr_str, "XYZ"))
{
MT_Point3 vec;
if (PyVecTo(pyvalue, vec))
{
m_vertex->SetXYZ(vec);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- return 1;
+ return PY_SET_ATTR_FAIL;
}
- if (!strcmp(attr, "UV"))
+ if (!strcmp(attr_str, "UV"))
{
MT_Point2 vec;
if (PyVecTo(pyvalue, vec))
{
m_vertex->SetUV(vec);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- return 1;
+ return PY_SET_ATTR_FAIL;
}
- if (!strcmp(attr, "color") || !strcmp(attr, "colour"))
+ if (!strcmp(attr_str, "color") || !strcmp(attr_str, "colour"))
{
MT_Vector4 vec;
if (PyVecTo(pyvalue, vec))
{
m_vertex->SetRGBA(vec);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- return 1;
+ return PY_SET_ATTR_FAIL;
}
- if (!strcmp(attr, "normal"))
+ if (!strcmp(attr_str, "normal"))
{
MT_Vector3 vec;
if (PyVecTo(pyvalue, vec))
{
m_vertex->SetNormal(vec);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- return 1;
+ return PY_SET_ATTR_FAIL;
}
}
@@ -193,51 +218,51 @@ int KX_VertexProxy::_setattr(const char *attr, PyObject *pyvalue)
float val = PyFloat_AsDouble(pyvalue);
// pos
MT_Point3 pos(m_vertex->getXYZ());
- if (!strcmp(attr, "x"))
+ if (!strcmp(attr_str, "x"))
{
pos.x() = val;
m_vertex->SetXYZ(pos);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "y"))
+ if (!strcmp(attr_str, "y"))
{
pos.y() = val;
m_vertex->SetXYZ(pos);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "z"))
+ if (!strcmp(attr_str, "z"))
{
pos.z() = val;
m_vertex->SetXYZ(pos);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
// uv
MT_Point2 uv = m_vertex->getUV1();
- if (!strcmp(attr, "u"))
+ if (!strcmp(attr_str, "u"))
{
uv[0] = val;
m_vertex->SetUV(uv);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "v"))
+ if (!strcmp(attr_str, "v"))
{
uv[1] = val;
m_vertex->SetUV(uv);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
// uv
MT_Point2 uv2 = m_vertex->getUV2();
- if (!strcmp(attr, "u2"))
+ if (!strcmp(attr_str, "u2"))
{
uv[0] = val;
m_vertex->SetUV2(uv);
@@ -245,49 +270,49 @@ int KX_VertexProxy::_setattr(const char *attr, PyObject *pyvalue)
return 0;
}
- if (!strcmp(attr, "v2"))
+ if (!strcmp(attr_str, "v2"))
{
uv[1] = val;
m_vertex->SetUV2(uv);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
// col
unsigned int icol = *((const unsigned int *)m_vertex->getRGBA());
unsigned char *cp = (unsigned char*) &icol;
val *= 255.0;
- if (!strcmp(attr, "r"))
+ if (!strcmp(attr_str, "r"))
{
cp[0] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "g"))
+ if (!strcmp(attr_str, "g"))
{
cp[1] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "b"))
+ if (!strcmp(attr_str, "b"))
{
cp[2] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
- if (!strcmp(attr, "a"))
+ if (!strcmp(attr_str, "a"))
{
cp[3] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
}
- return SCA_IObject::_setattr(attr, pyvalue);
+ return SCA_IObject::py_setattro(attr, pyvalue);
}
KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex)
@@ -307,7 +332,7 @@ CValue* KX_VertexProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}
STR_String sVertexName="vertex";
const STR_String & KX_VertexProxy::GetText() {return sVertexName;};
-float KX_VertexProxy::GetNumber() { return -1;}
+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;}
@@ -316,12 +341,12 @@ void KX_VertexProxy::ReplicaSetName(STR_String) {};
// stuff for python integration
-PyObject* KX_VertexProxy::PyGetXYZ(PyObject*)
+PyObject* KX_VertexProxy::PyGetXYZ()
{
return PyObjectFrom(MT_Point3(m_vertex->getXYZ()));
}
-PyObject* KX_VertexProxy::PySetXYZ(PyObject*, PyObject* value)
+PyObject* KX_VertexProxy::PySetXYZ(PyObject* value)
{
MT_Point3 vec;
if (!PyVecTo(value, vec))
@@ -332,12 +357,12 @@ PyObject* KX_VertexProxy::PySetXYZ(PyObject*, PyObject* value)
Py_RETURN_NONE;
}
-PyObject* KX_VertexProxy::PyGetNormal(PyObject*)
+PyObject* KX_VertexProxy::PyGetNormal()
{
return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
}
-PyObject* KX_VertexProxy::PySetNormal(PyObject*, PyObject* value)
+PyObject* KX_VertexProxy::PySetNormal(PyObject* value)
{
MT_Vector3 vec;
if (!PyVecTo(value, vec))
@@ -349,13 +374,13 @@ PyObject* KX_VertexProxy::PySetNormal(PyObject*, PyObject* value)
}
-PyObject* KX_VertexProxy::PyGetRGBA(PyObject*)
+PyObject* KX_VertexProxy::PyGetRGBA()
{
int *rgba = (int *) m_vertex->getRGBA();
return PyInt_FromLong(*rgba);
}
-PyObject* KX_VertexProxy::PySetRGBA(PyObject*, PyObject* value)
+PyObject* KX_VertexProxy::PySetRGBA(PyObject* value)
{
if PyInt_Check(value) {
int rgba = PyInt_AsLong(value);
@@ -373,17 +398,17 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject*, PyObject* value)
}
}
- PyErr_SetString(PyExc_TypeError, "expected a 4D vector or an int");
+ PyErr_SetString(PyExc_TypeError, "vert.setRGBA(value): KX_VertexProxy, expected a 4D vector or an int");
return NULL;
}
-PyObject* KX_VertexProxy::PyGetUV(PyObject*)
+PyObject* KX_VertexProxy::PyGetUV()
{
return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
}
-PyObject* KX_VertexProxy::PySetUV(PyObject*, PyObject* value)
+PyObject* KX_VertexProxy::PySetUV(PyObject* value)
{
MT_Point2 vec;
if (!PyVecTo(value, vec))
@@ -394,12 +419,12 @@ PyObject* KX_VertexProxy::PySetUV(PyObject*, PyObject* value)
Py_RETURN_NONE;
}
-PyObject* KX_VertexProxy::PyGetUV2(PyObject*)
+PyObject* KX_VertexProxy::PyGetUV2()
{
return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
}
-PyObject* KX_VertexProxy::PySetUV2(PyObject*, PyObject* args)
+PyObject* KX_VertexProxy::PySetUV2(PyObject* args)
{
MT_Point2 vec;
unsigned int unit=0;
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index 28196075904..67a15d96768 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -46,7 +46,7 @@ public:
CValue* Calc(VALUE_OPERATOR op, CValue *val) ;
CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
const STR_String & GetText();
- float GetNumber();
+ double GetNumber();
STR_String GetName();
void SetName(STR_String name); // Set the name of the value
void ReplicaSetName(STR_String name);
@@ -54,8 +54,8 @@ public:
// stuff for python integration
- virtual PyObject* _getattr(const char *attr);
- virtual int _setattr(const char *attr, PyObject *pyvalue);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
KX_PYMETHOD_O(KX_VertexProxy,SetXYZ);
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
index 0ec280080bd..ba59d0d3d47 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
@@ -38,11 +38,13 @@
KX_VisibilityActuator::KX_VisibilityActuator(
SCA_IObject* gameobj,
bool visible,
+ bool occlusion,
bool recursive,
PyTypeObject* T
)
: SCA_IActuator(gameobj,T),
m_visible(visible),
+ m_occlusion(occlusion),
m_recursive(recursive)
{
// intentionally empty
@@ -78,6 +80,7 @@ KX_VisibilityActuator::Update()
KX_GameObject *obj = (KX_GameObject*) GetParent();
obj->SetVisible(m_visible, m_recursive);
+ obj->SetOccluder(m_occlusion, m_recursive);
obj->UpdateBuckets(m_recursive);
return false;
@@ -90,24 +93,24 @@ KX_VisibilityActuator::Update()
/* Integration hooks ------------------------------------------------------- */
-PyTypeObject
-KX_VisibilityActuator::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+PyTypeObject KX_VisibilityActuator::Type = {
+ PyObject_HEAD_INIT(NULL)
0,
"KX_VisibilityActuator",
- sizeof(KX_VisibilityActuator),
+ sizeof(PyObjectPlus_Proxy),
0,
- PyDestructor,
+ py_base_dealloc,
0,
- __getattr,
- __setattr,
- 0, //&MyPyCompare,
- __repr,
- 0, //&cvalue_as_number,
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
@@ -121,20 +124,29 @@ KX_VisibilityActuator::Parents[] = {
PyMethodDef
KX_VisibilityActuator::Methods[] = {
- {"set", (PyCFunction) KX_VisibilityActuator::sPySetVisible,
- METH_VARARGS, (PY_METHODCHAR)SetVisible_doc},
+ // Deprecated ----->
+ {"set", (PyCFunction) KX_VisibilityActuator::sPySetVisible, METH_VARARGS,
+ (PY_METHODCHAR) SetVisible_doc},
+ // <-----
{NULL,NULL} //Sentinel
};
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),
{ NULL } //Sentinel
};
-PyObject* KX_VisibilityActuator::_getattr(const char *attr)
+PyObject* KX_VisibilityActuator::py_getattro(PyObject *attr)
{
- _getattr_up(SCA_IActuator);
-};
+ py_getattro_up(SCA_IActuator);
+}
+int KX_VisibilityActuator::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(SCA_IActuator);
+}
/* set visibility ---------------------------------------------------------- */
@@ -145,12 +157,11 @@ KX_VisibilityActuator::SetVisible_doc[] =
"\tSet the properties of the actuator.\n";
PyObject*
-KX_VisibilityActuator::PySetVisible(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+KX_VisibilityActuator::PySetVisible(PyObject* args) {
int vis;
+ ShowDeprecationWarning("SetVisible()", "the visible property");
- if(!PyArg_ParseTuple(args, "i", &vis)) {
+ if(!PyArg_ParseTuple(args, "i:setVisible", &vis)) {
return NULL;
}
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h
index 323280de8cb..04633bce665 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.h
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h
@@ -39,6 +39,7 @@ class KX_VisibilityActuator : public SCA_IActuator
/** Make visible? */
bool m_visible;
+ bool m_occlusion;
bool m_recursive;
public:
@@ -46,6 +47,7 @@ class KX_VisibilityActuator : public SCA_IActuator
KX_VisibilityActuator(
SCA_IObject* gameobj,
bool visible,
+ bool occlusion,
bool recursive,
PyTypeObject* T=&Type
);
@@ -67,9 +69,13 @@ class KX_VisibilityActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const char *attr);
- //KX_PYMETHOD_DOC
- KX_PYMETHOD_DOC(KX_VisibilityActuator,SetVisible);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+
+ // Deprecated ----->
+ KX_PYMETHOD_DOC_VARARGS(KX_VisibilityActuator,SetVisible);
+ // <-----
+
};
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 950c82b2795..0e888edd43b 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -6,7 +6,7 @@ Import ('env')
sources = env.Glob('*.cpp')
defs = ''
-#XXX
+# XXX 2.5
# Mathutils C files.
#sources.extend([\
# '#source/blender/python/api2_2x/Mathutils.c',\
@@ -18,8 +18,17 @@ defs = ''
# '#source/blender/python/api2_2x/quat.c',\
# '#source/blender/python/api2_2x/vector.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! - no other deps
+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'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #intern/bmfont'