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-06-09 00:08:19 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-06-09 00:08:19 +0400
commitc8b4cf92067ffeb625aa39003baf5d8f7c3f0025 (patch)
treec6c50dbc3d90a65fca6c1ca56a93e4a57cf7e154 /source/gameengine/Ketsji
parente93db433a086a3e739c0f4026cd500f0b595b0f1 (diff)
parentd76a6f5231c015c35123d22e1f5c3ffcdfbf9bbd (diff)
2.50:
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19820:HEAD Notes: * Game and sequencer RNA, and sequencer header are now out of date a bit after changes in trunk. * I didn't know how to port these bugfixes, most likely they are not needed anymore. * Fix "duplicate strip" always increase the user count for ipo. * IPO pinning on sequencer strips was lost during Undo.
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp32
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.h13
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp7
-rw-r--r--source/gameengine/Ketsji/BL_Material.h4
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp13
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h1
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt3
-rw-r--r--source/gameengine/Ketsji/KXNetwork/CMakeLists.txt2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp8
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp18
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h1
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp27
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h3
-rw-r--r--source/gameengine/Ketsji/KXNetwork/Makefile2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/SConscript4
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp119
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h16
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp58
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h5
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.cpp18
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp453
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h30
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp25
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_ClientObjectInfo.h6
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp21
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.cpp82
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.h6
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h6
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp182
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp417
-rw-r--r--source/gameengine/Ketsji/KX_Dome.h29
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp27
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp556
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h50
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.cpp17
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h12
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp42
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp202
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h21
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp276
-rw-r--r--source/gameengine/Ketsji/KX_Light.h8
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp59
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.h8
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.h1
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp36
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h7
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp93
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp337
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h92
-rw-r--r--source/gameengine/Ketsji/KX_OdePhysicsController.h1
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp30
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.h7
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h1
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.cpp24
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.h8
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp108
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h15
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp65
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.h14
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp426
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h2
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.cpp382
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.h60
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp68
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.h2
-rw-r--r--source/gameengine/Ketsji/KX_RayEventManager.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp38
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h3
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp44
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp23
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp15
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp288
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h63
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp119
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp82
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.cpp50
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.h16
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h3
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp60
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp105
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h7
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp34
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp40
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.h1
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp31
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h8
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.cpp19
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.h1
-rw-r--r--source/gameengine/Ketsji/SConscript41
110 files changed, 4120 insertions, 1739 deletions
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 3df483b0598..a0a61d01bb2 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -20,41 +20,33 @@ BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lig
:
mScene(scene),
mMat(ma),
- mLightLayer(lightlayer)
+ mLightLayer(lightlayer),
+ mGPUMat(NULL)
{
mBlenderScene = scene->GetBlenderScene();
mBlendMode = GPU_BLEND_SOLID;
- if(mMat)
- GPU_material_from_blender(mBlenderScene, mMat);
+ ReloadMaterial();
}
BL_BlenderShader::~BL_BlenderShader()
{
- if(mMat && GPU_material_from_blender(mBlenderScene, mMat))
- GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat));
+ if(mGPUMat)
+ GPU_material_unbind(mGPUMat);
}
-bool BL_BlenderShader::Ok()
+void BL_BlenderShader::ReloadMaterial()
{
- return VerifyShader();
-}
-
-bool BL_BlenderShader::VerifyShader()
-{
- if(mMat)
- return (GPU_material_from_blender(mBlenderScene, mMat) != 0);
- else
- return false;
+ mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
}
void BL_BlenderShader::SetProg(bool enable, double time)
{
if(VerifyShader()) {
if(enable)
- GPU_material_bind(GPU_material_from_blender(mBlenderScene, mMat), mLightLayer, mBlenderScene->lay, time);
+ GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time);
else
- GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat));
+ GPU_material_unbind(mGPUMat);
}
}
@@ -66,7 +58,7 @@ int BL_BlenderShader::GetAttribNum()
if(!VerifyShader())
return enabled;
- GPU_material_vertex_attributes(GPU_material_from_blender(mBlenderScene, mMat), &attribs);
+ GPU_material_vertex_attributes(mGPUMat, &attribs);
for(i = 0; i < attribs.totlayer; i++)
if(attribs.layer[i].glindex+1 > enabled)
@@ -89,7 +81,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
if(!VerifyShader())
return;
- gpumat = GPU_material_from_blender(mBlenderScene, mMat);
+ gpumat = mGPUMat;
if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
GPU_material_vertex_attributes(gpumat, &attribs);
@@ -131,7 +123,7 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
GPUMaterial *gpumat;
- gpumat = GPU_material_from_blender(mBlenderScene, mMat);
+ gpumat = mGPUMat;
if(!gpumat || !GPU_material_bound(gpumat))
return;
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h
index 5c1f59f94ad..9af53bfc863 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.h
+++ b/source/gameengine/Ketsji/BL_BlenderShader.h
@@ -32,19 +32,28 @@ private:
struct Material *mMat;
int mLightLayer;
int mBlendMode;
+ GPUMaterial *mGPUMat;
- bool VerifyShader();
+ bool VerifyShader()
+ {
+ return (NULL != mGPUMat);
+ }
public:
BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer);
virtual ~BL_BlenderShader();
- bool Ok();
+ bool Ok()
+ {
+ // same as VerifyShared
+ return (NULL != mGPUMat);
+ }
void SetProg(bool enable, double time=0.0);
int GetAttribNum();
void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
void Update(const class RAS_MeshSlot & ms, class RAS_IRasterizer* rasty);
+ void ReloadMaterial();
int GetBlendMode();
bool Equals(BL_BlenderShader *blshader);
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 7e3d6984f19..c63b9d55306 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -28,6 +28,11 @@ int getNumTexChannels( Material *mat )
BL_Material::BL_Material()
{
+ Initialize();
+}
+
+void BL_Material::Initialize()
+{
rgb[0] = 0;
rgb[1] = 0;
rgb[2] = 0;
@@ -52,7 +57,7 @@ BL_Material::BL_Material()
mode = 0;
material = 0;
tface = 0;
- material_index = 0;
+ materialindex = 0;
amb=0.5f;
num_enabled = 0;
num_users = 1;
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index 0eaa234566c..4f572f95891 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -44,6 +44,7 @@ private:
public:
// -----------------------------------
BL_Material();
+ void Initialize();
int IdMode;
unsigned int ras_mode;
@@ -54,6 +55,7 @@ public:
int tile,tilexrep[MAXTEX],tileyrep[MAXTEX];
STR_String matname;
STR_String mtexname[MAXTEX];
+ int materialindex;
float matcolor[4];
float speccolor[3];
@@ -68,8 +70,6 @@ public:
int mode;
int num_enabled;
- int material_index;
-
BL_Mapping mapping[MAXTEX];
STR_String imageId[MAXTEX];
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index 88d920043e0..c5c517c8a65 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -734,6 +734,10 @@ PyObject* BL_Shader::py_getattro(PyObject *attr)
py_getattro_up(PyObjectPlus);
}
+PyObject* BL_Shader::py_getattro_dict() {
+ py_getattro_dict_up(PyObjectPlus);
+}
+
PyMethodDef BL_Shader::Methods[] =
{
@@ -772,8 +776,13 @@ PyAttributeDef BL_Shader::Attributes[] = {
};
PyTypeObject BL_Shader::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"BL_Shader",
sizeof(PyObjectPlus_Proxy),
0,
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index 08cad5071fd..7db40e778ae 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -203,6 +203,7 @@ public:
// Python interface
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual PyObject* py_repr(void) { return PyString_FromFormat("BL_Shader\n\tvertex shader:%s\n\n\tfragment shader%s\n\n", vertProg, fragProg); }
// -----------------------------------
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index ca9ce4dc50c..4aaa49a8493 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -30,11 +30,10 @@ FILE(GLOB SRC *.cpp)
#SET(SRC
# ${SRC}
# ../../../source/blender/python/api2_2x/Mathutils.c
+# ../../../source/blender/python/api2_2x/Geometry.c
# ../../../source/blender/python/api2_2x/constant.c
# ../../../source/blender/python/api2_2x/euler.c
-# ../../../source/blender/python/api2_2x/gen_utils.c
# ../../../source/blender/python/api2_2x/matrix.c
-# ../../../source/blender/python/api2_2x/point.c
# ../../../source/blender/python/api2_2x/quat.c
# ../../../source/blender/python/api2_2x/vector.c
# ../../../source/blender/python/api2_2x/bpy_internal_import.c
diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
index fa0ca378c6b..d9a9fc54f4b 100644
--- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
+++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
@@ -30,9 +30,11 @@ SET(INC
.
../../../../source/kernel/gen_system
../../../../intern/string
+ ../../../../intern/moto/include
../../../../source/gameengine/Ketsji
../../../../source/gameengine/GameLogic
../../../../source/gameengine/Expressions
+ ../../../../source/gameengine/SceneGraph
../../../../source/gameengine/Network
${PYTHON_INC}
)
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
index eee8e9f6827..738f64713b0 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
@@ -61,12 +61,12 @@ void KX_NetworkEventManager::NextFrame()
// each frame, the logicmanager will call the network
// eventmanager to look for network events, and process it's
// 'network' sensors
- set<class SCA_ISensor*>::iterator it;
-
- for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) {
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
+ {
// printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime);
// process queue
- (*it)->Activate(m_logicmgr, NULL);
+ (*it)->Activate(m_logicmgr);
}
// now a list of triggerer sensors has been built
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
index 2483a6bfb39..63773352d96 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
@@ -75,7 +75,7 @@ bool KX_NetworkMessageActuator::Update()
m_toPropName,
GetParent()->GetName(),
m_subject,
- GetParent()->GetPropertyText(m_body,""));
+ GetParent()->GetPropertyText(m_body));
} else
{
m_networkscene->SendMessage(
@@ -93,9 +93,6 @@ CValue* KX_NetworkMessageActuator::GetReplica()
new KX_NetworkMessageActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
return replica;
}
@@ -105,8 +102,13 @@ CValue* KX_NetworkMessageActuator::GetReplica()
/* Integration hooks -------------------------------------------------- */
PyTypeObject KX_NetworkMessageActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_NetworkMessageActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -157,6 +159,10 @@ PyObject* KX_NetworkMessageActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_NetworkMessageActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_NetworkMessageActuator::py_setattro(PyObject *attr, PyObject *value) {
py_setattro_up(SCA_IActuator);
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
index 850f825b8f3..cf92fd46fe0 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
@@ -62,6 +62,7 @@ public:
/* ------------------------------------------------------------ */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// Deprecated ----->
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index 7782567943e..8ddcd87b66f 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -79,15 +79,13 @@ CValue* KX_NetworkMessageSensor::GetReplica() {
CValue* replica = new KX_NetworkMessageSensor(*this);
if (replica == NULL) return NULL;
-
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
// Return true only for flank (UP and DOWN)
-bool KX_NetworkMessageSensor::Evaluate(CValue* event)
+bool KX_NetworkMessageSensor::Evaluate()
{
bool result = false;
bool WasUp = m_IsUp;
@@ -104,8 +102,8 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event)
m_SubjectList = NULL;
}
- STR_String toname=GetParent()->GetName();
- STR_String subject = this->m_subject;
+ STR_String& toname=GetParent()->GetName();
+ STR_String& subject = this->m_subject;
vector<NG_NetworkMessage*> messages =
m_NetworkScene->FindMessages(toname,"",subject,true);
@@ -125,9 +123,9 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event)
for (mesit=messages.begin();mesit!=messages.end();mesit++)
{
// save the body
- STR_String body = (*mesit)->GetMessageText();
+ const STR_String& body = (*mesit)->GetMessageText();
// save the subject
- STR_String messub = (*mesit)->GetSubject();
+ const STR_String& messub = (*mesit)->GetSubject();
#ifdef NAN_NET_DEBUG
if (body) {
cout << "body [" << body << "]\n";
@@ -168,8 +166,13 @@ bool KX_NetworkMessageSensor::IsPositiveTrigger()
/* Integration hooks --------------------------------------------------- */
PyTypeObject KX_NetworkMessageSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_NetworkMessageSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -227,6 +230,10 @@ PyObject* KX_NetworkMessageSensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* KX_NetworkMessageSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int KX_NetworkMessageSensor::py_setattro(PyObject *attr, PyObject *value) {
return SCA_ISensor::py_setattro(attr, value);
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index ac0e880d25c..53183f33826 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -63,7 +63,7 @@ public:
virtual ~KX_NetworkMessageSensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void Init();
void EndFrame();
@@ -73,6 +73,7 @@ public:
/* ------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// Deprecated ----->
diff --git a/source/gameengine/Ketsji/KXNetwork/Makefile b/source/gameengine/Ketsji/KXNetwork/Makefile
index ddcb03600d5..365ed8fc9c3 100644
--- a/source/gameengine/Ketsji/KXNetwork/Makefile
+++ b/source/gameengine/Ketsji/KXNetwork/Makefile
@@ -38,8 +38,10 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../../Expressions
CPPFLAGS += -I../../GameLogic
+CPPFLAGS += -I../../SceneGraph
CPPFLAGS += -I../../Network
CPPFLAGS += -I../../../kernel/gen_system
CPPFLAGS += -I..
diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript
index b417edf6413..f350b2ce25a 100644
--- a/source/gameengine/Ketsji/KXNetwork/SConscript
+++ b/source/gameengine/Ketsji/KXNetwork/SConscript
@@ -3,9 +3,9 @@ Import ('env')
sources = env.Glob('*.cpp')
-incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Ketsji'
+incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Ketsji'
incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions'
-incs += ' #source/gameengine/Network'
+incs += ' #source/gameengine/Network #source/gameengine/SceneGraph'
incs += ' ' + env['BF_PYTHON_INC']
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 849332008ce..30057fc039d 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -43,35 +43,48 @@ BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL;
//static PyObject *gTextureDict = 0;
KX_BlenderMaterial::KX_BlenderMaterial(
- KX_Scene *scene,
- BL_Material *data,
- bool skin,
- int lightlayer,
PyTypeObject *T
)
: PyObjectPlus(T),
- RAS_IPolyMaterial(
- STR_String( data->texname[0] ),
- STR_String( data->matname ), // needed for physics!
- data->tile,
- data->tilexrep[0],
- data->tileyrep[0],
- data->mode,
- data->transp,
- ((data->ras_mode &ALPHA)!=0),
- ((data->ras_mode &ZSORT)!=0),
- lightlayer
- ),
- mMaterial(data),
+ RAS_IPolyMaterial(),
+ mMaterial(NULL),
mShader(0),
mBlenderShader(0),
- mScene(scene),
+ mScene(NULL),
mUserDefBlend(0),
mModified(0),
mConstructed(false),
mPass(0)
+{
+}
+void KX_BlenderMaterial::Initialize(
+ KX_Scene *scene,
+ BL_Material *data,
+ bool skin,
+ int lightlayer)
{
+ RAS_IPolyMaterial::Initialize(
+ data->texname[0],
+ data->matname,
+ data->materialindex,
+ data->tile,
+ data->tilexrep[0],
+ data->tileyrep[0],
+ data->mode,
+ data->transp,
+ ((data->ras_mode &ALPHA)!=0),
+ ((data->ras_mode &ZSORT)!=0),
+ lightlayer
+ );
+ mMaterial = data;
+ mShader = 0;
+ mBlenderShader = 0;
+ mScene = scene;
+ mUserDefBlend = 0;
+ mModified = 0;
+ mConstructed = false;
+ mPass = 0;
// --------------------------------
// RAS_IPolyMaterial variables...
m_flag |= RAS_BLENDERMAT;
@@ -95,7 +108,6 @@ KX_BlenderMaterial::KX_BlenderMaterial(
);
}
m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(COLLIDER|USE_LIGHT));
-
}
KX_BlenderMaterial::~KX_BlenderMaterial()
@@ -106,7 +118,6 @@ KX_BlenderMaterial::~KX_BlenderMaterial()
OnExit();
}
-
MTFace* KX_BlenderMaterial::GetMTFace(void) const
{
// fonts on polys
@@ -120,14 +131,41 @@ unsigned int* KX_BlenderMaterial::GetMCol(void) const
return mMaterial->rgb;
}
-void KX_BlenderMaterial::OnConstruction()
+void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
+{
+ if (mMaterial) {
+ *rgba++ = (unsigned char) (mMaterial->matcolor[0]*255.0);
+ *rgba++ = (unsigned char) (mMaterial->matcolor[1]*255.0);
+ *rgba++ = (unsigned char) (mMaterial->matcolor[2]*255.0);
+ *rgba++ = (unsigned char) (mMaterial->matcolor[3]*255.0);
+ } else
+ RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
+}
+
+Material *KX_BlenderMaterial::GetBlenderMaterial() const
+{
+ return mMaterial->material;
+}
+
+Scene* KX_BlenderMaterial::GetBlenderScene() const
+{
+ return mScene->GetBlenderScene();
+}
+
+void KX_BlenderMaterial::ReleaseMaterial()
+{
+ if (mBlenderShader)
+ mBlenderShader->ReloadMaterial();
+}
+
+void KX_BlenderMaterial::OnConstruction(int layer)
{
if (mConstructed)
// when material are reused between objects
return;
if(mMaterial->glslmat)
- SetBlenderGLSLShader();
+ SetBlenderGLSLShader(layer);
// for each unique material...
int i;
@@ -377,10 +415,12 @@ KX_BlenderMaterial::ActivatShaders(
}
else
rasty->SetLines(false);
+ ActivatGLMaterials(rasty);
+ ActivateTexGen(rasty);
}
- ActivatGLMaterials(rasty);
- ActivateTexGen(rasty);
+ //ActivatGLMaterials(rasty);
+ //ActivateTexGen(rasty);
}
void
@@ -469,10 +509,12 @@ KX_BlenderMaterial::ActivateMat(
}
else
rasty->SetLines(false);
+ ActivatGLMaterials(rasty);
+ ActivateTexGen(rasty);
}
- ActivatGLMaterials(rasty);
- ActivateTexGen(rasty);
+ //ActivatGLMaterials(rasty);
+ //ActivateTexGen(rasty);
}
bool
@@ -601,8 +643,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
if (mode &USECUSTOMUV)
{
- STR_String str = mMaterial->mapping[i].uvCoName;
- if (!str.IsEmpty())
+ if (!mMaterial->mapping[i].uvCoName.IsEmpty())
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
continue;
}
@@ -749,12 +790,20 @@ PyMethodDef KX_BlenderMaterial::Methods[] =
};
PyAttributeDef KX_BlenderMaterial::Attributes[] = {
+ //KX_PYATTRIBUTE_TODO("shader"),
+ //KX_PYATTRIBUTE_TODO("materialIndex"),
+ //KX_PYATTRIBUTE_TODO("blending"),
{ NULL } //Sentinel
};
PyTypeObject KX_BlenderMaterial::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_BlenderMaterial",
sizeof(PyObjectPlus_Proxy),
0,
@@ -784,6 +833,10 @@ PyObject* KX_BlenderMaterial::py_getattro(PyObject *attr)
py_getattro_up(PyObjectPlus);
}
+PyObject* KX_BlenderMaterial::py_getattro_dict() {
+ py_getattro_dict_up(PyObjectPlus);
+}
+
int KX_BlenderMaterial::py_setattro(PyObject *attr, PyObject *pyvalue)
{
return PyObjectPlus::py_setattro(attr, pyvalue);
@@ -846,10 +899,10 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
}
-void KX_BlenderMaterial::SetBlenderGLSLShader(void)
+void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
{
if(!mBlenderShader)
- mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, m_lightlayer);
+ mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
if(!mBlenderShader->Ok()) {
delete mBlenderShader;
@@ -859,7 +912,7 @@ void KX_BlenderMaterial::SetBlenderGLSLShader(void)
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
{
- return PyInt_FromLong( mMaterial->material_index );
+ return PyInt_FromLong( GetMaterialIndex() );
}
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" )
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 48d4730ab07..b29f2df98db 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -24,11 +24,13 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial
public:
// --------------------------------
KX_BlenderMaterial(
+ PyTypeObject* T=&Type
+ );
+ void Initialize(
class KX_Scene* scene,
BL_Material* mat,
bool skin,
- int lightlayer,
- PyTypeObject* T=&Type
+ int lightlayer
);
virtual ~KX_BlenderMaterial();
@@ -73,7 +75,6 @@ public:
Image * getImage (unsigned int idx) {
return (idx < MAXTEX && mMaterial) ? mMaterial->img[idx] : NULL;
}
-
// for ipos
void UpdateIPO(
MT_Vector4 rgba, MT_Vector3 specrgb,
@@ -83,6 +84,7 @@ public:
// --------------------------------
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
virtual PyObject* py_repr(void) { return PyString_FromString(mMaterial->matname.ReadPtr()); }
@@ -95,7 +97,7 @@ public:
// --------------------------------
// pre calculate to avoid pops/lag at startup
- virtual void OnConstruction( );
+ virtual void OnConstruction(int layer);
static void EndFrame();
@@ -110,12 +112,16 @@ private:
bool mModified;
bool mConstructed; // if false, don't clean on exit
- void SetBlenderGLSLShader();
+ void SetBlenderGLSLShader(int layer);
void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
void ActivateTexGen( RAS_IRasterizer *ras ) const;
bool UsesLighting(RAS_IRasterizer *rasty) const;
+ void GetMaterialRGBAColor(unsigned char *rgba) const;
+ Material* GetBlenderMaterial() const;
+ Scene* GetBlenderScene() const;
+ void ReleaseMaterial();
// message centers
void setTexData( bool enable,RAS_IRasterizer *ras);
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 831f9241fec..748b0667061 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -17,13 +17,17 @@
#include "BulletSoftBody/btSoftBody.h"
-KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound)
-: KX_IPhysicsController(dyna,compound,(PHY_IPhysicsController*)this),
+KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound)
+: KX_IPhysicsController(dyna,sensor,compound,(PHY_IPhysicsController*)this),
CcdPhysicsController(ci),
m_savedCollisionFlags(0),
+m_savedCollisionFilterGroup(0),
+m_savedCollisionFilterMask(0),
+m_savedMass(0.0),
+m_savedDyna(false),
+m_suspended(false),
m_bulletChildShape(NULL)
{
-
}
KX_BulletPhysicsController::~KX_BulletPhysicsController ()
@@ -88,7 +92,13 @@ void KX_BulletPhysicsController::SetObject (SG_IObject* object)
gameobj->SetPhysicsController(this,gameobj->IsDynamic());
CcdPhysicsController::setNewClientInfo(gameobj->getClientInfo());
-
+ if (m_bSensor)
+ {
+ // use a different callback function for sensor object,
+ // bullet will not synchronize, we must do it explicitely
+ SG_Callbacks& callbacks = gameobj->GetSGNode()->GetCallBackFunctions();
+ callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc;
+ }
}
MT_Scalar KX_BulletPhysicsController::GetRadius()
@@ -170,6 +180,20 @@ void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling)
{
CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z());
}
+void KX_BulletPhysicsController::SetTransform()
+{
+ btVector3 pos;
+ btVector3 scale;
+ float ori[12];
+ m_MotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]);
+ m_MotionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]);
+ m_MotionState->getWorldOrientation(ori);
+ btMatrix3x3 rot(ori[0], ori[4], ori[8],
+ ori[1], ori[5], ori[9],
+ ori[2], ori[6], ori[10]);
+ CcdPhysicsController::forceWorldTransform(rot, pos);
+}
+
MT_Scalar KX_BulletPhysicsController::GetMass()
{
if (GetSoftBody())
@@ -258,7 +282,7 @@ void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* chil
// add to parent compound shapeinfo
GetShapeInfo()->AddShape(proxyShapeInfo);
// create new bullet collision shape from the object shapeinfo and set scaling
- btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape();
+ btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin());
newChildShape->setLocalScaling(relativeScale);
// add bullet collision shape to parent compound collision shape
compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape);
@@ -337,8 +361,7 @@ void KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* c
void KX_BulletPhysicsController::SetMass(MT_Scalar newmass)
{
btRigidBody *body = GetRigidBody();
- if (body && body->getActivationState() != DISABLE_SIMULATION &&
- newmass>MT_EPSILON && GetMass()>MT_EPSILON)
+ if (body && !m_suspended && newmass>MT_EPSILON && GetMass()>MT_EPSILON)
{
btVector3 grav = body->getGravity();
btVector3 accel = grav / GetMass();
@@ -356,34 +379,37 @@ void KX_BulletPhysicsController::SetMass(MT_Scalar newmass)
void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
{
btRigidBody *body = GetRigidBody();
- if (body && body->getActivationState() != DISABLE_SIMULATION)
+ if (body && !m_suspended && !IsSensor())
{
btBroadphaseProxy* handle = body->getBroadphaseHandle();
m_savedCollisionFlags = body->getCollisionFlags();
m_savedMass = GetMass();
+ m_savedDyna = m_bDyna;
m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
m_savedCollisionFilterMask = handle->m_collisionFilterMask;
- m_savedActivationState = body->getActivationState();
- body->forceActivationState(DISABLE_SIMULATION);
+ m_suspended = true;
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
0.0,
btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
btBroadphaseProxy::StaticFilter,
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
+ m_bDyna = false;
}
}
void KX_BulletPhysicsController::RestoreDynamics()
{
btRigidBody *body = GetRigidBody();
- if (body && body->getActivationState() == DISABLE_SIMULATION)
+ if (body && m_suspended)
{
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
m_savedMass,
m_savedCollisionFlags,
m_savedCollisionFilterGroup,
m_savedCollisionFilterMask);
- body->forceActivationState(m_savedActivationState);
+ body->activate();
+ m_bDyna = m_savedDyna;
+ m_suspended = false;
}
}
@@ -438,12 +464,12 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly)
{
- if (GetRigidBody())
- GetRigidBody()->activate(true);
- if (!m_bDyna)
+ if (!m_bDyna && !m_bSensor)
{
- GetCollisionObject()->setCollisionFlags(GetRigidBody()->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ btCollisionObject* object = GetRigidBody();
+ object->setActivationState(ACTIVE_TAG);
+ object->setCollisionFlags(object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
} else
{
if (!nondynaonly)
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index b39098206f7..755b1cbd780 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -13,11 +13,13 @@ private:
short int m_savedCollisionFilterGroup;
short int m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
+ bool m_savedDyna;
+ bool m_suspended;
btCollisionShape* m_bulletChildShape;
public:
- KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound);
+ KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound);
virtual ~KX_BulletPhysicsController ();
///////////////////////////////////
@@ -40,6 +42,7 @@ public:
virtual void setOrientation(const MT_Matrix3x3& orn);
virtual void setPosition(const MT_Point3& pos);
virtual void setScaling(const MT_Vector3& scaling);
+ virtual void SetTransform();
virtual MT_Scalar GetMass();
virtual void SetMass(MT_Scalar newmass);
virtual MT_Vector3 GetLocalInertia();
diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp
index 121d4512265..8511526fd5f 100644
--- a/source/gameengine/Ketsji/KX_CDActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CDActuator.cpp
@@ -74,9 +74,6 @@ CValue* KX_CDActuator::GetReplica()
{
KX_CDActuator* replica = new KX_CDActuator(*this);
replica->ProcessReplica();
-
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
};
@@ -158,8 +155,13 @@ bool KX_CDActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_CDActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SoundActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -212,7 +214,7 @@ int KX_CDActuator::pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *a
{
KX_CDActuator* act = static_cast<KX_CDActuator*>(self);
SND_CDObject::Instance()->SetGain(act->m_gain);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_CDActuator::py_getattro(PyObject *attr)
@@ -220,6 +222,10 @@ PyObject* KX_CDActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_CDActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_CDActuator::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_IActuator);
diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h
index b674755e59f..2fd05ab72e5 100644
--- a/source/gameengine/Ketsji/KX_CDActuator.h
+++ b/source/gameengine/Ketsji/KX_CDActuator.h
@@ -82,6 +82,7 @@ public:
/* -------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// Deprecated ----->
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index c8575424751..ba4d6e22872 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -28,6 +28,7 @@
* Camera in the gameengine. Cameras are also used for views.
*/
+#include "GL/glew.h"
#include "KX_Camera.h"
#include "KX_Scene.h"
#include "KX_PythonInit.h"
@@ -41,15 +42,17 @@ KX_Camera::KX_Camera(void* sgReplicationInfo,
SG_Callbacks callbacks,
const RAS_CameraData& camdata,
bool frustum_culling,
+ bool delete_node,
PyTypeObject *T)
:
KX_GameObject(sgReplicationInfo,callbacks,T),
m_camdata(camdata),
m_dirty(true),
m_normalized(false),
- m_frustum_culling(frustum_culling && camdata.m_perspective),
+ m_frustum_culling(frustum_culling),
m_set_projection_matrix(false),
- m_set_frustum_center(false)
+ m_set_frustum_center(false),
+ m_delete_node(delete_node)
{
// setting a name would be nice...
m_name = "cam";
@@ -63,6 +66,12 @@ KX_Camera::KX_Camera(void* sgReplicationInfo,
KX_Camera::~KX_Camera()
{
+ if (m_delete_node && m_pSGNode)
+ {
+ // for shadow camera, avoids memleak
+ delete m_pSGNode;
+ m_pSGNode = NULL;
+ }
}
@@ -71,15 +80,16 @@ CValue* KX_Camera::GetReplica()
KX_Camera* replica = new KX_Camera(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
- ProcessReplica(replica);
+ replica->ProcessReplica();
return replica;
}
-
-void KX_Camera::ProcessReplica(KX_Camera* replica)
+
+void KX_Camera::ProcessReplica()
{
- KX_GameObject::ProcessReplica(replica);
+ KX_GameObject::ProcessReplica();
+ // replicated camera are always registered in the scene
+ m_delete_node = false;
}
MT_Transform KX_Camera::GetWorldToCamera() const
@@ -190,6 +200,11 @@ float KX_Camera::GetLens() const
return m_camdata.m_lens;
}
+float KX_Camera::GetScale() const
+{
+ return m_camdata.m_scale;
+}
+
float KX_Camera::GetCameraNear() const
@@ -270,80 +285,83 @@ void KX_Camera::ExtractFrustumSphere()
MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix;
clip_camcs_matrix.invert();
- // detect which of the corner of the far clipping plane is the farthest to the origin
- MT_Vector4 nfar; // far point in device normalized coordinate
- MT_Point3 farpoint; // most extreme far point in camera coordinate
- MT_Point3 nearpoint;// most extreme near point in camera coordinate
- MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate
- MT_Scalar F=1.0, N; // square distance of far and near point to origin
- MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0
- MT_Scalar e, s; // far and near clipping distance (<0)
- MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance
- MT_Scalar z; // projection of sphere center on z axis (<0)
- // tmp value
- MT_Vector4 npoint(1., 1., 1., 1.);
- MT_Vector4 hpoint;
- MT_Point3 point;
- MT_Scalar len;
- for (int i=0; i<4; i++)
- {
- hpoint = clip_camcs_matrix*npoint;
- point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]);
- len = point.dot(point);
- if (len > F)
- {
- nfar = npoint;
- farpoint = point;
- F = len;
- }
- // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane
- len = npoint[0];
- npoint[0] = -npoint[1];
- npoint[1] = len;
- farcenter += point;
- }
- // the far center is the average of the far clipping points
- farcenter *= 0.25;
- // the extreme near point is the opposite point on the near clipping plane
- nfar.setValue(-nfar[0], -nfar[1], -1., 1.);
- nfar = clip_camcs_matrix*nfar;
- nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]);
- N = nearpoint.dot(nearpoint);
- e = farpoint[2];
- s = nearpoint[2];
- // projection on XY plane for distance to axis computation
- MT_Point2 farxy(farpoint[0], farpoint[1]);
- // f is forced positive by construction
- f = farxy.length();
- // get corresponding point on the near plane
- farxy *= s/e;
- // this formula preserve the sign of n
- n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length();
- c = MT_Point2(farcenter[0], farcenter[1]).length()/e;
- // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case
- z = (F-N)/(2.0*(e-s+c*(f-n)));
- m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z);
- m_frustum_radius = m_frustum_center.distance(farpoint);
-
-#if 0
- // The most extreme points on the near and far plane. (normalized device coords)
- MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.);
-
- // Transform to hom camera local space
- hnear = clip_camcs_matrix*hnear;
- hfar = clip_camcs_matrix*hfar;
-
- // Tranform to 3d camera local space.
- MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]);
- MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
-
- // Compute center
- // don't use camera data in case the user specifies the matrix directly
- m_frustum_center = MT_Point3(0., 0.,
- (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(nearpoint[2]-farpoint[2] /*m_camdata.m_clipend - m_camdata.m_clipstart*/)));
- m_frustum_radius = m_frustum_center.distance(farpoint);
-#endif
-
+ if (m_projection_matrix[3][3] == MT_Scalar(0.0))
+ {
+ // frustrum projection
+ // detect which of the corner of the far clipping plane is the farthest to the origin
+ MT_Vector4 nfar; // far point in device normalized coordinate
+ MT_Point3 farpoint; // most extreme far point in camera coordinate
+ MT_Point3 nearpoint;// most extreme near point in camera coordinate
+ MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate
+ MT_Scalar F=-1.0, N; // square distance of far and near point to origin
+ MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0
+ MT_Scalar e, s; // far and near clipping distance (<0)
+ MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance
+ MT_Scalar z; // projection of sphere center on z axis (<0)
+ // tmp value
+ MT_Vector4 npoint(1., 1., 1., 1.);
+ MT_Vector4 hpoint;
+ MT_Point3 point;
+ MT_Scalar len;
+ for (int i=0; i<4; i++)
+ {
+ hpoint = clip_camcs_matrix*npoint;
+ point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]);
+ len = point.dot(point);
+ if (len > F)
+ {
+ nfar = npoint;
+ farpoint = point;
+ F = len;
+ }
+ // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane
+ len = npoint[0];
+ npoint[0] = -npoint[1];
+ npoint[1] = len;
+ farcenter += point;
+ }
+ // the far center is the average of the far clipping points
+ farcenter *= 0.25;
+ // the extreme near point is the opposite point on the near clipping plane
+ nfar.setValue(-nfar[0], -nfar[1], -1., 1.);
+ nfar = clip_camcs_matrix*nfar;
+ nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]);
+ // this is a frustrum projection
+ N = nearpoint.dot(nearpoint);
+ e = farpoint[2];
+ s = nearpoint[2];
+ // projection on XY plane for distance to axis computation
+ MT_Point2 farxy(farpoint[0], farpoint[1]);
+ // f is forced positive by construction
+ f = farxy.length();
+ // get corresponding point on the near plane
+ farxy *= s/e;
+ // this formula preserve the sign of n
+ n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length();
+ c = MT_Point2(farcenter[0], farcenter[1]).length()/e;
+ // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case
+ z = (F-N)/(2.0*(e-s+c*(f-n)));
+ m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z);
+ m_frustum_radius = m_frustum_center.distance(farpoint);
+ }
+ else
+ {
+ // orthographic projection
+ // The most extreme points on the near and far plane. (normalized device coords)
+ MT_Vector4 hnear(1., 1., 1., 1.), hfar(-1., -1., -1., 1.);
+
+ // Transform to hom camera local space
+ hnear = clip_camcs_matrix*hnear;
+ hfar = clip_camcs_matrix*hfar;
+
+ // Tranform to 3d camera local space.
+ MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]);
+ MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
+
+ // just use mediant point
+ m_frustum_center = (farpoint + nearpoint)*0.5;
+ m_frustum_radius = m_frustum_center.distance(farpoint);
+ }
// Transform to world space.
m_frustum_center = GetCameraToWorld()(m_frustum_center);
m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]);
@@ -474,11 +492,16 @@ PyMethodDef KX_Camera::Methods[] = {
KX_PYMETHODTABLE_O(KX_Camera, pointInsideFrustum),
KX_PYMETHODTABLE_NOARGS(KX_Camera, getCameraToWorld),
KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera),
- KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix),
- KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix),
- KX_PYMETHODTABLE_O(KX_Camera, enableViewport),
KX_PYMETHODTABLE(KX_Camera, setViewport),
KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop),
+ KX_PYMETHODTABLE_O(KX_Camera, getScreenPosition),
+ KX_PYMETHODTABLE(KX_Camera, getScreenVect),
+ KX_PYMETHODTABLE(KX_Camera, getScreenRay),
+
+ // DEPRECATED
+ KX_PYMETHODTABLE_O(KX_Camera, enableViewport),
+ KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix),
+ KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix),
{NULL,NULL} //Sentinel
};
@@ -492,7 +515,9 @@ PyAttributeDef KX_Camera::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("near", KX_Camera, pyattr_get_near, pyattr_set_near),
KX_PYATTRIBUTE_RW_FUNCTION("far", KX_Camera, pyattr_get_far, pyattr_set_far),
- KX_PYATTRIBUTE_RO_FUNCTION("projection_matrix", KX_Camera, pyattr_get_projection_matrix),
+ KX_PYATTRIBUTE_RW_FUNCTION("useViewport", KX_Camera, pyattr_get_use_viewport, pyattr_set_use_viewport),
+
+ KX_PYATTRIBUTE_RW_FUNCTION("projection_matrix", KX_Camera, pyattr_get_projection_matrix, pyattr_set_projection_matrix),
KX_PYATTRIBUTE_RO_FUNCTION("modelview_matrix", KX_Camera, pyattr_get_modelview_matrix),
KX_PYATTRIBUTE_RO_FUNCTION("camera_to_world", KX_Camera, pyattr_get_camera_to_world),
KX_PYATTRIBUTE_RO_FUNCTION("world_to_camera", KX_Camera, pyattr_get_world_to_camera),
@@ -506,8 +531,13 @@ PyAttributeDef KX_Camera::Attributes[] = {
};
PyTypeObject KX_Camera::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_Camera",
sizeof(PyObjectPlus_Proxy),
0,
@@ -544,6 +574,10 @@ PyObject* KX_Camera::py_getattro(PyObject *attr)
py_getattro_up(KX_GameObject);
}
+PyObject* KX_Camera::py_getattro_dict() {
+ py_getattro_dict_up(KX_GameObject);
+}
+
int KX_Camera::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(KX_GameObject);
@@ -678,6 +712,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getProjectionMatrix,
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
)
{
+ ShowDeprecationWarning("getProjectionMatrix()", "the projection_matrix property");
return PyObjectFrom(GetProjectionMatrix()); /* new ref */
}
@@ -723,6 +758,8 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, setProjectionMatrix,
"\tcam = co.getOwner()\n"
"\tcam.setProjectionMatrix(Perspective(-1.0, 1.0, -1.0, 1.0, 0.1, 1))\n")
{
+ ShowDeprecationWarning("setProjectionMatrix(mat)", "the projection_matrix property");
+
MT_Matrix4x4 mat;
if (!PyMatTo(value, mat))
{
@@ -739,8 +776,9 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport,
"Sets this camera's viewport status\n"
)
{
- int viewport = PyObject_IsTrue(value);
+ ShowDeprecationWarning("enableViewport(bool)", "the useViewport property");
+ int viewport = PyObject_IsTrue(value);
if (viewport == -1) {
PyErr_SetString(PyExc_ValueError, "camera.enableViewport(bool): KX_Camera, expected True/False or 0/1");
return NULL;
@@ -770,10 +808,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, setOnTop,
"setOnTop()\n"
"Sets this camera's viewport on top\n")
{
- class KX_Scene* scene;
-
- scene = KX_GetActiveScene();
- MT_assert(scene);
+ class KX_Scene* scene = KX_GetActiveScene();
scene->SetCameraOnTop(this);
Py_RETURN_NONE;
}
@@ -790,11 +825,11 @@ int KX_Camera::pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *at
int param = PyObject_IsTrue( value );
if (param == -1) {
PyErr_SetString(PyExc_AttributeError, "camera.perspective = bool: KX_Camera, expected True/False or 0/1");
- return -1;
+ return PY_SET_ATTR_FAIL;
}
self->m_camdata.m_perspective= param;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_Camera::pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -809,12 +844,12 @@ int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef,
float param = PyFloat_AsDouble(value);
if (param == -1) {
PyErr_SetString(PyExc_AttributeError, "camera.lens = float: KX_Camera, expected a float greater then zero");
- return -1;
+ return PY_SET_ATTR_FAIL;
}
self->m_camdata.m_lens= param;
self->m_set_projection_matrix = false;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_Camera::pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -829,12 +864,12 @@ int KX_Camera::pyattr_set_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef,
float param = PyFloat_AsDouble(value);
if (param == -1) {
PyErr_SetString(PyExc_AttributeError, "camera.near = float: KX_Camera, expected a float greater then zero");
- return -1;
+ return PY_SET_ATTR_FAIL;
}
self->m_camdata.m_clipstart= param;
self->m_set_projection_matrix = false;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_Camera::pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -849,14 +884,34 @@ int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, P
float param = PyFloat_AsDouble(value);
if (param == -1) {
PyErr_SetString(PyExc_AttributeError, "camera.far = float: KX_Camera, expected a float greater then zero");
- return -1;
+ return PY_SET_ATTR_FAIL;
}
self->m_camdata.m_clipend= param;
self->m_set_projection_matrix = false;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
+}
+
+
+PyObject* KX_Camera::pyattr_get_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self= static_cast<KX_Camera*>(self_v);
+ return PyBool_FromLong(self->GetViewport());
+}
+
+int KX_Camera::pyattr_set_use_viewport(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.useViewport = bool: KX_Camera, expected True or False");
+ return PY_SET_ATTR_FAIL;
+ }
+ self->EnableViewport((bool)param);
+ return PY_SET_ATTR_SUCCESS;
}
+
PyObject* KX_Camera::pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Camera* self= static_cast<KX_Camera*>(self_v);
@@ -868,10 +923,10 @@ int KX_Camera::pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_D
KX_Camera* self= static_cast<KX_Camera*>(self_v);
MT_Matrix4x4 mat;
if (!PyMatTo(value, mat))
- return -1;
+ return PY_SET_ATTR_FAIL;
self->SetProjectionMatrix(mat);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_Camera::pyattr_get_modelview_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -900,3 +955,197 @@ PyObject* KX_Camera::pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *
PyObject* KX_Camera::pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{ return PyInt_FromLong(INTERSECT); }
+
+bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix)
+{
+ if (value==NULL) {
+ PyErr_Format(PyExc_TypeError, "%s, python pointer NULL, should never happen", error_prefix);
+ *object = NULL;
+ return false;
+ }
+
+ if (value==Py_None) {
+ *object = NULL;
+
+ if (py_none_ok) {
+ return true;
+ } else {
+ PyErr_Format(PyExc_TypeError, "%s, expected KX_Camera or a KX_Camera name, None is invalid", error_prefix);
+ return false;
+ }
+ }
+
+ if (PyString_Check(value)) {
+ STR_String value_str = PyString_AsString(value);
+ *object = KX_GetActiveScene()->FindCamera(value_str);
+
+ if (*object) {
+ return true;
+ } else {
+ PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, PyString_AsString(value));
+ return false;
+ }
+ }
+
+ if (PyObject_TypeCheck(value, &KX_Camera::Type)) {
+ *object = static_cast<KX_Camera*>BGE_PROXY_REF(value);
+
+ /* sets the error */
+ if (*object==NULL) {
+ PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
+ return false;
+ }
+
+ return true;
+ }
+
+ *object = NULL;
+
+ if (py_none_ok) {
+ PyErr_Format(PyExc_TypeError, "%s, expect a KX_Camera, a string or None", error_prefix);
+ } else {
+ PyErr_Format(PyExc_TypeError, "%s, expect a KX_Camera or a string", error_prefix);
+ }
+
+ return false;
+}
+
+KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition,
+"getScreenPosition()\n"
+)
+
+{
+ MT_Vector3 vect;
+ KX_GameObject *obj = NULL;
+
+ if (!PyVecTo(value, vect))
+ {
+ if(ConvertPythonToGameObject(value, &obj, true, ""))
+ {
+ PyErr_Clear();
+ vect = MT_Vector3(obj->NodeGetWorldPosition());
+ }
+ else
+ {
+ PyErr_SetString(PyExc_TypeError, "Error in getScreenPosition. Expected a Vector3 or a KX_GameObject or a string for a name of a KX_GameObject");
+ return NULL;
+ }
+ }
+
+ GLint viewport[4];
+ GLdouble win[3];
+ GLdouble modelmatrix[16];
+ GLdouble projmatrix[16];
+
+ MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix();
+ MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
+
+ m_modelmatrix.getValue(modelmatrix);
+ m_projmatrix.getValue(projmatrix);
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+
+ gluProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]);
+
+ vect[0] = (win[0] - viewport[0]) / viewport[2];
+ vect[1] = (win[1] - viewport[1]) / viewport[3];
+
+ vect[1] = 1.0 - vect[1]; //to follow Blender window coordinate system (Top-Down)
+
+ PyObject* ret = PyTuple_New(2);
+ if(ret){
+ PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(vect[0]));
+ PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(vect[1]));
+ return ret;
+ }
+
+ return NULL;
+}
+
+KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect,
+"getScreenVect()\n"
+)
+{
+ double x,y;
+ if (!PyArg_ParseTuple(args,"dd:getScreenVect",&x,&y))
+ return NULL;
+
+ y = 1.0 - y; //to follow Blender window coordinate system (Top-Down)
+
+ MT_Vector3 vect;
+ MT_Point3 campos, screenpos;
+
+ GLint viewport[4];
+ GLdouble win[3];
+ GLdouble modelmatrix[16];
+ GLdouble projmatrix[16];
+
+ MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix();
+ MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
+
+ m_modelmatrix.getValue(modelmatrix);
+ m_projmatrix.getValue(projmatrix);
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+
+ vect[0] = x * viewport[2];
+ vect[1] = y * viewport[3];
+
+ vect[0] += viewport[0];
+ vect[1] += viewport[1];
+
+ glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vect[2]);
+ gluUnProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]);
+
+ campos = this->GetCameraLocation();
+ screenpos = MT_Point3(win[0], win[1], win[2]);
+ vect = campos-screenpos;
+
+ vect.normalize();
+ return PyObjectFrom(vect);
+}
+
+KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay,
+"getScreenRay()\n"
+)
+{
+ MT_Vector3 vect;
+ double x,y,dist;
+ char *propName = NULL;
+
+ if (!PyArg_ParseTuple(args,"ddd|s:getScreenRay",&x,&y,&dist,&propName))
+ return NULL;
+
+ PyObject* argValue = PyTuple_New(2);
+ if (argValue) {
+ PyTuple_SET_ITEM(argValue, 0, PyFloat_FromDouble(x));
+ PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(y));
+ }
+
+ if(!PyVecTo(PygetScreenVect(argValue), vect))
+ {
+ Py_DECREF(argValue);
+ PyErr_SetString(PyExc_TypeError,
+ "Error in getScreenRay. Invalid 2D coordinate. Expected a normalized 2D screen coordinate, a distance and an optional property argument");
+ return NULL;
+ }
+ Py_DECREF(argValue);
+
+ dist = -dist;
+ vect += this->GetCameraLocation();
+
+ argValue = (propName?PyTuple_New(3):PyTuple_New(2));
+ if (argValue) {
+ PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect));
+ PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist));
+ if (propName)
+ PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName));
+
+ PyObject* ret= this->PyrayCastTo(argValue,NULL);
+ Py_DECREF(argValue);
+ return ret;
+ }
+
+ return NULL;
+}
+
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index 4accd4bc2f1..aef21cd91e4 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -41,6 +41,9 @@
#include "IntValue.h"
#include "RAS_CameraData.h"
+/* utility conversion function */
+bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix);
+
class KX_Camera : public KX_GameObject
{
Py_Header;
@@ -110,6 +113,11 @@ protected:
bool m_set_frustum_center;
/**
+ * whether the camera should delete the node itself (only for shadow camera)
+ */
+ bool m_delete_node;
+
+ /**
* Extracts the camera clip frames from the projection and world-to-camera matrices.
*/
void ExtractClipPlanes();
@@ -135,7 +143,7 @@ public:
enum { INSIDE, INTERSECT, OUTSIDE } ;
- KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, PyTypeObject *T = &Type);
+ KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false, PyTypeObject *T = &Type);
virtual ~KX_Camera();
/**
@@ -146,15 +154,7 @@ public:
virtual CValue*
GetReplica(
);
-
- /**
- * Inherited from CValue -- Makes sure any internal
- * data owned by this class is deep copied. Called internally
- */
- virtual void
- ProcessReplica(
- KX_Camera* replica
- );
+ virtual void ProcessReplica();
MT_Transform GetWorldToCamera() const;
MT_Transform GetCameraToWorld() const;
@@ -193,6 +193,8 @@ public:
/** Gets the aperture. */
float GetLens() const;
+ /** Gets the ortho scale. */
+ float GetScale() const;
/** Gets the near clip distance. */
float GetCameraNear() const;
/** Gets the far clip distance. */
@@ -277,7 +279,12 @@ public:
KX_PYMETHOD_DOC_VARARGS(KX_Camera, setViewport);
KX_PYMETHOD_DOC_NOARGS(KX_Camera, setOnTop);
+ KX_PYMETHOD_DOC_O(KX_Camera, getScreenPosition);
+ KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenVect);
+ KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenRay);
+
virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
static PyObject* pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -290,6 +297,9 @@ public:
static PyObject* pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
static PyObject* pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 8ef9f318142..f8557dac2c4 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -82,8 +82,6 @@ GetReplica(
) {
KX_CameraActuator* replica = new KX_CameraActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
};
@@ -371,8 +369,13 @@ bool KX_CameraActuator::string2axischoice(const char *axisString)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_CameraActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_CameraActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -416,7 +419,7 @@ PyAttributeDef KX_CameraActuator::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_minHeight),
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_BOOL_RW("useXY",KX_CameraActuator,m_x),
KX_PYATTRIBUTE_RW_FUNCTION("object", KX_CameraActuator, pyattr_get_object, pyattr_set_object),
{NULL}
};
@@ -425,6 +428,10 @@ PyObject* KX_CameraActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_CameraActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_CameraActuator::py_setattro(PyObject *attr, PyObject* value) {
py_setattro_up(SCA_IActuator);
}
@@ -447,7 +454,7 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* args)
Py_RETURN_NONE;
if (ret_name_only)
- return PyString_FromString(m_ob->GetName());
+ return PyString_FromString(m_ob->GetName().ReadPtr());
else
return m_ob->GetProxy();
}
@@ -554,7 +561,7 @@ const char KX_CameraActuator::SetXY_doc[] =
"\t1=x, 0=y\n";
PyObject* KX_CameraActuator::PySetXY(PyObject* args)
{
- ShowDeprecationWarning("setXY()", "the xy property");
+ ShowDeprecationWarning("setXY()", "the useXY property");
int value;
if(PyArg_ParseTuple(args,"i:setXY", &value))
{
@@ -590,7 +597,7 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF
KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_CameraActuator"))
- return 1; // ConvertPythonToGameObject sets the error
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
if (self->m_ob)
self->m_ob->UnregisterActuator(self);
@@ -598,7 +605,7 @@ int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF
if ((self->m_ob = (SCA_IObject*)gameobj))
self->m_ob->RegisterActuator(self);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
/* eof */
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
index 9298e1e868d..efa4e2f38d7 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.h
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -121,6 +121,7 @@ private :
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
/* set object to look at */
diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
index 7345edb054b..077ac96f0ac 100644
--- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h
+++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
@@ -50,8 +50,9 @@ struct KX_ClientObjectInfo
STATIC,
ACTOR,
RESERVED1,
- RADAR,
- NEAR
+ SENSOR,
+ OBSENSOR,
+ OBACTORSENSOR
} m_type;
KX_GameObject* m_gameobject;
void* m_auxilary_info;
@@ -84,6 +85,7 @@ public:
}
bool isActor() { return m_type <= ACTOR; }
+ bool isSensor() { return m_type >= SENSOR && m_type <= OBACTORSENSOR; }
};
#endif //__KX_CLIENTOBJECT_INFO_H
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index c2b4db2de8e..bd03dea486b 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -565,8 +565,13 @@ bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_ConstraintActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_ConstraintActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -625,7 +630,7 @@ PyAttributeDef KX_ConstraintActuator::Attributes[] = {
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_STRING_RW("propName",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),
@@ -639,6 +644,10 @@ PyObject* KX_ConstraintActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_ConstraintActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_ConstraintActuator::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(SCA_IActuator);
@@ -749,9 +758,9 @@ PyObject* KX_ConstraintActuator::PyGetDirection(){
ShowDeprecationWarning("getDirection()", "the direction property");
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_refDirection[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_refDirection[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_refDirection[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_refDirection[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_refDirection[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_refDirection[2]));
return retVal;
}
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index 98f6fcd7906..40607b44947 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -132,8 +132,6 @@ protected:
virtual CValue* GetReplica() {
KX_ConstraintActuator* replica = new KX_ConstraintActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
};
@@ -144,6 +142,7 @@ protected:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
static int pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
index 7c3abb49159..c5cf67af67d 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
@@ -48,24 +48,48 @@ KX_ConstraintWrapper::KX_ConstraintWrapper(
KX_ConstraintWrapper::~KX_ConstraintWrapper()
{
}
-//python integration methods
-PyObject* KX_ConstraintWrapper::PyTestMethod(PyObject* args, PyObject* kwds)
-{
- Py_RETURN_NONE;
-}
-PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* args, PyObject* kwds)
+PyObject* KX_ConstraintWrapper::PyGetConstraintId()
{
return PyInt_FromLong(m_constraintId);
}
+PyObject* KX_ConstraintWrapper::PyGetParam(PyObject* args, PyObject* kwds)
+{
+ int dof;
+ float value;
+
+ if (!PyArg_ParseTuple(args,"i:getParam",&dof))
+ return NULL;
+
+ value = m_physenv->getConstraintParam(m_constraintId,dof);
+ return PyFloat_FromDouble(value);
+
+}
+
+PyObject* KX_ConstraintWrapper::PySetParam(PyObject* args, PyObject* kwds)
+{
+ int dof;
+ float minLimit,maxLimit;
+
+ if (!PyArg_ParseTuple(args,"iff:setParam",&dof,&minLimit,&maxLimit))
+ return NULL;
+
+ m_physenv->setConstraintParam(m_constraintId,dof,minLimit,maxLimit);
+ Py_RETURN_NONE;
+}
//python specific stuff
PyTypeObject KX_ConstraintWrapper::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_ConstraintWrapper",
sizeof(PyObjectPlus_Proxy),
0,
@@ -87,45 +111,33 @@ PyParentObject KX_ConstraintWrapper::Parents[] = {
NULL
};
-PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr)
+//here you can search for existing data members (like mass,friction etc.)
+PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr)
{
- //here you can search for existing data members (like mass,friction etc.)
py_getattro_up(PyObjectPlus);
}
-int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* pyobj)
+PyObject* KX_ConstraintWrapper::py_getattro_dict() {
+ py_getattro_dict_up(PyObjectPlus);
+}
+
+int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value)
{
- int result = 1;
- /* what the heck is this supposed to do?, needs attention */
- if (PyList_Check(pyobj))
- {
- result = 0;
- }
- if (PyFloat_Check(pyobj))
- {
- result = 0;
-
- }
- if (PyInt_Check(pyobj))
- {
- result = 0;
- }
- if (PyString_Check(pyobj))
- {
- result = 0;
- }
- if (result)
- result = PyObjectPlus::py_setattro(attr,pyobj);
- return result;
+ py_setattro_up(PyObjectPlus);
};
+
+
+
PyMethodDef KX_ConstraintWrapper::Methods[] = {
- {"testMethod",(PyCFunction) KX_ConstraintWrapper::sPyTestMethod, METH_VARARGS},
- {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS},
+ {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_NOARGS},
+ {"setParam",(PyCFunction) KX_ConstraintWrapper::sPySetParam, METH_VARARGS},
+ {"getParam",(PyCFunction) KX_ConstraintWrapper::sPyGetParam, METH_VARARGS},
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_ConstraintWrapper::Attributes[] = {
+ //KX_PYATTRIBUTE_TODO("constraintId"),
{ NULL } //Sentinel
};
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
index 6e67d842cb6..03813e0f167 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
@@ -36,14 +36,16 @@ class KX_ConstraintWrapper : public PyObjectPlus
{
Py_Header;
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
public:
KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
virtual ~KX_ConstraintWrapper ();
int getConstraintId() { return m_constraintId;};
- KX_PYMETHOD(KX_ConstraintWrapper,TestMethod);
- KX_PYMETHOD(KX_ConstraintWrapper,GetConstraintId);
+ KX_PYMETHOD_NOARGS(KX_ConstraintWrapper,GetConstraintId);
+ KX_PYMETHOD(KX_ConstraintWrapper,SetParam);
+ KX_PYMETHOD(KX_ConstraintWrapper,GetParam);
private:
int m_constraintId;
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
index 3534500e619..74042366bae 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -47,6 +47,7 @@
class RAS_MeshObject;
class KX_Scene;
+struct DerivedMesh;
typedef enum {
KX_BOUNDBOX,
@@ -82,6 +83,7 @@ struct KX_ObjectProperties
bool m_ghost;
class KX_GameObject* m_dynamic_parent;
bool m_isactor;
+ bool m_sensor;
bool m_concave;
bool m_isdeformable;
bool m_disableSleeping;
@@ -124,6 +126,7 @@ struct KX_ObjectProperties
float m_soft_kAHR; /* Anchors hardness [0,1] */
int m_soft_collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
int m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/
+ float m_soft_welding; /* threshold to remove duplicate/nearby vertices */
/////////////////////////
@@ -136,6 +139,8 @@ struct KX_ObjectProperties
/////////////////////////
double m_margin;
+ float m_contactProcessingThreshold;
+
KX_BoundBoxClass m_boundclass;
union {
KX_BoxBounds box;
@@ -182,6 +187,7 @@ bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj);
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
class RAS_MeshObject* meshobj,
+ struct DerivedMesh* dm,
class KX_Scene* kxscene,
struct PHY_ShapeProps* shapeprops,
struct PHY_MaterialProps* smmaterial,
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 08e2ea30414..51c41c0686d 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -34,7 +34,7 @@
// defines USE_ODE to choose physics engine
#include "KX_ConvertPhysicsObject.h"
-#include "KX_GameObject.h"
+#include "BL_DeformableGameObject.h"
#include "RAS_MeshObject.h"
#include "KX_Scene.h"
#include "SYS_System.h"
@@ -52,6 +52,10 @@
#include "KX_MotionState.h" // bridge between motionstate and scenegraph node
+extern "C"{
+ #include "BKE_DerivedMesh.h"
+}
+
#ifdef USE_ODE
#include "KX_OdePhysicsController.h"
@@ -670,11 +674,11 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
class KX_SoftBodyDeformer : public RAS_Deformer
{
- class RAS_MeshObject* m_pMeshObject;
- class KX_GameObject* m_gameobj;
+ class RAS_MeshObject* m_pMeshObject;
+ class BL_DeformableGameObject* m_gameobj;
public:
- KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,KX_GameObject* gameobj)
+ KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
:m_pMeshObject(pMeshObject),
m_gameobj(gameobj)
{
@@ -687,7 +691,15 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
};
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
{
- //printf("relink\n");
+ void **h_obj = (*map)[m_gameobj];
+
+ if (h_obj) {
+ m_gameobj = (BL_DeformableGameObject*)(*h_obj);
+ m_pMeshObject = m_gameobj->GetMesh(0);
+ } else {
+ m_gameobj = NULL;
+ m_pMeshObject = NULL;
+ }
}
virtual bool Apply(class RAS_IPolyMaterial *polymat)
{
@@ -749,14 +761,27 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
virtual bool Update(void)
{
//printf("update\n");
+ m_bDynamic = true;
return true;//??
}
- virtual RAS_Deformer *GetReplica(class KX_GameObject* replica)
+ virtual bool UpdateBuckets(void)
{
- KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(replica->GetMesh(0),replica);
- return deformer;
+ // this is to update the mesh slots outside the rasterizer,
+ // no need to do it for this deformer, it's done in any case in Apply()
+ return false;
}
+ virtual RAS_Deformer *GetReplica()
+ {
+ KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this);
+ deformer->ProcessReplica();
+ return deformer;
+ }
+ virtual void ProcessReplica()
+ {
+ // we have two pointers to deal with but we cannot do it now, will be done in Relink
+ m_bDynamic = false;
+ }
virtual bool SkipVertexTransform()
{
return true;
@@ -771,6 +796,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
class RAS_MeshObject* meshobj,
+ struct DerivedMesh* dm,
class KX_Scene* kxscene,
struct PHY_ShapeProps* shapeprops,
struct PHY_MaterialProps* smmaterial,
@@ -782,12 +808,12 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
bool isbulletdyna = false;
+ bool isbulletsensor = false;
CcdConstructionInfo ci;
class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
-
if (!objprop->m_dyna)
{
ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
@@ -806,6 +832,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_margin = objprop->m_margin;
shapeInfo->m_radius = objprop->m_radius;
isbulletdyna = objprop->m_dyna;
+ isbulletsensor = objprop->m_sensor;
ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
@@ -825,7 +852,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
//bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
- bm = shapeInfo->CreateBulletShape();
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
break;
};
case KX_BOUNDBOX:
@@ -838,7 +865,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
shapeInfo->m_halfExtend /= 2.0;
shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
shapeInfo->m_shapeType = PHY_SHAPE_BOX;
- bm = shapeInfo->CreateBulletShape();
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
break;
};
case KX_BOUNDCYLINDER:
@@ -849,7 +876,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
objprop->m_boundobject.c.m_height * 0.5f
);
shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
- bm = shapeInfo->CreateBulletShape();
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
break;
}
@@ -858,45 +885,41 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
shapeInfo->m_height = objprop->m_boundobject.c.m_height;
shapeInfo->m_shapeType = PHY_SHAPE_CONE;
- bm = shapeInfo->CreateBulletShape();
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
break;
}
case KX_BOUNDPOLYTOPE:
{
- shapeInfo->SetMesh(meshobj, true,false);
- bm = shapeInfo->CreateBulletShape();
+ shapeInfo->SetMesh(meshobj, dm,true,false);
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
break;
}
case KX_BOUNDMESH:
{
-
- if (!ci.m_mass ||objprop->m_softbody)
- {
- // mesh shapes can be shared, check first if we already have a shape on that mesh
- class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false);
- if (sharedShapeInfo != NULL)
- {
- delete shapeInfo;
- shapeInfo = sharedShapeInfo;
- shapeInfo->AddRef();
- } else
- {
- shapeInfo->SetMesh(meshobj, false,false);
- }
-
- // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
- if (objprop->m_softbody)
- shapeInfo->setVertexWeldingThreshold1(0.01f); //todo: expose this to the UI
+ bool useGimpact = ((ci.m_mass || isbulletsensor) && !objprop->m_softbody);
- bm = shapeInfo->CreateBulletShape();
- //no moving concave meshes, so don't bother calculating inertia
- //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+ // mesh shapes can be shared, check first if we already have a shape on that mesh
+ class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact);
+ if (sharedShapeInfo != NULL)
+ {
+ delete shapeInfo;
+ shapeInfo = sharedShapeInfo;
+ shapeInfo->AddRef();
} else
{
- shapeInfo->SetMesh(meshobj, false,true);
- bm = shapeInfo->CreateBulletShape();
+ shapeInfo->SetMesh(meshobj, dm, false,useGimpact);
+ }
+
+ // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
+ if (objprop->m_softbody)
+ {
+ shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
}
+ bm = shapeInfo->CreateBulletShape(ci.m_margin);
+ //should we compute inertia for dynamic shape?
+ //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+
break;
}
}
@@ -911,7 +934,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
return;
}
- bm->setMargin(ci.m_margin);
+ //bm->setMargin(ci.m_margin);
if (objprop->m_isCompoundChild)
@@ -926,39 +949,27 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
assert(colShape->isCompound());
btCompoundShape* compoundShape = (btCompoundShape*)colShape;
- // compute the local transform from parent, this may include a parent inverse node
+ // compute the local transform from parent, this may include several node in the chain
SG_Node* gameNode = gameobj->GetSGNode();
- SG_Node* parentInverseNode = gameNode->GetSGParent();
- if (parentInverseNode && parentInverseNode->GetSGClientObject() != NULL)
- // this is not a parent inverse node, cancel it
- parentInverseNode = NULL;
- // now combine the parent inverse node and the game node
- MT_Point3 childPos = gameNode->GetLocalPosition();
- MT_Matrix3x3 childRot = gameNode->GetLocalOrientation();
- MT_Vector3 childScale = gameNode->GetLocalScale();
- if (parentInverseNode)
- {
- const MT_Point3& parentInversePos = parentInverseNode->GetLocalPosition();
- const MT_Matrix3x3& parentInverseRot = parentInverseNode->GetLocalOrientation();
- const MT_Vector3& parentInverseScale = parentInverseNode->GetLocalScale();
- childRot = parentInverseRot * childRot;
- childScale = parentInverseScale * childScale;
- childPos = parentInversePos+parentInverseScale*(parentInverseRot*childPos);
- }
-
- shapeInfo->m_childScale.setValue(childScale.x(),childScale.y(),childScale.z());
+ SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode();
+ // relative transform
+ MT_Vector3 parentScale = parentNode->GetWorldScaling();
+ parentScale[0] = MT_Scalar(1.0)/parentScale[0];
+ parentScale[1] = MT_Scalar(1.0)/parentScale[1];
+ parentScale[2] = MT_Scalar(1.0)/parentScale[2];
+ MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
+ MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
+ MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
+ MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
+
+ shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
bm->setLocalScaling(shapeInfo->m_childScale);
-
- shapeInfo->m_childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
- float rotval[12];
- childRot.getValue(rotval);
- btMatrix3x3 newRot;
- newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]);
- newRot = newRot.transpose();
-
- shapeInfo->m_childTrans.setBasis(newRot);
+ shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
+ float rot[12];
+ relativeRot.getValue(rot);
+ shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
+
parentShapeInfo->AddShape(shapeInfo);
-
compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
//do some recalc?
//recalc inertia for rigidbody
@@ -969,6 +980,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
compoundShape->calculateLocalInertia(mass,localInertia);
rigidbody->setMassProps(mass,localInertia);
}
+ // delete motionstate as it's not used
+ delete motionstate;
return;
}
@@ -1081,26 +1094,32 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/
////////////////////
-
- ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
- ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
+ ci.m_collisionFilterGroup =
+ (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
+ (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) :
+ short(CcdConstructionInfo::StaticFilter);
+ ci.m_collisionFilterMask =
+ (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
+ (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) :
+ short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
+
+ ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so
ci.m_bSoft = objprop->m_softbody;
+ ci.m_bSensor = isbulletsensor;
MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
- KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,objprop->m_hasCompoundChildren);
+ KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren);
// shapeInfo is reference counted, decrement now as we don't use it anymore
if (shapeInfo)
shapeInfo->Release();
- if (objprop->m_in_active_layer)
+ gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
+ // don't add automatically sensor object, they are added when a collision sensor is registered
+ if (!isbulletsensor && objprop->m_in_active_layer)
{
env->addCcdPhysicsController( physicscontroller);
}
-
-
-
- gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
physicscontroller->setNewClientInfo(gameobj->getClientInfo());
{
btRigidBody* rbody = physicscontroller->GetRigidBody();
@@ -1159,7 +1178,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
}
bool isActor = objprop->m_isactor;
- gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
+ gameobj->getClientInfo()->m_type =
+ (isbulletsensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) :
+ (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC;
// store materialname in auxinfo, needed for touchsensors
if (meshobj)
{
@@ -1187,9 +1208,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
{
//should be a mesh then, so add a soft body deformer
- KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),gameobj);
+ KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
gameobj->SetDeformer(softbodyDeformer);
-
}
}
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
index 321370f9f3f..daa31379985 100644
--- a/source/gameengine/Ketsji/KX_Dome.cpp
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -43,29 +43,30 @@ KX_Dome::KX_Dome (
RAS_IRenderTools* rendertools,
/// engine
KX_KetsjiEngine* engine,
-
- float size, //size for adjustments
+
short res, //resolution of the mesh
short mode, //mode - fisheye, truncated, warped, panoramic, ...
short angle,
float resbuf, //size adjustment of the buffer
+ short tilt,
struct Text* warptext
):
- m_canvas(canvas),
- m_rasterizer(rasterizer),
- m_rendertools(rendertools),
- m_engine(engine),
+ dlistSupported(false),
+ canvaswidth(-1), canvasheight(-1),
m_drawingmode(engine->GetDrawType()),
- m_size(size),
m_resolution(res),
m_mode(mode),
m_angle(angle),
m_resbuffer(resbuf),
- canvaswidth(-1), canvasheight(-1),
- dlistSupported(false)
+ m_tilt(tilt),
+ m_canvas(canvas),
+ m_rasterizer(rasterizer),
+ m_rendertools(rendertools),
+ m_engine(engine)
{
warp.usemesh = false;
+ fboSupported = false;
if (mode >= DOME_NUM_MODES)
m_mode = DOME_FISHEYE;
@@ -107,15 +108,9 @@ KX_Dome::KX_Dome (
CreateMeshDome250();
m_numfaces = 5;
} break;
- case DOME_TRUNCATED:
- cubetop.resize(1);
- cubebottom.resize(1);
- cubeleft.resize(2);
- cuberight.resize(2);
-
- m_angle = 180;
- CreateMeshDome180();
- m_numfaces = 4;
+ case DOME_ENVMAP:
+ m_angle = 360;
+ m_numfaces = 6;
break;
case DOME_PANORAM_SPH:
cubeleft.resize(2);
@@ -129,6 +124,25 @@ KX_Dome::KX_Dome (
CreateMeshPanorama();
m_numfaces = 6;
break;
+ default: //DOME_TRUNCATED_FRONT and DOME_TRUNCATED_REAR
+ 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;
}
m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces);
@@ -137,23 +151,27 @@ KX_Dome::KX_Dome (
CreateGLImages();
+ if(warp.usemesh)
+ fboSupported = CreateFBO();
+
dlistSupported = CreateDL();
}
// destructor
KX_Dome::~KX_Dome (void)
{
- GLuint m_numimages = m_numfaces;
-
ClearGLImages();
+ if(fboSupported)
+ glDeleteFramebuffersEXT(1, &warp.fboId);
+
if(dlistSupported)
glDeleteLists(dlistId, (GLsizei) m_numimages);
}
void KX_Dome::SetViewPort(GLuint viewport[4])
{
- if(canvaswidth != m_canvas->GetWidth() || canvasheight != m_canvas->GetHeight())
+ if(canvaswidth != m_viewport.GetWidth() || canvasheight != m_viewport.GetHeight())
{
m_viewport.SetLeft(viewport[0]);
m_viewport.SetBottom(viewport[1]);
@@ -180,9 +198,9 @@ void KX_Dome::CreateGLImages(void)
}
if(warp.usemesh){
glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagewidth, warp.imageheight, 0, GL_RGB8,
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagesize, warp.imagesize, 0, GL_RGB8,
GL_UNSIGNED_BYTE, 0);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagewidth, warp.imageheight, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagesize, warp.imagesize, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -207,12 +225,25 @@ void KX_Dome::CalculateImageSize(void)
- reduce the buffer for better performace
- create a power of 2 texture bigger than the buffer
*/
+/*
+Blender handles Canvas size differently when in fullscreen mode.
+We are manually checking for that. Although it's a hack, it works.
+
+Bug reported here: #18655 - Inconsistency of pixels in canvas dimensions when in maximized mode (affecting BGE Dome)
+http://projects.blender.org/tracker/?func=detail&aid=18655&group_id=9&atid=125
+*/
canvaswidth = m_canvas->GetWidth();
canvasheight = m_canvas->GetHeight();
+ bool fullscreen(false); //XXX HACK
+ fullscreen = (canvaswidth != m_viewport.GetWidth());
+
m_buffersize = (canvaswidth > canvasheight?canvasheight:canvaswidth);
- m_buffersize *= m_resbuffer; //reduce buffer size for better performance
+ m_buffersize = (int)(m_buffersize*m_resbuffer); //reduce buffer size for better performance
+
+ if (fullscreen) //XXX HACK
+ m_buffersize --;
int i = 0;
while ((1 << i) <= m_buffersize)
@@ -220,27 +251,25 @@ void KX_Dome::CalculateImageSize(void)
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);
+ // warp FBO needs to be up to twice as big as m_buffersize to get more resolution
+ warp.imagesize = m_imagesize;
+ if (m_buffersize == m_imagesize)
+ warp.imagesize *= 2;
- i = 0;
- while ((1 << i) <= warp.bufferheight)
- i++;
- warp.imageheight = (1 << i);
+ //if FBO is not working/supported, we use the canvas dimension as buffer
+ warp.bufferwidth = canvaswidth;
+ warp.bufferheight = canvasheight;
}
+
+ //XXX HACK
+ canvaswidth = m_viewport.GetWidth();
+ canvasheight = m_viewport.GetHeight();
}
bool KX_Dome::CreateDL(){
- int i,j;
-
dlistId = glGenLists((GLsizei) m_numimages);
if (dlistId != 0) {
- if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED){
+ if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_FRONT || m_mode == DOME_TRUNCATED_REAR){
glNewList(dlistId, GL_COMPILE);
GLDrawTriangles(cubetop, nfacestop);
glEndList();
@@ -312,6 +341,46 @@ bool KX_Dome::CreateDL(){
return true;
}
+bool KX_Dome::CreateFBO(void)
+{
+ if (!GLEW_EXT_framebuffer_object)
+ {
+ printf("Dome Error: FrameBuffer unsupported. Using low resolution warp image.");
+ return false;
+ }
+
+ glGenFramebuffersEXT(1, &warp.fboId);
+ if(warp.fboId==0)
+ {
+ printf("Dome Error: Invalid frame buffer object. Using low resolution warp image.");
+ return false;
+ }
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, domefacesId[m_numfaces], 0);
+
+ GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+
+ if(status == GL_FRAMEBUFFER_UNSUPPORTED_EXT)
+ {
+ printf("Dome Error: FrameBuffer settings unsupported. Using low resolution warp image.");
+ return false;
+ }
+ else if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
+ {
+ glDeleteFramebuffersEXT(1, &warp.fboId);
+ return false;
+ }
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ //nothing failed: we can use the whole FBO as buffersize
+ warp.bufferwidth = warp.bufferheight = warp.imagesize;
+ return true;
+}
+
void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces)
{
int i,j;
@@ -328,8 +397,9 @@ void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces)
void KX_Dome::GLDrawWarpQuads(void)
{
int i, j, i2;
- float uv_width = (float)(warp.bufferwidth-1) / warp.imagewidth;
- float uv_height = (float)(warp.bufferheight-1) / warp.imageheight;
+
+ float uv_width = (float)(warp.bufferwidth) / warp.imagesize;
+ float uv_height = (float)(warp.bufferheight) / warp.imagesize;
if(warp.mode ==2 ){
glBegin(GL_QUADS);
@@ -386,7 +456,7 @@ void KX_Dome::GLDrawWarpQuads(void)
}
glEnd();
} else{
- printf("Error: Warp Mode unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n");
+ printf("Dome Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode);
}
}
@@ -415,20 +485,22 @@ y varies from -1 to 1
u and v vary from 0 to 1
i ranges from 0 to 1, if negative don't draw that mesh node
*/
- int i,j,k;
+ int i;
int nodeX=0, nodeY=0;
vector<STR_String> columns, lines;
lines = text.Explode('\n');
if(lines.size() < 6){
- printf("Error: Warp Mesh File with insufficient data!\n");
+ printf("Dome Error: Warp Mesh File with insufficient data!\n");
return false;
}
columns = lines[1].Explode(' ');
+ if(columns.size() == 1)
+ columns = lines[1].Explode('\t');
if(columns.size() !=2){
- printf("Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
+ printf("Dome Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
return false;
}
@@ -437,14 +509,16 @@ i ranges from 0 to 1, if negative don't draw that mesh node
warp.n_width = atoi(columns[0]);
warp.n_height = atoi(columns[1]);
- if (lines.size() < 2 + (warp.n_width * warp.n_height)){
- printf("Error: Warp Mesh File with insufficient data!\n");
+ if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)){
+ printf("Dome 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() == 1)
+ columns = lines[i].Explode('\t');
if (columns.size() == 5){
nodeX = (i-2)%warp.n_width;
@@ -458,7 +532,7 @@ i ranges from 0 to 1, if negative don't draw that mesh node
}
else{
warp.nodes.clear();
- printf("Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
+ printf("Dome Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
return false;
}
}
@@ -1373,7 +1447,7 @@ void KX_Dome::CalculateFrustum(KX_Camera * cam)
/*
// manually creating a 90º Field of View Frustum
- the original formula:
+ the original formula:
top = tan(fov*3.14159/360.0) * near [for fov in degrees]
fov*0.5 = arctan ((top-bottom)*0.5 / near) [for fov in radians]
bottom = -top
@@ -1411,11 +1485,14 @@ Uses 4 cameras for angles up to 180º
Uses 5 cameras for angles up to 250º
Uses 6 cameras for angles up to 360º
*/
+ int i;
float deg45 = MT_PI / 4;
MT_Scalar c = cos(deg45);
MT_Scalar s = sin(deg45);
- if ((m_mode == DOME_FISHEYE && m_angle <= 180)|| m_mode == DOME_TRUNCATED){
+ if (m_angle <= 180 && (m_mode == DOME_FISHEYE
+ || m_mode == DOME_TRUNCATED_FRONT
+ || m_mode == DOME_TRUNCATED_REAR)){
m_locRot[0] = MT_Matrix3x3( // 90º - Top
c, -s, 0.0,
@@ -1437,7 +1514,9 @@ Uses 6 cameras for angles up to 360º
0.0, 1.0, 0.0,
s, 0.0, c);
- } else if ((m_mode == DOME_FISHEYE && m_angle > 180)){
+ } else if (m_mode == DOME_ENVMAP || (m_angle > 180 && (m_mode == DOME_FISHEYE
+ || m_mode == DOME_TRUNCATED_FRONT
+ || m_mode == DOME_TRUNCATED_REAR))){
m_locRot[0] = MT_Matrix3x3( // 90º - Top
1.0, 0.0, 0.0,
@@ -1464,7 +1543,7 @@ Uses 6 cameras for angles up to 360º
0.0, 1.0, 0.0,
0.0, 0.0, 1.0);
- m_locRot[5] = MT_Matrix3x3( // 180º - Back - NOT USING
+ m_locRot[5] = MT_Matrix3x3( // 180º - Back - USED for ENVMAP only
-1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0,-1.0);
@@ -1501,6 +1580,23 @@ Uses 6 cameras for angles up to 360º
0.0, 1.0, 0.0,
s, 0.0, c);
}
+
+ // rotating the camera in horizontal axis
+ if (m_tilt)
+ {
+ float tiltdeg = ((m_tilt % 360) * 2 * MT_PI) / 360;
+ c = cos(tiltdeg);
+ s = sin(tiltdeg);
+
+ MT_Matrix3x3 tilt_mat = MT_Matrix3x3(
+ 1.0, 0.0, 0.0,
+ 0.0, c, -s,
+ 0.0, s, c
+ );
+
+ for (i =0;i<6;i++)
+ m_locRot[i] = tilt_mat * m_locRot[i];
+ }
}
void KX_Dome::RotateCamera(KX_Camera* cam, int i)
@@ -1515,8 +1611,7 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i)
MT_Transform camtrans(cam->GetWorldToCamera());
MT_Matrix4x4 viewmat(camtrans);
- m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
- cam->GetCameraLocation(), cam->GetCameraOrientation());
+ m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
cam->SetModelviewMatrix(viewmat);
// restore the original orientation
@@ -1527,30 +1622,49 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i)
void KX_Dome::Draw(void)
{
+ if (fboSupported){
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId);
+
+ glViewport(0,0,warp.imagesize, warp.imagesize);
+ glScissor(0,0,warp.imagesize, warp.imagesize);
+ }
+
switch(m_mode){
case DOME_FISHEYE:
DrawDomeFisheye();
break;
- case DOME_TRUNCATED:
- DrawDomeFisheye();
+ case DOME_ENVMAP:
+ DrawEnvMap();
break;
case DOME_PANORAM_SPH:
DrawPanorama();
break;
+ case DOME_TRUNCATED_FRONT:
+ DrawDomeFisheye();
+ break;
+ case DOME_TRUNCATED_REAR:
+ DrawDomeFisheye();
+ 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);
+ if(fboSupported)
+ {
+ m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), warp.bufferwidth, warp.bufferheight);
+ }
DrawDomeWarped();
}
}
-void KX_Dome::DrawDomeFisheye(void)
+void KX_Dome::DrawEnvMap(void)
{
- int i,j;
-
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -1563,28 +1677,17 @@ void KX_Dome::DrawDomeFisheye(void)
float ortho_width, ortho_height;
if (warp.usemesh)
- glOrtho((-1.0), 1.0, (-1.0), 1.0, -20.0, 10.0); //stretch the image to reduce resolution lost
+ glOrtho((-1.0), 1.0, (-0.66), 0.66, -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){
+ else {
+ if (can_width/3 <= can_height/2){
ortho_width = 1.0;
ortho_height = (float)can_height/can_width;
}else{
- ortho_width = (float)can_width/can_height;
- ortho_height = 1.0;
+ ortho_height = 2.0f / 3;
+ ortho_width = (float)can_width/can_height * ortho_height;
}
- ortho_width /= m_size;
- ortho_height /= m_size;
-
glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0);
}
@@ -1592,6 +1695,150 @@ void KX_Dome::DrawDomeFisheye(void)
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+ gluLookAt(0.0,0.0,1.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
+
+ glPolygonMode(GL_FRONT, GL_FILL);
+ glShadeModel(GL_SMOOTH);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_DEPTH_TEST);
+
+ glEnable(GL_TEXTURE_2D);
+ glColor3f(1.0,1.0,1.0);
+
+ float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
+ double onebythree = 1.0f / 3;
+
+ // domefacesId[0] => (top)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[0]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_ratio,uv_ratio);
+ glVertex3f( onebythree, 0.0f, 3.0f);
+ glTexCoord2f(0.0,uv_ratio);
+ glVertex3f(-onebythree, 0.0f, 3.0f);
+ glTexCoord2f(0.0,0.0);
+ glVertex3f(-onebythree,-2 * onebythree, 3.0f);
+ glTexCoord2f(uv_ratio,0.0);
+ glVertex3f(onebythree,-2 * onebythree, 3.0f);
+ glEnd();
+
+ // domefacesId[1] => (bottom)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_ratio,uv_ratio);
+ glVertex3f(-onebythree, 0.0f, 3.0f);
+ glTexCoord2f(0.0,uv_ratio);
+ glVertex3f(-1.0f, 0.0f, 3.0f);
+ glTexCoord2f(0.0,0.0);
+ glVertex3f(-1.0f,-2 * onebythree, 3.0f);
+ glTexCoord2f(uv_ratio,0.0);
+ glVertex3f(-onebythree,-2 * onebythree, 3.0f);
+ glEnd();
+
+ // domefacesId[2] => -90º (left)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_ratio,uv_ratio);
+ glVertex3f(-onebythree, 2 * onebythree, 3.0f);
+ glTexCoord2f(0.0,uv_ratio);
+ glVertex3f(-1.0f, 2 * onebythree, 3.0f);
+ glTexCoord2f(0.0,0.0);
+ glVertex3f(-1.0f, 0.0f, 3.0f);
+ glTexCoord2f(uv_ratio,0.0);
+ glVertex3f(-onebythree, 0.0f, 3.0f);
+ glEnd();
+
+ // domefacesId[3] => 90º (right)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_ratio,uv_ratio);
+ glVertex3f( 1.0f, 2 * onebythree, 3.0f);
+ glTexCoord2f(0.0,uv_ratio);
+ glVertex3f( onebythree, 2 * onebythree, 3.0f);
+ glTexCoord2f(0.0,0.0);
+ glVertex3f( onebythree, 0.0f, 3.0f);
+ glTexCoord2f(uv_ratio,0.0);
+ glVertex3f(1.0f, 0.0f, 3.0f);
+ glEnd();
+
+ // domefacesId[4] => 0º (front)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_ratio,uv_ratio);
+ glVertex3f( 1.0f, 0.0f, 3.0f);
+ glTexCoord2f(0.0,uv_ratio);
+ glVertex3f( onebythree, 0.0f, 3.0f);
+ glTexCoord2f(0.0,0.0);
+ glVertex3f( onebythree,-2 * onebythree, 3.0f);
+ glTexCoord2f(uv_ratio,0.0);
+ glVertex3f(1.0f, -2 * onebythree, 3.0f);
+ glEnd();
+
+ // domefacesId[5] => 180º (back)
+ glBindTexture(GL_TEXTURE_2D, domefacesId[5]);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_ratio,uv_ratio);
+ glVertex3f( onebythree, 2 * onebythree, 3.0f);
+ glTexCoord2f(0.0,uv_ratio);
+ glVertex3f(-onebythree, 2 * onebythree, 3.0f);
+ glTexCoord2f(0.0,0.0);
+ glVertex3f(-onebythree, 0.0f, 3.0f);
+ glTexCoord2f(uv_ratio,0.0);
+ glVertex3f(onebythree, 0.0f, 3.0f);
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void KX_Dome::DrawDomeFisheye(void)
+{
+ int i;
+
+ 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(m_mode == DOME_FISHEYE) {
+ if (warp.usemesh)
+ glOrtho((-1.0), 1.0, (-1.0), 1.0, -20.0, 10.0); //stretch the image to reduce resolution lost
+
+ else {
+ if (can_width < can_height){
+ ortho_width = 1.0;
+ ortho_height = (float)can_height/can_width;
+ }else{
+ ortho_width = (float)can_width/can_height;
+ ortho_height = 1.0;
+ }
+
+ glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0);
+ }
+ }
+ else if(m_mode == DOME_TRUNCATED_FRONT)
+ {
+ ortho_width = 1.0;
+ ortho_height = 2 * ((float)can_height/can_width) - 1.0 ;
+
+ glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0);
+ }
+ else { //m_mode == DOME_TRUNCATED_REAR
+ ortho_width = 1.0;
+ ortho_height = 2 * ((float)can_height/can_width) - 1.0 ;
+
+ glOrtho((-ortho_width), ortho_width, (-ortho_width), ortho_height, -20.0, 10.0);
+ }
+
+ glMatrixMode(GL_TEXTURE);
+ 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)
@@ -1641,7 +1888,7 @@ void KX_Dome::DrawDomeFisheye(void)
void KX_Dome::DrawPanorama(void)
{
- int i,j;
+ int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -1666,9 +1913,6 @@ void KX_Dome::DrawPanorama(void)
ortho_width = (float)can_width/can_height * 0.5;
ortho_height = 0.5;
}
-
- ortho_width /= m_size;
- ortho_height /= m_size;
glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0);
}
@@ -1728,8 +1972,6 @@ void KX_Dome::DrawPanorama(void)
void KX_Dome::DrawDomeWarped(void)
{
- int i,j;
-
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -1739,7 +1981,6 @@ void KX_Dome::DrawDomeWarped(void)
int can_height = m_viewport.GetTop();
double screen_ratio = can_width/ (double) can_height;
- screen_ratio /= m_size;
glOrtho(-screen_ratio,screen_ratio,-1.0,1.0,-20.0,10.0);
@@ -1762,10 +2003,6 @@ void KX_Dome::DrawDomeWarped(void)
glEnable(GL_TEXTURE_2D);
glColor3f(1.0,1.0,1.0);
-
- float uv_width = (float)(warp.bufferwidth-1) / warp.imagewidth;
- float uv_height = (float)(warp.bufferheight-1) / warp.imageheight;
-
if (dlistSupported){
glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
glCallList(dlistId + m_numfaces);
@@ -1806,8 +2043,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
MT_Transform camtrans(cam->GetWorldToCamera());
MT_Matrix4x4 viewmat(camtrans);
- m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
- cam->GetCameraLocation(), cam->GetCameraOrientation());
+ m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), 1.0);
cam->SetModelviewMatrix(viewmat);
scene->CalculateVisibleMeshes(m_rasterizer,cam);
@@ -1816,4 +2052,5 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
// restore the original orientation
cam->NodeSetLocalOrientation(camori);
cam->NodeUpdateGS(0.f);
-} \ No newline at end of file
+}
+
diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h
index 786e04b4385..20b60ef0173 100644
--- a/source/gameengine/Ketsji/KX_Dome.h
+++ b/source/gameengine/Ketsji/KX_Dome.h
@@ -38,13 +38,14 @@ Developed as part of a Research and Development project for SAT - La Société des
#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
+#define DOME_FISHEYE 1
+#define DOME_TRUNCATED_FRONT 2
+#define DOME_TRUNCATED_REAR 3
+#define DOME_ENVMAP 4
+#define DOME_PANORAM_SPH 5
+#define DOME_NUM_MODES 6
/// class for render 3d scene
@@ -60,12 +61,12 @@ public:
RAS_IRenderTools* m_rendertools,
/// engine
KX_KetsjiEngine* m_engine,
-
- float size,
+
short res,
short mode,
short angle,
float resbuf,
+ short tilt,
struct Text* warptext
);
@@ -74,6 +75,7 @@ public:
//openGL checks:
bool dlistSupported;
+ bool fboSupported;
//openGL names:
GLuint domefacesId[7]; // ID of the images -- room for 7 images, using only 4 for 180º x 360º dome, 6 for panoramic and +1 for warp mesh
@@ -93,8 +95,9 @@ public:
bool usemesh;
int mode;
int n_width, n_height; //nodes width and height
- int imagewidth, imageheight;
+ int imagesize;
int bufferwidth, bufferheight;
+ GLuint fboId;
vector <vector <WarpMeshNode> > nodes;
} warp;
@@ -116,7 +119,7 @@ public:
void CalculateFrustum(KX_Camera* cam);
void RotateCamera(KX_Camera* cam, int i);
- //Mesh Creating Functions
+ //Mesh creation Functions
void CreateMeshDome180(void);
void CreateMeshDome250(void);
void CreateMeshPanorama(void);
@@ -131,6 +134,7 @@ public:
void GLDrawWarpQuads(void);
void Draw(void);
void DrawDomeFisheye(void);
+ void DrawEnvMap(void);
void DrawPanorama(void);
void DrawDomeWarped(void);
@@ -139,6 +143,8 @@ public:
void ClearGLImages(void);//called on resize
bool CreateDL(void); //create Display Lists
void ClearDL(void); //remove Display Lists
+ bool CreateFBO(void);//create FBO (for warp mesh)
+ void ClearFBO(void); //remove FBO
void CalculateCameraOrientation();
void CalculateImageSize(); //set m_imagesize
@@ -153,13 +159,13 @@ protected:
int m_buffersize; // canvas small dimension
int m_numfaces; // 4 to 6 depending on the kind of dome image
int m_numimages; //numfaces +1 if we have warp mesh
-
- float m_size; // size to adjust
+
short m_resolution; //resolution to tesselate the mesh
short m_mode; // the mode (truncated, warped, panoramic,...)
short m_angle; //the angle of the fisheye
float m_radangle; //the angle of the fisheye in radians
float m_resbuffer; //the resolution of the buffer
+ short m_tilt; //the dome tilt (camera rotation on horizontal axis)
RAS_Rect m_viewport;
@@ -181,3 +187,4 @@ protected:
};
#endif
+
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index 8b587c6f7de..28bf12f5e87 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -73,8 +73,6 @@ CValue* KX_GameActuator::GetReplica()
{
KX_GameActuator* replica = new KX_GameActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
}
@@ -151,6 +149,8 @@ bool KX_GameActuator::Update()
} else {
printf("Warning: could not create marshal buffer\n");
}
+ if (marshal_buffer)
+ delete [] marshal_buffer;
}
break;
}
@@ -208,8 +208,13 @@ bool KX_GameActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_GameActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_GameActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -249,16 +254,20 @@ PyMethodDef KX_GameActuator::Methods[] =
};
PyAttributeDef KX_GameActuator::Attributes[] = {
- KX_PYATTRIBUTE_STRING_RW("file",0,100,false,KX_GameActuator,m_filename),
+ KX_PYATTRIBUTE_STRING_RW("fileName",0,100,false,KX_GameActuator,m_filename),
+ KX_PYATTRIBUTE_INT_RW("mode", KX_GAME_NODEF+1, KX_GAME_MAX-1, true, KX_GameActuator, m_mode),
{ NULL } //Sentinel
};
-PyObject*
-KX_GameActuator::py_getattro(PyObject *attr)
+PyObject* KX_GameActuator::py_getattro(PyObject *attr)
{
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_GameActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_GameActuator::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_IActuator);
@@ -272,7 +281,7 @@ const char KX_GameActuator::GetFile_doc[] =
"get the name of the file to start.\n";
PyObject* KX_GameActuator::PyGetFile(PyObject* args, PyObject* kwds)
{
- ShowDeprecationWarning("getFile()", "the file property");
+ ShowDeprecationWarning("getFile()", "the fileName property");
return PyString_FromString(m_filename);
}
@@ -284,7 +293,7 @@ PyObject* KX_GameActuator::PySetFile(PyObject* args, PyObject* kwds)
{
char* new_file;
- ShowDeprecationWarning("setFile()", "the file property");
+ ShowDeprecationWarning("setFile()", "the fileName property");
if (!PyArg_ParseTuple(args, "s:setFile", &new_file))
{
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
index 570cb2e68ef..b2b1d6ec2b9 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.h
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -78,6 +78,7 @@ protected:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// Deprecated functions ----->
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index bea0fcff2af..7f417b325c8 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -49,6 +49,8 @@ typedef unsigned long uint_ptr;
#include "RAS_IPolygonMaterial.h"
#include "KX_BlenderMaterial.h"
#include "KX_GameObject.h"
+#include "KX_Camera.h" // only for their ::Type
+#include "KX_Light.h" // only for their ::Type
#include "RAS_MeshObject.h"
#include "KX_MeshProxy.h"
#include "KX_PolyProxy.h"
@@ -63,6 +65,7 @@ typedef unsigned long uint_ptr;
#include "KX_RayCast.h"
#include "KX_PythonInit.h"
#include "KX_PyMath.h"
+#include "KX_PythonSeq.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
#include "SCA_IController.h"
@@ -187,38 +190,23 @@ double KX_GameObject::GetNumber()
-STR_String KX_GameObject::GetName()
+STR_String& KX_GameObject::GetName()
{
return m_name;
}
-void KX_GameObject::SetName(STR_String name)
+void KX_GameObject::SetName(const char *name)
{
m_name = name;
}; // Set the name of the value
-
-
-void KX_GameObject::ReplicaSetName(STR_String name)
-{
-}
-
-
-
-
-
-
KX_IPhysicsController* KX_GameObject::GetPhysicsController()
{
return m_pPhysicsController1;
}
-
-
-
-
KX_GameObject* KX_GameObject::GetParent()
{
KX_GameObject* result = NULL;
@@ -238,7 +226,7 @@ KX_GameObject* KX_GameObject::GetParent()
}
-void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
+void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj, bool addToCompound, bool ghost)
{
// check on valid node in case a python controller holds a reference to a deleted object
if (obj && GetSGNode() && obj->GetSGNode() && GetSGNode()->GetSGParent() != obj->GetSGNode())
@@ -259,7 +247,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
if (m_pPhysicsController1)
{
- m_pPhysicsController1->SuspendDynamics(true);
+ m_pPhysicsController1->SuspendDynamics(ghost);
}
// Set us to our new scale, position, and orientation
scale2[0] = 1.0/scale2[0];
@@ -280,7 +268,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
Release();
// if the new parent is a compound object, add this object shape to the compound shape.
// step 0: verify this object has physical controller
- if (m_pPhysicsController1)
+ if (m_pPhysicsController1 && addToCompound)
{
// step 1: find the top parent (not necessarily obj)
KX_GameObject* rootobj = (KX_GameObject*)obj->GetSGNode()->GetRootSGParent()->GetSGClientObject();
@@ -326,33 +314,75 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
rootobj->m_pPhysicsController1->RemoveCompoundChild(m_pPhysicsController1);
}
m_pPhysicsController1->RestoreDynamics();
+ if (m_pPhysicsController1->IsDyna() && rootobj->m_pPhysicsController1)
+ {
+ // dynamic object should remember the velocity they had while being parented
+ MT_Point3 childPoint = GetSGNode()->GetWorldPosition();
+ MT_Point3 rootPoint = rootobj->GetSGNode()->GetWorldPosition();
+ MT_Point3 relPoint;
+ relPoint = (childPoint-rootPoint);
+ MT_Vector3 linVel = rootobj->m_pPhysicsController1->GetVelocity(relPoint);
+ MT_Vector3 angVel = rootobj->m_pPhysicsController1->GetAngularVelocity();
+ m_pPhysicsController1->SetLinearVelocity(linVel, false);
+ m_pPhysicsController1->SetAngularVelocity(angVel, false);
+ }
}
// graphically, the object hasn't change place, no need to update m_pGraphicController
}
}
-void KX_GameObject::ProcessReplica(KX_GameObject* replica)
+void KX_GameObject::ProcessReplica()
{
- replica->m_pPhysicsController1 = NULL;
- replica->m_pGraphicController = NULL;
- replica->m_pSGNode = NULL;
- replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
- replica->m_pClient_info->m_gameobject = replica;
- replica->m_state = 0;
+ SCA_IObject::ProcessReplica();
+
+ m_pPhysicsController1 = NULL;
+ m_pGraphicController = NULL;
+ m_pSGNode = NULL;
+ m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
+ m_pClient_info->m_gameobject = this;
+ m_state = 0;
if(m_attr_dict)
- replica->m_attr_dict= PyDict_Copy(m_attr_dict);
+ m_attr_dict= PyDict_Copy(m_attr_dict);
+
+}
+
+static void setGraphicController_recursive(SG_Node* node)
+{
+ 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->ActivateGraphicController(false);
+ // if the childobj is NULL then this may be an inverse parent link
+ // so a non recursive search should still look down this node.
+ setGraphicController_recursive(childnode);
+ }
}
+void KX_GameObject::ActivateGraphicController(bool recurse)
+{
+ if (m_pGraphicController)
+ {
+ m_pGraphicController->Activate(m_bVisible);
+ }
+ if (recurse)
+ {
+ setGraphicController_recursive(GetSGNode());
+ }
+}
+
CValue* KX_GameObject::GetReplica()
{
KX_GameObject* replica = new KX_GameObject(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
- ProcessReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -421,6 +451,7 @@ double* KX_GameObject::GetOpenGLMatrix()
m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false;
trans.scale(scaling[0], scaling[1], scaling[2]);
trans.getValue(fl);
+ GetSGNode()->ClearDirty();
}
return fl;
}
@@ -428,8 +459,18 @@ double* KX_GameObject::GetOpenGLMatrix()
void KX_GameObject::AddMeshUser()
{
for (size_t i=0;i<m_meshes.size();i++)
- m_meshes[i]->AddMeshUser(this);
-
+ {
+ m_meshes[i]->AddMeshUser(this, &m_meshSlots, GetDeformer());
+ }
+ // set the part of the mesh slot that never change
+ double* fl = GetOpenGLMatrixPtr()->getPointer();
+
+ SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
+ RAS_MeshSlot* ms;
+ for(mit.begin(); !mit.end(); ++mit)
+ {
+ (*mit)->m_OpenGLMatrix = fl;
+ }
UpdateBuckets(false);
}
@@ -453,10 +494,27 @@ static void UpdateBuckets_recursive(SG_Node* node)
void KX_GameObject::UpdateBuckets( bool recursive )
{
if (GetSGNode()) {
- double* fl = GetOpenGLMatrixPtr()->getPointer();
+ RAS_MeshSlot *ms;
+
+ if (GetSGNode()->IsDirty())
+ GetOpenGLMatrix();
- for (size_t i=0;i<m_meshes.size();i++)
- m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
+ SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
+ for(mit.begin(); !mit.end(); ++mit)
+ {
+ ms = *mit;
+ ms->m_bObjectColor = m_bUseObjectColor;
+ ms->m_RGBAcolor = m_objectColor;
+ ms->m_bVisible = m_bVisible;
+ ms->m_bCulled = m_bCulled || !m_bVisible;
+ if (!ms->m_bCulled)
+ ms->m_bucket->ActivateMesh(ms);
+
+ /* split if necessary */
+#ifdef USE_SPLIT
+ ms->Split();
+#endif
+ }
if (recursive) {
UpdateBuckets_recursive(GetSGNode());
@@ -476,11 +534,11 @@ void KX_GameObject::RemoveMeshes()
void KX_GameObject::UpdateTransform()
{
- if (m_pPhysicsController1)
- // only update the transform of static object, dynamic object are handled differently
- // note that for bullet, this does not even update the transform of static object
+ // HACK: saves function call for dynamic object, they are handled differently
+ if (m_pPhysicsController1 && !m_pPhysicsController1->IsDyna())
+ // Note that for Bullet, this does not even update the transform of static object
// but merely sets there collision flag to "kinematic" because the synchronization is
- // done differently during physics simulation
+ // done during physics simulation
m_pPhysicsController1->SetSumoTransform(true);
if (m_pGraphicController)
// update the culling tree
@@ -493,6 +551,20 @@ void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* s
((KX_GameObject*)gameobj)->UpdateTransform();
}
+void KX_GameObject::SynchronizeTransform()
+{
+ // only used for sensor object, do full synchronization as bullet doesn't do it
+ if (m_pPhysicsController1)
+ m_pPhysicsController1->SetTransform();
+ if (m_pGraphicController)
+ m_pGraphicController->SetGraphicTransform();
+}
+
+void KX_GameObject::SynchronizeTransformFunc(SG_IObject* node, void* gameobj, void* scene)
+{
+ ((KX_GameObject*)gameobj)->SynchronizeTransform();
+}
+
void KX_GameObject::SetDebugColor(unsigned int bgra)
{
@@ -613,6 +685,8 @@ KX_GameObject::SetVisible(
{
if (GetSGNode()) {
m_bVisible = v;
+ if (m_pGraphicController)
+ m_pGraphicController->Activate(m_bVisible);
if (recursive)
setVisible_recursive(GetSGNode(), v);
}
@@ -1081,7 +1155,6 @@ CListValue* KX_GameObject::GetChildrenRecursive()
/* ------- python stuff ---------------------------------------------------*/
PyMethodDef KX_GameObject::Methods[] = {
- {"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O},
{"applyForce", (PyCFunction) KX_GameObject::sPyApplyForce, METH_VARARGS},
{"applyTorque", (PyCFunction) KX_GameObject::sPyApplyTorque, METH_VARARGS},
{"applyRotation", (PyCFunction) KX_GameObject::sPyApplyRotation, METH_VARARGS},
@@ -1100,7 +1173,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_NOARGS},
{"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS},
{"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O},
- {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
+ {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_VARARGS},
{"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
{"setOcclusion",(PyCFunction) KX_GameObject::sPySetOcclusion, METH_VARARGS},
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
@@ -1116,10 +1189,15 @@ PyMethodDef KX_GameObject::Methods[] = {
KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo),
KX_PYMETHODTABLE_O(KX_GameObject, getVectTo),
KX_PYMETHODTABLE(KX_GameObject, sendMessage),
-
+
+ // dict style access for props
+ {"has_key",(PyCFunction) KX_GameObject::sPyhas_key, METH_O},
+ {"get",(PyCFunction) KX_GameObject::sPyget, METH_VARARGS},
+
// deprecated
{"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS},
{"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O},
+ {"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O},
{"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS},
{"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O},
{"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS},
@@ -1147,13 +1225,14 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("state", KX_GameObject, pyattr_get_state, pyattr_set_state),
KX_PYATTRIBUTE_RO_FUNCTION("meshes", KX_GameObject, pyattr_get_meshes),
KX_PYATTRIBUTE_RW_FUNCTION("localOrientation",KX_GameObject,pyattr_get_localOrientation,pyattr_set_localOrientation),
- KX_PYATTRIBUTE_RO_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation),
+ KX_PYATTRIBUTE_RW_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_worldOrientation),
KX_PYATTRIBUTE_RW_FUNCTION("localPosition", KX_GameObject, pyattr_get_localPosition, pyattr_set_localPosition),
KX_PYATTRIBUTE_RW_FUNCTION("worldPosition", KX_GameObject, pyattr_get_worldPosition, pyattr_set_worldPosition),
- KX_PYATTRIBUTE_RW_FUNCTION("localScaling", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling),
- KX_PYATTRIBUTE_RO_FUNCTION("worldScaling", KX_GameObject, pyattr_get_worldScaling),
-
- KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_GameObject, pyattr_get_dir_dict),
+ KX_PYATTRIBUTE_RW_FUNCTION("localScale", KX_GameObject, pyattr_get_localScaling, pyattr_set_localScaling),
+ KX_PYATTRIBUTE_RO_FUNCTION("worldScale", KX_GameObject, pyattr_get_worldScaling),
+ KX_PYATTRIBUTE_RO_FUNCTION("children", KX_GameObject, pyattr_get_children),
+ KX_PYATTRIBUTE_RO_FUNCTION("childrenRecursive", KX_GameObject, pyattr_get_children_recursive),
+ KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict),
/* Experemental, dont rely on these yet */
KX_PYATTRIBUTE_RO_FUNCTION("sensors", KX_GameObject, pyattr_get_sensors),
@@ -1193,8 +1272,8 @@ PyObject* KX_GameObject::PyReplaceMesh(PyObject* value)
PyObject* KX_GameObject::PyEndObject()
{
-
KX_Scene *scene = KX_GetActiveScene();
+
scene->DelayedRemoveObject(this);
Py_RETURN_NONE;
@@ -1208,21 +1287,6 @@ PyObject* KX_GameObject::PyGetPosition()
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);
@@ -1231,7 +1295,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item)
PyObject* pyconvert;
if (self==NULL) {
- PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
return NULL;
}
@@ -1265,7 +1329,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
PyErr_Clear();
if (self==NULL) {
- PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG);
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
return -1;
}
@@ -1281,7 +1345,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
if (del==0) {
if(attr_str) PyErr_Format(PyExc_KeyError, "gameOb[key] = value: KX_GameObject, key \"%s\" could not be set", attr_str);
- else PyErr_SetString(PyExc_KeyError, "gameOb[key] = value: KX_GameObject, key could not be set");
+ else PyErr_SetString(PyExc_KeyError, "del gameOb[key]: KX_GameObject, key could not be deleted");
return -1;
}
else if (self->m_attr_dict) {
@@ -1292,9 +1356,9 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
int set= 0;
/* as CValue */
- if(attr_str)
+ if(attr_str && BGE_PROXY_CHECK_TYPE(val)==0) /* dont allow GameObjects for eg to be assigned to CValue props */
{
- CValue* vallie = self->ConvertPythonToValue(val);
+ CValue* vallie = self->ConvertPythonToValue(val, ""); /* error unused */
if(vallie)
{
@@ -1345,17 +1409,21 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
return 0; /* success */
}
-
+/* Cant set the len otherwise it can evaluate as false */
PyMappingMethods KX_GameObject::Mapping = {
- (lenfunc)KX_GameObject::Map_Len, /*inquiry mp_length */
+ (lenfunc)NULL , /*inquiry mp_length */
(binaryfunc)KX_GameObject::Map_GetItem, /*binaryfunc mp_subscript */
(objobjargproc)KX_GameObject::Map_SetItem, /*objobjargproc mp_ass_subscript */
};
-
PyTypeObject KX_GameObject::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_GameObject",
sizeof(PyObjectPlus_Proxy),
0,
@@ -1396,8 +1464,10 @@ PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
KX_GameObject* parent = self->GetParent();
- if (parent)
+ if (parent) {
+ parent->Release(); /* self->GetParent() AddRef's */
return parent->GetProxy();
+ }
Py_RETURN_NONE;
}
@@ -1415,13 +1485,13 @@ int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrd
MT_Scalar val = PyFloat_AsDouble(value);
if (val < 0.0f) { /* also accounts for non float */
PyErr_SetString(PyExc_AttributeError, "gameOb.mass = float: KX_GameObject, expected a float zero or above");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
if (spc)
spc->SetMass(val);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1438,13 +1508,13 @@ int KX_GameObject::pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF
MT_Scalar val = PyFloat_AsDouble(value);
if (val < 0.0f) { /* also accounts for non float */
PyErr_SetString(PyExc_AttributeError, "gameOb.linVelocityMin = float: KX_GameObject, expected a float zero or above");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
if (spc)
spc->SetLinVelocityMin(val);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1461,13 +1531,13 @@ int KX_GameObject::pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF
MT_Scalar val = PyFloat_AsDouble(value);
if (val < 0.0f) { /* also accounts for non float */
PyErr_SetString(PyExc_AttributeError, "gameOb.linVelocityMax = float: KX_GameObject, expected a float zero or above");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
if (spc)
spc->SetLinVelocityMax(val);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
@@ -1483,12 +1553,12 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at
int param = PyObject_IsTrue( value );
if (param == -1) {
PyErr_SetString(PyExc_AttributeError, "gameOb.visible = bool: KX_GameObject, expected True or False");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
self->SetVisible(param, false);
self->UpdateBuckets(false);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1502,11 +1572,11 @@ int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_D
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
MT_Point3 pos;
if (!PyVecTo(value, pos))
- return 1;
+ return PY_SET_ATTR_FAIL;
self->NodeSetWorldPosition(pos);
self->NodeUpdateGS(0.f);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1523,11 +1593,11 @@ int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_D
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
MT_Point3 pos;
if (!PyVecTo(value, pos))
- return 1;
+ return PY_SET_ATTR_FAIL;
self->NodeSetLocalPosition(pos);
self->NodeUpdateGS(0.f);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1546,6 +1616,26 @@ PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYAT
return PyObjectFrom(self->NodeGetWorldOrientation());
}
+int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+
+ /* if value is not a sequence PyOrientationTo makes an error */
+ MT_Matrix3x3 rot;
+ if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, "))
+ return PY_SET_ATTR_FAIL;
+
+ if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) {
+ self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot);
+ }
+ else {
+ self->NodeSetLocalOrientation(rot);
+ }
+
+ self->NodeUpdateGS(0.f);
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
@@ -1561,12 +1651,12 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT
/* if value is not a sequence PyOrientationTo makes an error */
MT_Matrix3x3 rot;
- if (!PyOrientationTo(value, rot, "gameOb.orientation = sequence: KX_GameObject, "))
- return NULL;
+ if (!PyOrientationTo(value, rot, "gameOb.localOrientation = sequence: KX_GameObject, "))
+ return PY_SET_ATTR_FAIL;
self->NodeSetLocalOrientation(rot);
self->NodeUpdateGS(0.f);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1589,11 +1679,11 @@ int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DE
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
MT_Vector3 scale;
if (!PyVecTo(value, scale))
- return 1;
+ return PY_SET_ATTR_FAIL;
self->NodeSetLocalScale(scale);
self->NodeUpdateGS(0.f);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1615,12 +1705,12 @@ int KX_GameObject::pyattr_set_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF
SG_Node* sg_parent= self->GetSGNode()->GetSGParent();
if (val < 0.0f) { /* also accounts for non float */
PyErr_SetString(PyExc_AttributeError, "gameOb.timeOffset = float: KX_GameObject, expected a float zero or above");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
if (sg_parent && sg_parent->IsSlowParent())
static_cast<KX_SlowParentRelation *>(sg_parent->GetParentRelation())->SetTimeOffset(val);
}
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1639,16 +1729,16 @@ int KX_GameObject::pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attr
if (state_i == -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "gameOb.state = int: KX_GameObject, expected an int bit field");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
state |= state_i;
if ((state & ((1<<30)-1)) == 0) {
PyErr_SetString(PyExc_AttributeError, "gameOb.state = int: KX_GameObject, state bitfield was not between 0 and 30 (1<<0 and 1<<29)");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
self->SetState(state);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -1657,10 +1747,10 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE
PyObject *meshes= PyList_New(self->m_meshes.size());
int i;
- for(i=0; i < self->m_meshes.size(); i++)
+ for(i=0; i < (int)self->m_meshes.size(); i++)
{
KX_MeshProxy* meshproxy = new KX_MeshProxy(self->m_meshes[i]);
- PyList_SET_ITEM(meshes, i, meshproxy->GetProxy());
+ PyList_SET_ITEM(meshes, i, meshproxy->NewProxy(true));
}
return meshes;
@@ -1669,69 +1759,40 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE
/* experemental! */
PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- KX_GameObject* self= static_cast<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;
+ return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_SENSORS);
}
PyObject* KX_GameObject::pyattr_get_controllers(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- KX_GameObject* self= static_cast<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;
+ return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_CONTROLLERS);
}
PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
+ return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_ACTUATORS);
+}
+
+PyObject* KX_GameObject::pyattr_get_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
KX_GameObject* self= static_cast<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;
+ return self->GetChildren()->NewProxy(true);
}
-/* __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)
+PyObject* KX_GameObject::pyattr_get_children_recursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+ return self->GetChildrenRecursive()->NewProxy(true);
+}
+
+PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self= static_cast<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)
- {
- 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);
- /* Add m_attr_dict if we have it */
- if(self->m_attr_dict)
- PyDict_Update(dict, self->m_attr_dict);
+ if(self->m_attr_dict==NULL)
+ self->m_attr_dict= PyDict_New();
- return dict;
+ Py_INCREF(self->m_attr_dict);
+ return self->m_attr_dict;
}
/* We need these because the macros have a return in them */
@@ -1772,11 +1833,38 @@ PyObject* KX_GameObject::py_getattro(PyObject *attr)
return object;
}
+PyObject* KX_GameObject::py_getattro_dict() {
+ //py_getattro_dict_up(SCA_IObject);
+ PyObject *dict= py_getattr_dict(SCA_IObject::py_getattro_dict(), Type.tp_dict);
+ if(dict==NULL)
+ return NULL;
+
+ /* normally just return this but KX_GameObject has some more items */
+
+
+ /* Not super fast getting as a list then making into dict keys but its only for dir() */
+ PyObject *list= ConvertKeysToPython();
+ if(list)
+ {
+ int i;
+ for(i=0; i<PyList_Size(list); i++)
+ PyDict_SetItem(dict, PyList_GET_ITEM(list, i), Py_None);
+ }
+ else
+ PyErr_Clear();
+
+ Py_DECREF(list);
+
+ /* Add m_attr_dict if we have it */
+ if(m_attr_dict)
+ PyDict_Update(dict, m_attr_dict);
+
+ return dict;
+}
+
int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro method
{
- int ret;
-
- ret= py_setattro__internal(attr, value);
+ int ret= py_setattro__internal(attr, value);
if (ret==PY_SET_ATTR_SUCCESS) {
/* remove attribute in our own dict to avoid double ups */
@@ -1789,7 +1877,7 @@ int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro m
if (ret==PY_SET_ATTR_COERCE_FAIL) {
/* CValue attribute exists, remove CValue and add PyDict value */
- RemoveProperty(STR_String(PyString_AsString(attr)));
+ RemoveProperty(PyString_AsString(attr));
ret= PY_SET_ATTR_MISSING;
}
@@ -1814,16 +1902,18 @@ int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro m
int KX_GameObject::py_delattro(PyObject *attr)
{
+ ShowDeprecationWarning("del ob.attr", "del ob['attr'] for user defined properties");
+
char *attr_str= PyString_AsString(attr);
- if (RemoveProperty(STR_String(attr_str))) // XXX - should call CValues instead but its only 2 lines here
- return 0;
+ if (RemoveProperty(attr_str)) // XXX - should call CValues instead but its only 2 lines here
+ return PY_SET_ATTR_SUCCESS;
if (m_attr_dict && (PyDict_DelItem(m_attr_dict, attr) == 0))
- return 0;
+ return PY_SET_ATTR_SUCCESS;
PyErr_Format(PyExc_AttributeError, "del gameOb.myAttr: KX_GameObject, attribute \"%s\" dosnt exist", attr_str);
- return 1;
+ return PY_SET_ATTR_MISSING;
}
@@ -2008,14 +2098,8 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* args)
MT_Point3 point(0.0,0.0,0.0);
PyObject* pypos = NULL;
- if (PyArg_ParseTuple(args, "|O:getVelocity", &pypos))
- {
- if (pypos)
- PyVecTo(pypos, point);
- }
- else {
+ if (!PyArg_ParseTuple(args, "|O:getVelocity", &pypos) || (pypos && !PyVecTo(pypos, point)))
return NULL;
- }
if (m_pPhysicsController1)
{
@@ -2075,35 +2159,49 @@ PyObject* KX_GameObject::PyGetParent()
{
ShowDeprecationWarning("getParent()", "the parent property");
KX_GameObject* parent = this->GetParent();
- if (parent)
+ if (parent) {
+ parent->Release(); /* self->GetParent() AddRef's */
return parent->GetProxy();
+ }
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PySetParent(PyObject* value)
+PyObject* KX_GameObject::PySetParent(PyObject* args)
{
+ KX_Scene *scene = KX_GetActiveScene();
+ PyObject* pyobj;
KX_GameObject *obj;
- if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject"))
- return NULL;
+ int addToCompound=1, ghost=1;
- this->SetParent(KX_GetActiveScene(), obj);
+ if (!PyArg_ParseTuple(args,"O|ii:setParent", &pyobj, &addToCompound, &ghost)) {
+ return NULL; // Python sets a simple error
+ }
+ if (!ConvertPythonToGameObject(pyobj, &obj, true, "gameOb.setParent(obj): KX_GameObject"))
+ return NULL;
+ if (obj)
+ this->SetParent(scene, obj, addToCompound, ghost);
Py_RETURN_NONE;
}
PyObject* KX_GameObject::PyRemoveParent()
{
KX_Scene *scene = KX_GetActiveScene();
+
this->RemoveParent(scene);
Py_RETURN_NONE;
}
PyObject* KX_GameObject::PyGetChildren()
{
+ ShowDeprecationWarning("getChildren()", "the children property");
+
return GetChildren()->NewProxy(true);
}
PyObject* KX_GameObject::PyGetChildrenRecursive()
{
+ ShowDeprecationWarning("getChildrenRecursive()", "the childrenRecursive property");
+
return GetChildrenRecursive()->NewProxy(true);
}
@@ -2203,23 +2301,15 @@ PyObject* KX_GameObject::PyGetOrientation() //keywords
PyObject* KX_GameObject::PySetOrientation(PyObject* value)
{
ShowDeprecationWarning("setOrientation()", "the orientation property");
- MT_Matrix3x3 matrix;
- if (PyObject_IsMT_Matrix(value, 3) && PyMatTo(value, matrix))
- {
- NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f);
- Py_RETURN_NONE;
- }
+ MT_Matrix3x3 rot;
+
+ /* if value is not a sequence PyOrientationTo makes an error */
+ if (!PyOrientationTo(value, rot, "gameOb.setOrientation(sequence): KX_GameObject, "))
+ return NULL;
- MT_Quaternion quat;
- if (PyVecTo(value, quat))
- {
- matrix.setRotation(quat);
- NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f);
- Py_RETURN_NONE;
- }
- return NULL;
+ NodeSetLocalOrientation(rot);
+ NodeUpdateGS(0.f);
+ Py_RETURN_NONE;
}
PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* args)
@@ -2256,7 +2346,7 @@ PyObject* KX_GameObject::PyGetAxisVect(PyObject* value)
PyObject* KX_GameObject::PySetPosition(PyObject* value)
{
- ShowDeprecationWarning("setPosition()", "the position property");
+ ShowDeprecationWarning("setPosition()", "the localPosition property");
MT_Point3 pos;
if (PyVecTo(value, pos))
{
@@ -2270,6 +2360,7 @@ PyObject* KX_GameObject::PySetPosition(PyObject* value)
PyObject* KX_GameObject::PySetWorldPosition(PyObject* value)
{
+ ShowDeprecationWarning("setWorldPosition()", "the worldPosition property");
MT_Point3 pos;
if (PyVecTo(value, pos))
{
@@ -2474,6 +2565,34 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
Py_RETURN_NONE;
}
+/* faster then Py_BuildValue since some scripts call raycast a lot */
+static PyObject *none_tuple_3()
+{
+ PyObject *ret= PyTuple_New(3);
+ PyTuple_SET_ITEM(ret, 0, Py_None);
+ PyTuple_SET_ITEM(ret, 1, Py_None);
+ PyTuple_SET_ITEM(ret, 2, Py_None);
+
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ return ret;
+}
+static PyObject *none_tuple_4()
+{
+ PyObject *ret= PyTuple_New(4);
+ PyTuple_SET_ITEM(ret, 0, Py_None);
+ PyTuple_SET_ITEM(ret, 1, Py_None);
+ PyTuple_SET_ITEM(ret, 2, Py_None);
+ PyTuple_SET_ITEM(ret, 3, Py_None);
+
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ return ret;
+}
+
KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
"rayCast(to,from,dist,prop,face,xray,poly): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) of contact point with object within dist that matches prop.\n"
" If no hit, return (None,None,None) or (None,None,None,None).\n"
@@ -2541,12 +2660,14 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
if (dist != 0.0f) {
MT_Vector3 toDir = toPoint-fromPoint;
if (MT_fuzzyZero(toDir.length2())) {
- return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ //return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ return none_tuple_3();
}
toDir.normalize();
toPoint = fromPoint + (dist) * toDir;
} else if (MT_fuzzyZero((toPoint-fromPoint).length2())) {
- return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ //return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ return none_tuple_3();
}
PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment();
@@ -2594,9 +2715,11 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
}
// no hit
if (poly)
- return Py_BuildValue("OOOO", Py_None, Py_None, Py_None, Py_None);
+ //return Py_BuildValue("OOOO", Py_None, Py_None, Py_None, Py_None);
+ return none_tuple_4();
else
- return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ //return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ return none_tuple_3();
}
KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage,
@@ -2606,6 +2729,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage,
"body = Message body (string)"
"to = Name of object to send the message to")
{
+ KX_Scene *scene = KX_GetActiveScene();
char* subject;
char* body = (char *)"";
char* to = (char *)"";
@@ -2613,12 +2737,58 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage,
if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to))
return NULL;
+
+ scene->GetNetworkScene()->SendMessage(to, from, subject, body);
+ Py_RETURN_NONE;
+}
- KX_GetActiveScene()->GetNetworkScene()->SendMessage(to, from, subject, body);
+/* dict style access */
- Py_RETURN_NONE;
+
+/* Matches python dict.get(key, [default]) */
+PyObject* KX_GameObject::Pyget(PyObject *args)
+{
+ PyObject *key;
+ PyObject* def = Py_None;
+ PyObject* ret;
+
+ if (!PyArg_ParseTuple(args, "O|O:get", &key, &def))
+ return NULL;
+
+
+ if(PyString_Check(key)) {
+ CValue *item = GetProperty(PyString_AsString(key));
+ if (item) {
+ ret = item->ConvertValueToPython();
+ if(ret)
+ return ret;
+ else
+ return item->GetProxy();
+ }
+ }
+
+ if (m_attr_dict && (ret=PyDict_GetItem(m_attr_dict, key))) {
+ Py_INCREF(ret);
+ return ret;
+ }
+
+ Py_INCREF(def);
+ return def;
+}
+
+/* Matches python dict.has_key() */
+PyObject* KX_GameObject::Pyhas_key(PyObject* value)
+{
+ if(PyString_Check(value) && GetProperty(PyString_AsString(value)))
+ Py_RETURN_TRUE;
+
+ if (m_attr_dict && PyDict_GetItem(m_attr_dict, value))
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
}
+
/* ---------------------------------------------------------------------
* Some stuff taken from the header
* --------------------------------------------------------------------- */
@@ -2641,6 +2811,7 @@ void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
}
}
+
bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix)
{
if (value==NULL) {
@@ -2671,12 +2842,15 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
}
}
- if (PyObject_TypeCheck(value, &KX_GameObject::Type)) {
+ if ( PyObject_TypeCheck(value, &KX_GameObject::Type) ||
+ PyObject_TypeCheck(value, &KX_LightObject::Type) ||
+ PyObject_TypeCheck(value, &KX_Camera::Type) )
+ {
*object = static_cast<KX_GameObject*>BGE_PROXY_REF(value);
/* sets the error */
if (*object==NULL) {
- PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
+ PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
return false;
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index ec02dc17b75..dbdea97031d 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -77,6 +77,7 @@ protected:
STR_String m_text;
int m_layer;
std::vector<RAS_MeshObject*> m_meshes;
+ SG_QList m_meshSlots; // head of mesh slots of this
struct Object* m_pBlenderObject;
struct Object* m_pBlenderGroupObject;
@@ -170,7 +171,7 @@ public:
/**
* Sets the parent of this object to a game object
*/
- void SetParent(KX_Scene *scene, KX_GameObject *obj);
+ void SetParent(KX_Scene *scene, KX_GameObject *obj, bool addToCompound=true, bool ghost=true);
/**
* Removes the parent of this object to a game object
@@ -192,11 +193,6 @@ public:
~KX_GameObject(
);
- CValue*
- AddRef() {
- /* temporarily to find memleaks */ return CValue::AddRef();
- }
-
/**
* @section Stuff which is here due to poor design.
* Inherited from CValue and needs an implementation.
@@ -245,7 +241,7 @@ public:
/**
* Inherited from CValue -- returns the name of this object.
*/
- STR_String
+ STR_String&
GetName(
);
@@ -254,15 +250,7 @@ public:
*/
void
SetName(
- STR_String name
- );
-
- /**
- * Inherited from CValue -- does nothing.
- */
- void
- ReplicaSetName(
- STR_String name
+ const char *name
);
/**
@@ -279,9 +267,7 @@ public:
* data owned by this class is deep copied. Called internally
*/
virtual void
- ProcessReplica(
- KX_GameObject* replica
- );
+ ProcessReplica();
/**
* Return the linear velocity of the game object.
@@ -395,6 +381,10 @@ public:
{
m_pGraphicController = graphiccontroller;
}
+ /*
+ * @add/remove the graphic controller to the physic system
+ */
+ void ActivateGraphicController(bool recurse);
/**
* @section Coordinate system manipulation functions
@@ -570,6 +560,13 @@ public:
static void UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene);
/**
+ * only used for sensor objects
+ */
+ void SynchronizeTransform();
+
+ static void SynchronizeTransformFunc(SG_IObject* node, void* gameobj, void* scene);
+
+ /**
* Function to set IPO option at start of IPO
*/
void
@@ -816,6 +813,7 @@ public:
*/
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value); // py_setattro method
virtual int py_delattro(PyObject *attr);
virtual PyObject* py_repr(void)
@@ -860,7 +858,7 @@ public:
KX_PYMETHOD_VARARGS(KX_GameObject,ApplyImpulse);
KX_PYMETHOD_O(KX_GameObject,SetCollisionMargin);
KX_PYMETHOD_NOARGS(KX_GameObject,GetParent);
- KX_PYMETHOD_O(KX_GameObject,SetParent);
+ KX_PYMETHOD_VARARGS(KX_GameObject,SetParent);
KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildren);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildrenRecursive);
@@ -874,6 +872,11 @@ public:
KX_PYMETHOD_DOC_O(KX_GameObject,getDistanceTo);
KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo);
KX_PYMETHOD_DOC_VARARGS(KX_GameObject, sendMessage);
+
+ /* Dict access */
+ KX_PYMETHOD_VARARGS(KX_GameObject,get);
+ KX_PYMETHOD_O(KX_GameObject,has_key);
+
/* attributes */
static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -893,6 +896,7 @@ public:
static PyObject* pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -903,9 +907,9 @@ public:
static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_meshes(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
- /* for dir(), python3 uses __dir__() */
- static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_children_recursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
/* Experemental! */
static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
index 55a7e2ade60..bd7e09d1dda 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
@@ -194,7 +194,8 @@ bool KX_IpoSGController::Update(double currentTime)
else
newPosition = m_ipo_start_point + newPosition;
}
- ob->SetLocalPosition(newPosition);
+ if (m_game_object)
+ m_game_object->NodeSetLocalPosition(newPosition);
}
}
//modifies orientation?
@@ -233,7 +234,8 @@ bool KX_IpoSGController::Update(double currentTime)
rotation = m_ipo_start_orient * rotation;
else
rotation = rotation * m_ipo_start_orient;
- ob->SetLocalOrientation(rotation);
+ if (m_game_object)
+ m_game_object->NodeSetLocalOrientation(rotation);
}
} else if (m_ipo_channels_active[OB_ROT_X] || m_ipo_channels_active[OB_ROT_Y] || m_ipo_channels_active[OB_ROT_Z]) {
if (m_ipo_euler_initialized) {
@@ -265,7 +267,8 @@ bool KX_IpoSGController::Update(double currentTime)
else if (m_ipo_channels_active[OB_DROT_Z]) {
roll += m_ipo_xform.GetDeltaEulerAngles()[2];
}
- ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll));
+ if (m_game_object)
+ m_game_object->NodeSetLocalOrientation(MT_Vector3(yaw, pitch, roll));
}
} else if (m_ipo_start_initialized) {
// only DROT, treat as Add
@@ -286,7 +289,8 @@ bool KX_IpoSGController::Update(double currentTime)
// dRot are always local
MT_Matrix3x3 rotation(MT_Vector3(yaw, pitch, roll));
rotation = m_ipo_start_orient * rotation;
- ob->SetLocalOrientation(rotation);
+ if (m_game_object)
+ m_game_object->NodeSetLocalOrientation(rotation);
}
}
//modifies scale?
@@ -322,8 +326,8 @@ bool KX_IpoSGController::Update(double currentTime)
if (m_ipo_add) {
newScale = m_ipo_start_scale * newScale;
}
-
- ob->SetLocalScale(newScale);
+ if (m_game_object)
+ m_game_object->NodeSetLocalScale(newScale);
}
m_modified=false;
@@ -342,6 +346,7 @@ SG_Controller* KX_IpoSGController::GetReplica(class SG_Node* destnode)
KX_IpoSGController* iporeplica = new KX_IpoSGController(*this);
// clear object that ipo acts on in the replica.
iporeplica->ClearObject();
+ iporeplica->SetGameObject((KX_GameObject*)destnode->GetSGClientObject());
// dirty hack, ask Gino for a better solution in the ipo implementation
// hacken en zagen, in what we call datahiding, not written for replication :(
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp
index a38222c5f7e..673acabd774 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp
@@ -35,9 +35,10 @@
#include "PHY_DynamicTypes.h"
-KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool compound, void* userdata)
+KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool sensor, bool compound, void* userdata)
: m_bDyna(dyna),
+ m_bSensor(sensor),
m_bCompound(compound),
m_suspendDynamics(false),
m_userdata(userdata)
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
index 10b66da7b76..81c01045071 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -49,11 +49,12 @@ class KX_IPhysicsController : public SG_Controller
{
protected:
bool m_bDyna;
+ bool m_bSensor;
bool m_bCompound;
bool m_suspendDynamics;
void* m_userdata;
public:
- KX_IPhysicsController(bool dyna,bool compound, void* userdata);
+ KX_IPhysicsController(bool dyna,bool sensor,bool compound, void* userdata);
virtual ~KX_IPhysicsController();
@@ -74,6 +75,7 @@ public:
virtual void getOrientation(MT_Quaternion& orn)=0;
virtual void setOrientation(const MT_Matrix3x3& orn)=0;
+ virtual void SetTransform()=0;
//virtual void setOrientation(const MT_Quaternion& orn)=0;
virtual void setPosition(const MT_Point3& pos)=0;
virtual void setScaling(const MT_Vector3& scaling)=0;
@@ -100,10 +102,18 @@ public:
m_bDyna = isDynamic;
}
+ void SetSensor(bool isSensor) {
+ m_bSensor = isSensor;
+ }
+
bool IsDyna(void) {
return m_bDyna;
}
+ bool IsSensor(void) {
+ return m_bSensor;
+ }
+
bool IsCompound(void) {
return m_bCompound;
}
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index f04e3c79a8e..3ec0598ac03 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -164,14 +164,14 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
// result = true if animation has to be continued, false if animation stops
// maybe there are events for us in the queue !
bool bNegativeEvent = false;
- int numevents = 0;
+ bool numevents = false;
bool bIpoStart = false;
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
if (frame)
{
- numevents = m_events.size();
+ numevents = m_posevent || m_negevent;
bNegativeEvent = IsNegativeEvent();
RemoveAllEvents();
}
@@ -273,7 +273,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
{
result = false;
m_bNegativeEvent = false;
- numevents = 0;
+ numevents = false;
}
if (!m_bIpoPlaying)
{
@@ -413,8 +413,13 @@ int KX_IpoActuator::string2mode(char* modename) {
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_IpoActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_IpoActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -440,9 +445,8 @@ PyParentObject KX_IpoActuator::Parents[] = {
};
PyMethodDef KX_IpoActuator::Methods[] = {
- {"set", (PyCFunction) KX_IpoActuator::sPySet, METH_VARARGS, (PY_METHODCHAR)Set_doc},
-
// deprecated
+ {"set", (PyCFunction) KX_IpoActuator::sPySet, METH_VARARGS, (PY_METHODCHAR)Set_doc},
{"setProperty", (PyCFunction) KX_IpoActuator::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
{"setStart", (PyCFunction) KX_IpoActuator::sPySetStart, METH_VARARGS, (PY_METHODCHAR)SetStart_doc},
{"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart, METH_NOARGS, (PY_METHODCHAR)GetStart_doc},
@@ -460,11 +464,11 @@ PyMethodDef KX_IpoActuator::Methods[] = {
};
PyAttributeDef KX_IpoActuator::Attributes[] = {
- KX_PYATTRIBUTE_FLOAT_RW("startFrame", 0, 300000, KX_IpoActuator, m_startframe),
- KX_PYATTRIBUTE_FLOAT_RW("endFrame", 0, 300000, KX_IpoActuator, m_endframe),
+ KX_PYATTRIBUTE_FLOAT_RW("frameStart", 0, 300000, KX_IpoActuator, m_startframe),
+ KX_PYATTRIBUTE_FLOAT_RW("frameEnd", 0, 300000, KX_IpoActuator, m_endframe),
KX_PYATTRIBUTE_STRING_RW("propName", 0, 64, false, KX_IpoActuator, m_propname),
KX_PYATTRIBUTE_STRING_RW("framePropName", 0, 64, false, KX_IpoActuator, m_framepropname),
- KX_PYATTRIBUTE_INT_RW("type", KX_ACT_IPO_NODEF+1, KX_ACT_IPO_MAX-1, true, KX_IpoActuator, m_type),
+ KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_IPO_NODEF+1, KX_ACT_IPO_MAX-1, true, KX_IpoActuator, m_type),
KX_PYATTRIBUTE_BOOL_RW("useIpoAsForce", KX_IpoActuator, m_ipo_as_force),
KX_PYATTRIBUTE_BOOL_RW("useIpoAdd", KX_IpoActuator, m_ipo_add),
KX_PYATTRIBUTE_BOOL_RW("useIpoLocal", KX_IpoActuator, m_ipo_local),
@@ -477,6 +481,10 @@ PyObject* KX_IpoActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_IpoActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_IpoActuator::py_setattro(PyObject *attr, PyObject *value) // py_setattro method
{
py_setattro_up(SCA_IActuator);
@@ -492,7 +500,7 @@ const char KX_IpoActuator::Set_doc[] =
"\tSet the properties of the actuator.\n";
PyObject* KX_IpoActuator::PySet(PyObject* args) {
- ShowDeprecationWarning("set()", "a number properties");
+ ShowDeprecationWarning("set()", "a range properties");
/* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND */
/* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe, */
@@ -554,7 +562,7 @@ const char KX_IpoActuator::SetStart_doc[] =
"\tSet the frame from which the ipo starts playing.\n";
PyObject* KX_IpoActuator::PySetStart(PyObject* args) {
- ShowDeprecationWarning("setStart()", "the startFrame property");
+ ShowDeprecationWarning("setStart()", "the frameStart property");
float startArg;
if(!PyArg_ParseTuple(args, "f:setStart", &startArg)) {
@@ -570,7 +578,7 @@ const char KX_IpoActuator::GetStart_doc[] =
"getStart()\n"
"\tReturns the frame from which the ipo starts playing.\n";
PyObject* KX_IpoActuator::PyGetStart() {
- ShowDeprecationWarning("getStart()", "the startFrame property");
+ ShowDeprecationWarning("getStart()", "the frameStart property");
return PyFloat_FromDouble(m_startframe);
}
@@ -580,7 +588,7 @@ const char KX_IpoActuator::SetEnd_doc[] =
"\t - frame: last frame to use (int)\n"
"\tSet the frame at which the ipo stops playing.\n";
PyObject* KX_IpoActuator::PySetEnd(PyObject* args) {
- ShowDeprecationWarning("setEnd()", "the endFrame property");
+ ShowDeprecationWarning("setEnd()", "the frameEnd property");
float endArg;
if(!PyArg_ParseTuple(args, "f:setEnd", &endArg)) {
return NULL;
@@ -595,7 +603,7 @@ const char KX_IpoActuator::GetEnd_doc[] =
"getEnd()\n"
"\tReturns the frame at which the ipo stops playing.\n";
PyObject* KX_IpoActuator::PyGetEnd() {
- ShowDeprecationWarning("getEnd()", "the endFrame property");
+ ShowDeprecationWarning("getEnd()", "the frameEnd property");
return PyFloat_FromDouble(m_endframe);
}
@@ -661,7 +669,7 @@ const char KX_IpoActuator::SetType_doc[] =
"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
"\tSet the operation mode of the actuator.\n";
PyObject* KX_IpoActuator::PySetType(PyObject* args) {
- ShowDeprecationWarning("setType()", "the type property");
+ ShowDeprecationWarning("setType()", "the mode property");
int typeArg;
if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
@@ -680,7 +688,7 @@ const char KX_IpoActuator::GetType_doc[] =
"getType()\n"
"\tReturns the operation mode of the actuator.\n";
PyObject* KX_IpoActuator::PyGetType() {
- ShowDeprecationWarning("getType()", "the type property");
+ ShowDeprecationWarning("getType()", "the mode property");
return PyInt_FromLong(m_type);
}
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h
index 184ad5512de..9ea597def1e 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.h
+++ b/source/gameengine/Ketsji/KX_IpoActuator.h
@@ -128,8 +128,6 @@ public:
virtual CValue* GetReplica() {
KX_IpoActuator* replica = new KX_IpoActuator(*this);//m_float,GetName());
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
};
@@ -142,6 +140,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
//KX_PYMETHOD_DOC
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 83a2fa8a448..b30b79e7f23 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -77,6 +77,8 @@
#include "RAS_FramingManager.h"
#include "stdio.h"
+#include "DNA_world_types.h"
+#include "DNA_scene_types.h"
// If define: little test for Nzc: guarded drawing. If the canvas is
// not valid, skip rendering this frame.
@@ -97,6 +99,8 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = {
};
double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE;
+int KX_KetsjiEngine::m_maxLogicFrame = 5;
+int KX_KetsjiEngine::m_maxPhysicsFrame = 5;
double KX_KetsjiEngine::m_anim_framerate = 25.0;
double KX_KetsjiEngine::m_suspendedtime = 0.0;
double KX_KetsjiEngine::m_suspendeddelta = 0.0;
@@ -145,8 +149,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_stereo(false),
m_curreye(0),
- m_usedome(false),
-
m_logger(NULL),
// Set up timing info display variables
@@ -164,7 +166,9 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_overrideFrameColor(false),
m_overrideFrameColorR(0.0),
m_overrideFrameColorG(0.0),
- m_overrideFrameColorB(0.0)
+ m_overrideFrameColorB(0.0),
+
+ m_usedome(false)
{
// Initialize the time logger
m_logger = new KX_TimeCategoryLogger (25);
@@ -261,9 +265,9 @@ void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter)
m_sceneconverter = sceneconverter;
}
-void KX_KetsjiEngine::InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text)
+void KX_KetsjiEngine::InitDome(short res, short mode, short angle, float resbuf, short tilt, struct Text* text)
{
- m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, size, res, mode, angle, resbuf, text);
+ m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, res, mode, angle, resbuf, tilt, text);
m_usedome = true;
}
@@ -271,7 +275,6 @@ void KX_KetsjiEngine::RenderDome()
{
GLuint viewport[4]={0};
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
-// unsigned int m_viewport[4] = {viewport[0], viewport[1], viewport[2], viewport[3]};
m_dome->SetViewPort(viewport);
@@ -295,11 +298,6 @@ void KX_KetsjiEngine::RenderDome()
return;
KX_SceneList::iterator sceneit;
- for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
- {
- // do this only once per scene
- (*sceneit)->UpdateMeshTransformations();
- }
int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
for (int i=0;i<n_renders;i++){
@@ -353,7 +351,6 @@ void KX_KetsjiEngine::RenderDome()
m_dome->BindImages(i);
}
-// m_dome->Dome_PostRender(scene, cam, stereomode);
m_canvas->EndFrame();//XXX do we really need that?
m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
@@ -381,7 +378,8 @@ void KX_KetsjiEngine::RenderDome()
m_dome->Draw();
- //run 2dfilters
+ // run the 2dfilters and motion blur once for all the scenes
+ PostRenderFrame();
EndFrame();
}
@@ -398,7 +396,20 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo)
m_firstframe = true;
m_bInitialized = true;
- m_ticrate = DEFAULT_LOGIC_TIC_RATE;
+ // there is always one scene enabled at startup
+ World* world = m_scenes[0]->GetBlenderScene()->world;
+ if (world)
+ {
+ m_ticrate = world->ticrate;
+ m_maxLogicFrame = world->maxlogicstep;
+ m_maxPhysicsFrame = world->maxphystep;
+ }
+ else
+ {
+ m_ticrate = DEFAULT_LOGIC_TIC_RATE;
+ m_maxLogicFrame = 5;
+ m_maxPhysicsFrame = 5;
+ }
if (m_game2ipo)
{
@@ -511,7 +522,8 @@ void KX_KetsjiEngine::EndFrame()
bool KX_KetsjiEngine::NextFrame()
{
-
+ double timestep = 1.0/m_ticrate;
+ double framestep = timestep;
// static hidden::Clock sClock;
m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(),true);
@@ -520,7 +532,7 @@ m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(),true);
//sClock.reset();
if (m_bFixedTime)
- m_clockTime += 1./m_ticrate;
+ m_clockTime += timestep;
else
{
@@ -548,24 +560,29 @@ else
// PIL_sleep_ms(1);
KX_SceneList::iterator sceneit;
- int frameOut = 5;
- if (frames>frameOut)
+ if (frames>m_maxPhysicsFrame)
{
// printf("framedOut: %d\n",frames);
- m_frameTime+=(frames-frameOut)*(1.0/m_ticrate);
- frames = frameOut;
+ m_frameTime+=(frames-m_maxPhysicsFrame)*timestep;
+ frames = m_maxPhysicsFrame;
}
bool doRender = frames>0;
+ if (frames > m_maxLogicFrame)
+ {
+ framestep = (frames*timestep)/m_maxLogicFrame;
+ frames = m_maxLogicFrame;
+ }
+
while (frames)
{
- m_frameTime += 1.0/m_ticrate;
+ m_frameTime += framestep;
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
// for each scene, call the proceed functions
@@ -644,7 +661,7 @@ else
// Perform physics calculations on the scene. This can involve
// many iterations of the physics solver.
- scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,1.0/m_ticrate);//m_deltatimerealDeltaTime);
+ scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,timestep,framestep);//m_deltatimerealDeltaTime);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_PHYSICS2_UPDATE);
@@ -717,7 +734,7 @@ else
// Perform physics calculations on the scene. This can involve
// many iterations of the physics solver.
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
- scene->GetPhysicsEnvironment()->proceedDeltaTime(m_clockTime,0.f);
+ scene->GetPhysicsEnvironment()->proceedDeltaTime(m_clockTime,timestep,timestep);
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
@@ -817,8 +834,8 @@ void KX_KetsjiEngine::Render()
// pass the scene's worldsettings to the rasterizer
SetWorldSettings(scene->GetWorldInfo());
- // do this only once per scene
- scene->UpdateMeshTransformations();
+ // this is now done incrementatlly in KX_Scene::CalculateVisibleMeshes
+ //scene->UpdateMeshTransformations();
// shadow buffers
RenderShadowBuffers(scene);
@@ -906,9 +923,6 @@ void KX_KetsjiEngine::Render()
}
} // if(m_rasterizer->Stereo())
- // run the 2dfilters and motion blur once for all the scenes
- PostRenderFrame();
-
EndFrame();
}
@@ -1000,7 +1014,7 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
wi->getAmbientColorBlue()
);
- if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
+ if (m_drawingmode >= RAS_IRasterizer::KX_SOLID)
{
if (wi->hasMist())
{
@@ -1012,10 +1026,6 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
wi->getMistColorBlue()
);
}
- else
- {
- m_rasterizer->DisableFog();
- }
}
}
}
@@ -1097,7 +1107,7 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect
area = userviewport;
}
- else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) {
+ else if ( !m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) {
RAS_FramingManager::ComputeViewport(
scene->GetFramingType(),
m_canvas->GetDisplayArea(),
@@ -1117,16 +1127,13 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect
void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
{
- CListValue *objectlist = scene->GetObjectList();
+ CListValue *lightlist = scene->GetLightList();
int i, drawmode;
m_rendertools->SetAuxilaryClientInfo(scene);
- for(i=0; i<objectlist->GetCount(); i++) {
- KX_GameObject *gameobj = (KX_GameObject*)objectlist->GetValue(i);
-
- if(!gameobj->IsLight())
- continue;
+ for(i=0; i<lightlist->GetCount(); i++) {
+ KX_GameObject *gameobj = (KX_GameObject*)lightlist->GetValue(i);
KX_LightObject *light = (KX_LightObject*)gameobj;
@@ -1135,7 +1142,7 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) {
/* make temporary camera */
RAS_CameraData camdata = RAS_CameraData();
- KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false);
+ KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, true, true);
cam->SetName("__shadow__cam__");
MT_Transform camtrans;
@@ -1167,13 +1174,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
{
bool override_camera;
RAS_Rect viewport, area;
- float left, right, bottom, top, nearfrust, farfrust, focallength;
- const float ortho = 100.0;
+ float nearfrust, farfrust, focallength;
// KX_Camera* cam = scene->GetActiveCamera();
if (!cam)
return;
-
GetSceneViewport(scene, cam, area, viewport);
// store the computed viewport in the scene
@@ -1191,19 +1196,24 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
override_camera = override_camera && (cam->GetName() == "__default__cam__");
if (override_camera && m_overrideCamUseOrtho) {
- MT_CmMatrix4x4 projmat = m_overrideCamProjMat;
- m_rasterizer->SetProjectionMatrix(projmat);
+ m_rasterizer->SetProjectionMatrix(m_overrideCamProjMat);
+ if (!cam->hasValidProjectionMatrix()) {
+ // needed to get frustrum planes for culling
+ MT_Matrix4x4 projmat;
+ projmat.setValue(m_overrideCamProjMat.getPointer());
+ cam->SetProjectionMatrix(projmat);
+ }
} else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() )
{
m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
} else
{
RAS_FrameFrustum frustum;
- float lens = cam->GetLens();
bool orthographic = !cam->GetCameraData()->m_perspective;
nearfrust = cam->GetCameraNear();
farfrust = cam->GetCameraFar();
focallength = cam->GetFocalLength();
+ MT_Matrix4x4 projmat;
if(override_camera) {
nearfrust = m_overrideCamNear;
@@ -1211,50 +1221,58 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
}
if (orthographic) {
- lens *= ortho;
- nearfrust = (nearfrust + 1.0)*ortho;
- farfrust *= ortho;
- }
-
- RAS_FramingManager::ComputeFrustum(
- scene->GetFramingType(),
- area,
- viewport,
- lens,
- nearfrust,
- farfrust,
- frustum
- );
- left = frustum.x1 * m_cameraZoom;
- right = frustum.x2 * m_cameraZoom;
- bottom = frustum.y1 * m_cameraZoom;
- top = frustum.y2 * m_cameraZoom;
- nearfrust = frustum.camnear;
- farfrust = frustum.camfar;
+ RAS_FramingManager::ComputeOrtho(
+ scene->GetFramingType(),
+ area,
+ viewport,
+ cam->GetScale(),
+ nearfrust,
+ farfrust,
+ frustum
+ );
+ if (!cam->GetViewport()) {
+ frustum.x1 *= m_cameraZoom;
+ frustum.x2 *= m_cameraZoom;
+ frustum.y1 *= m_cameraZoom;
+ frustum.y2 *= m_cameraZoom;
+ }
+ projmat = m_rasterizer->GetOrthoMatrix(
+ frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar);
- MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
- left, right, bottom, top, nearfrust, farfrust, focallength);
+ } else {
+ RAS_FramingManager::ComputeFrustum(
+ scene->GetFramingType(),
+ area,
+ viewport,
+ cam->GetLens(),
+ nearfrust,
+ farfrust,
+ frustum
+ );
+ if (!cam->GetViewport()) {
+ frustum.x1 *= m_cameraZoom;
+ frustum.x2 *= m_cameraZoom;
+ frustum.y1 *= m_cameraZoom;
+ frustum.y2 *= m_cameraZoom;
+ }
+ projmat = m_rasterizer->GetFrustumMatrix(
+ frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar, focallength);
+ }
cam->SetProjectionMatrix(projmat);
// Otherwise the projection matrix for each eye will be the same...
- if (m_rasterizer->Stereo())
+ if (!orthographic && m_rasterizer->Stereo())
cam->InvalidateProjectionMatrix();
}
MT_Transform camtrans(cam->GetWorldToCamera());
- if (!cam->GetCameraData()->m_perspective)
- camtrans.getOrigin()[2] *= ortho;
MT_Matrix4x4 viewmat(camtrans);
- m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
- cam->GetCameraLocation(), cam->GetCameraOrientation());
+ m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
cam->SetModelviewMatrix(viewmat);
- //redundant, already done in Render()
- //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
@@ -1274,6 +1292,9 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
scene->GetPhysicsEnvironment()->debugDrawWorld();
m_rasterizer->FlushDebugLines();
+
+ //it's running once for every scene (i.e. overlay scenes have it running twice). That's not the ideal.
+ PostRenderFrame();
}
void KX_KetsjiEngine::PostRenderFrame()
@@ -1401,7 +1422,7 @@ void KX_KetsjiEngine::RenderDebugProperties()
m_canvas->GetWidth(),
m_canvas->GetHeight());
double time = m_logger->GetAverage((KX_TimeCategory)j);
- debugtxt.Format("%2.2f %%", time/tottime * 100.f);
+ debugtxt.Format("%.3fms (%2.2f %%)", time*1000.f, time/tottime * 100.f);
m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
debugtxt.Ptr(),
xcoord + 60 ,ycoord,
@@ -1719,6 +1740,26 @@ void KX_KetsjiEngine::SetTicRate(double ticrate)
m_ticrate = ticrate;
}
+int KX_KetsjiEngine::GetMaxLogicFrame()
+{
+ return m_maxLogicFrame;
+}
+
+void KX_KetsjiEngine::SetMaxLogicFrame(int frame)
+{
+ m_maxLogicFrame = frame;
+}
+
+int KX_KetsjiEngine::GetMaxPhysicsFrame()
+{
+ return m_maxPhysicsFrame;
+}
+
+void KX_KetsjiEngine::SetMaxPhysicsFrame(int frame)
+{
+ m_maxPhysicsFrame = frame;
+}
+
double KX_KetsjiEngine::GetAnimFrameRate()
{
return m_anim_framerate;
@@ -1729,6 +1770,11 @@ double KX_KetsjiEngine::GetClockTime(void) const
return m_clockTime;
}
+double KX_KetsjiEngine::GetRealTime(void) const
+{
+ return m_kxsystem->GetTimeInSeconds();
+}
+
void KX_KetsjiEngine::SetAnimFrameRate(double framerate)
{
m_anim_framerate = framerate;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index a8ccd6100d7..6fa379e551a 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -103,6 +103,8 @@ private:
double m_previousClockTime;//previous clock time
double m_remainingTime;
+ static int m_maxLogicFrame; /* maximum number of consecutive logic frame */
+ static int m_maxPhysicsFrame; /* maximum number of consecutive physics frame */
static double m_ticrate;
static double m_anim_framerate; /* for animation playback only - ipo and action */
@@ -210,7 +212,7 @@ public:
RAS_IRenderTools* GetRenderTools(){return m_rendertools;};
/// Dome functions
- void InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text);
+ void InitDome(short res, short mode, short angle, float resbuf, short tilt, struct Text* text);
void EndDome();
void RenderDome();
bool m_usedome;
@@ -269,6 +271,7 @@ public:
*/
double GetClockTime(void) const;
+ double GetRealTime(void) const;
/**
* Returns the difference between the local time of the scene (when it
* was running and not suspended) and the "curtime"
@@ -283,6 +286,22 @@ public:
* Sets the number of logic updates per second.
*/
static void SetTicRate(double ticrate);
+ /**
+ * Gets the maximum number of logic frame before render frame
+ */
+ static int GetMaxLogicFrame();
+ /**
+ * Sets the maximum number of logic frame before render frame
+ */
+ static void SetMaxLogicFrame(int frame);
+ /**
+ * Gets the maximum number of physics frame before render frame
+ */
+ static int GetMaxPhysicsFrame();
+ /**
+ * Sets the maximum number of physics frame before render frame
+ */
+ static void SetMaxPhysicsFrame(int frame);
/**
* Gets the framerate for playing animations. (actions and ipos)
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 713838c88ec..fe575384a35 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -82,10 +82,7 @@ CValue* KX_LightObject::GetReplica()
KX_LightObject* replica = new KX_LightObject(*this);
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
- ProcessReplica(replica);
+ replica->ProcessReplica();
replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr();
m_rendertools->AddLight(&replica->m_lightobj);
@@ -105,8 +102,11 @@ void KX_LightObject::Update()
{
GPULamp *lamp;
- if((lamp = GetGPULamp())) {
+ if((lamp = GetGPULamp()) != NULL && GetSGNode()) {
float obmat[4][4];
+ // lights don't get their openGL matrix updated, do it now
+ if (GetSGNode()->IsDirty())
+ GetOpenGLMatrix();
double *dobmat = GetOpenGLMatrixPtr()->getPointer();
for(int i=0; i<4; i++)
@@ -114,6 +114,8 @@ void KX_LightObject::Update()
obmat[i][j] = (float)*dobmat;
GPU_lamp_update(lamp, m_lightobj.m_layer, obmat);
+ GPU_lamp_update_colors(lamp, m_lightobj.m_red, m_lightobj.m_green,
+ m_lightobj.m_blue, m_lightobj.m_energy);
}
}
@@ -163,8 +165,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T
/* setup rasterizer transformations */
ras->SetProjectionMatrix(projectionmat);
- ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(),
- cam->GetCameraLocation(), cam->GetCameraOrientation());
+ ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
}
void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
@@ -173,160 +174,23 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
GPU_lamp_shadow_buffer_unbind(lamp);
}
-PyObject* KX_LightObject::py_getattro(PyObject *attr)
-{
- char *attr_str= PyString_AsString(attr);
-
- if (!strcmp(attr_str, "layer"))
- return PyInt_FromLong(m_lightobj.m_layer);
-
- if (!strcmp(attr_str, "energy"))
- return PyFloat_FromDouble(m_lightobj.m_energy);
-
- if (!strcmp(attr_str, "distance"))
- return PyFloat_FromDouble(m_lightobj.m_distance);
-
- if (!strcmp(attr_str, "colour") || !strcmp(attr_str, "color"))
- return Py_BuildValue("[fff]", m_lightobj.m_red, m_lightobj.m_green, m_lightobj.m_blue);
-
- if (!strcmp(attr_str, "lin_attenuation"))
- return PyFloat_FromDouble(m_lightobj.m_att1);
-
- if (!strcmp(attr_str, "quad_attenuation"))
- return PyFloat_FromDouble(m_lightobj.m_att2);
-
- if (!strcmp(attr_str, "spotsize"))
- return PyFloat_FromDouble(m_lightobj.m_spotsize);
-
- if (!strcmp(attr_str, "spotblend"))
- return PyFloat_FromDouble(m_lightobj.m_spotblend);
-
- if (!strcmp(attr_str, "SPOT"))
- return PyInt_FromLong(RAS_LightObject::LIGHT_SPOT);
-
- if (!strcmp(attr_str, "SUN"))
- return PyInt_FromLong(RAS_LightObject::LIGHT_SUN);
-
- if (!strcmp(attr_str, "NORMAL"))
- return PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL);
-
- if (!strcmp(attr_str, "type"))
- return PyInt_FromLong(m_lightobj.m_type);
-
- py_getattro_up(KX_GameObject);
-}
-
+/* ------------------------------------------------------------------------- */
+/* Python Integration Hooks */
+/* ------------------------------------------------------------------------- */
-int KX_LightObject::py_setattro(PyObject *attr, PyObject *pyvalue)
-{
- char *attr_str= PyString_AsString(attr);
-
- if (PyInt_Check(pyvalue))
- {
- int value = PyInt_AsLong(pyvalue);
- if (!strcmp(attr_str, "layer"))
- {
- m_lightobj.m_layer = value;
- return PY_SET_ATTR_SUCCESS;
- }
-
- if (!strcmp(attr_str, "type"))
- {
- if (value >= RAS_LightObject::LIGHT_SPOT && value <= RAS_LightObject::LIGHT_NORMAL)
- m_lightobj.m_type = (RAS_LightObject::LightType) value;
- return PY_SET_ATTR_SUCCESS;
- }
- }
-
- if (PyFloat_Check(pyvalue) || PyInt_Check(pyvalue))
- {
- float value = PyFloat_AsDouble(pyvalue);
- if (!strcmp(attr_str, "energy"))
- {
- m_lightobj.m_energy = value;
- return PY_SET_ATTR_SUCCESS;
- }
-
- if (!strcmp(attr_str, "distance"))
- {
- m_lightobj.m_distance = value;
- return PY_SET_ATTR_SUCCESS;
- }
-
- if (!strcmp(attr_str, "lin_attenuation"))
- {
- m_lightobj.m_att1 = value;
- return PY_SET_ATTR_SUCCESS;
- }
-
- if (!strcmp(attr_str, "quad_attenuation"))
- {
- m_lightobj.m_att2 = value;
- return PY_SET_ATTR_SUCCESS;
- }
-
- if (!strcmp(attr_str, "spotsize"))
- {
- m_lightobj.m_spotsize = value;
- return PY_SET_ATTR_SUCCESS;
- }
-
- if (!strcmp(attr_str, "spotblend"))
- {
- m_lightobj.m_spotblend = value;
- return PY_SET_ATTR_SUCCESS;
- }
- }
-
- if (PySequence_Check(pyvalue))
- {
- if (!strcmp(attr_str, "colour") || !strcmp(attr_str, "color"))
- {
- MT_Vector3 color;
- if (PyVecTo(pyvalue, color))
- {
- m_lightobj.m_red = color[0];
- m_lightobj.m_green = color[1];
- m_lightobj.m_blue = color[2];
- return PY_SET_ATTR_SUCCESS;
- }
- return PY_SET_ATTR_FAIL;
- }
- }
-
- if (!strcmp(attr_str, "SPOT") || !strcmp(attr_str, "SUN") || !strcmp(attr_str, "NORMAL"))
- {
- PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr_str);
- return PY_SET_ATTR_FAIL;
- }
-
- return KX_GameObject::py_setattro(attr, pyvalue);
+PyObject* KX_LightObject::py_getattro_dict() {
+ py_getattro_dict_up(KX_GameObject);
}
-PyMethodDef KX_LightObject::Methods[] = {
- {NULL,NULL} //Sentinel
-};
-
-PyAttributeDef KX_LightObject::Attributes[] = {
- KX_PYATTRIBUTE_DUMMY("layer"),
- KX_PYATTRIBUTE_DUMMY("energy"),
- KX_PYATTRIBUTE_DUMMY("distance"),
- KX_PYATTRIBUTE_DUMMY("colour"),
- KX_PYATTRIBUTE_DUMMY("color"),
- KX_PYATTRIBUTE_DUMMY("lin_attenuation"),
- KX_PYATTRIBUTE_DUMMY("quad_attenuation"),
- KX_PYATTRIBUTE_DUMMY("spotsize"),
- KX_PYATTRIBUTE_DUMMY("spotblend"),
- KX_PYATTRIBUTE_DUMMY("SPOT"),
- KX_PYATTRIBUTE_DUMMY("SUN"),
- KX_PYATTRIBUTE_DUMMY("NORMAL"),
- KX_PYATTRIBUTE_DUMMY("type"),
- { NULL } //Sentinel
-};
PyTypeObject KX_LightObject::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_LightObject",
sizeof(PyObjectPlus_Proxy),
0,
@@ -352,3 +216,103 @@ PyParentObject KX_LightObject::Parents[] = {
&CValue::Type,
NULL
};
+
+PyMethodDef KX_LightObject::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef KX_LightObject::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RW("layer", 1, 20, true, KX_LightObject, m_lightobj.m_layer),
+ KX_PYATTRIBUTE_FLOAT_RW("energy", 0, 10, KX_LightObject, m_lightobj.m_energy),
+ KX_PYATTRIBUTE_FLOAT_RW("distance", 0.01, 5000, KX_LightObject, m_lightobj.m_distance),
+ KX_PYATTRIBUTE_RW_FUNCTION("color", KX_LightObject, pyattr_get_color, pyattr_set_color),
+ KX_PYATTRIBUTE_RW_FUNCTION("colour", KX_LightObject, pyattr_get_color, pyattr_set_color),
+ KX_PYATTRIBUTE_FLOAT_RW("lin_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att1),
+ KX_PYATTRIBUTE_FLOAT_RW("quad_attenuation", 0, 1, KX_LightObject, m_lightobj.m_att2),
+ KX_PYATTRIBUTE_FLOAT_RW("spotsize", 1, 180, KX_LightObject, m_lightobj.m_spotsize),
+ KX_PYATTRIBUTE_FLOAT_RW("spotblend", 0, 1, KX_LightObject, m_lightobj.m_spotblend),
+ KX_PYATTRIBUTE_RO_FUNCTION("SPOT", KX_LightObject, pyattr_get_typeconst),
+ KX_PYATTRIBUTE_RO_FUNCTION("SUN", KX_LightObject, pyattr_get_typeconst),
+ KX_PYATTRIBUTE_RO_FUNCTION("NORMAL", KX_LightObject, pyattr_get_typeconst),
+ KX_PYATTRIBUTE_RW_FUNCTION("type", KX_LightObject, pyattr_get_type, pyattr_set_type),
+ { NULL } //Sentinel
+};
+
+PyObject* KX_LightObject::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return Py_BuildValue("[fff]", self->m_lightobj.m_red, self->m_lightobj.m_green, self->m_lightobj.m_blue);
+}
+
+int KX_LightObject::pyattr_set_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+
+ MT_Vector3 color;
+ if (PyVecTo(value, color))
+ {
+ self->m_lightobj.m_red = color[0];
+ self->m_lightobj.m_green = color[1];
+ self->m_lightobj.m_blue = color[2];
+ return PY_SET_ATTR_SUCCESS;
+ }
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ PyObject* retvalue;
+
+ const char* type = attrdef->m_name;
+
+ if(strcmp(type, "SPOT")) {
+ retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SPOT);
+ } else if (strcmp(type, "SUN")) {
+ retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SUN);
+ } else if (strcmp(type, "NORMAL")) {
+ retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL);
+ }
+
+ return retvalue;
+}
+
+PyObject* KX_LightObject::pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ return PyInt_FromLong(self->m_lightobj.m_type);
+}
+
+int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value)
+{
+ KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ int val = PyInt_AsLong(value);
+ if((val==-1 && PyErr_Occurred()) || val<0 || val>2) {
+ PyErr_SetString(PyExc_ValueError, "light.type= val: KX_LightObject, expected an int between 0 and 2");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ switch(val) {
+ case 0:
+ self->m_lightobj.m_type = self->m_lightobj.LIGHT_SPOT;
+ break;
+ case 1:
+ self->m_lightobj.m_type = self->m_lightobj.LIGHT_SUN;
+ break;
+ case 2:
+ self->m_lightobj.m_type = self->m_lightobj.LIGHT_NORMAL;
+ break;
+ }
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+
+PyObject* KX_LightObject::py_getattro(PyObject *attr)
+{
+ py_getattro_up(KX_GameObject);
+}
+
+int KX_LightObject::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(KX_GameObject);
+}
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 4559954c8d7..35f25515e3b 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -63,8 +63,16 @@ public:
void Update();
virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
+ /* attributes */
+ static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value);
+ static PyObject* pyattr_get_typeconst(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value);
+
virtual bool IsLight(void) { return true; }
};
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index 6be1da55ff8..11effa1ca98 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -46,8 +46,13 @@
#include "PyObjectPlus.h"
PyTypeObject KX_MeshProxy::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_MeshProxy",
sizeof(PyObjectPlus_Proxy),
0,
@@ -66,7 +71,6 @@ PyTypeObject KX_MeshProxy::Type = {
PyParentObject KX_MeshProxy::Parents[] = {
&KX_MeshProxy::Type,
- &SCA_IObject::Type,
&CValue::Type,
&PyObjectPlus::Type,
NULL
@@ -105,17 +109,21 @@ void KX_MeshProxy::SetMeshModified(bool v)
PyObject* KX_MeshProxy::py_getattro(PyObject *attr)
{
- py_getattro_up(SCA_IObject);
+ py_getattro_up(CValue);
+}
+
+PyObject* KX_MeshProxy::py_getattro_dict() {
+ py_getattro_dict_up(CValue);
}
int KX_MeshProxy::py_setattro(PyObject *attr, PyObject* value)
{
- py_setattro_up(SCA_IObject);
+ py_setattro_up(CValue);
}
KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh)
- : SCA_IObject(&Type), m_meshobj(mesh)
+ : CValue(&Type), m_meshobj(mesh)
{
}
@@ -131,10 +139,9 @@ CValue* KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValu
const STR_String & KX_MeshProxy::GetText() {return m_meshobj->GetName();};
double KX_MeshProxy::GetNumber() { return -1;}
-STR_String KX_MeshProxy::GetName() { return m_meshobj->GetName();}
-void KX_MeshProxy::SetName(STR_String name) { };
+STR_String& KX_MeshProxy::GetName() { return m_meshobj->GetName();}
+void KX_MeshProxy::SetName(const char *name) { };
CValue* KX_MeshProxy::GetReplica() { return NULL;}
-void KX_MeshProxy::ReplicaSetName(STR_String name) {};
// stuff for python integration
@@ -213,24 +220,20 @@ PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* args, PyObject* kwds)
PyObject* KX_MeshProxy::PyGetVertex(PyObject* args, PyObject* kwds)
{
- int vertexindex= 1;
- int matindex= 1;
- PyObject* vertexob = NULL;
+ int vertexindex;
+ int matindex;
- if (PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex))
- {
- RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex);
- if (vertex)
- {
- vertexob = (new KX_VertexProxy(this, vertex))->NewProxy(true);
- }
- }
- else {
+ if (!PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex))
+ return NULL;
+
+ RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex);
+
+ if(vertex==NULL) {
+ PyErr_SetString(PyExc_ValueError, "mesh.getVertex(mat_idx, vert_idx): KX_MeshProxy, could not get a vertex at the given indicies");
return NULL;
}
-
- return vertexob;
-
+
+ return (new KX_VertexProxy(this, vertex))->NewProxy(true);
}
PyObject* KX_MeshProxy::PyGetPolygon(PyObject* args, PyObject* kwds)
@@ -262,8 +265,12 @@ PyObject* KX_MeshProxy::PyGetPolygon(PyObject* args, PyObject* kwds)
KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh,
"Reinstance the physics mesh.")
{
+#if 0
//this needs to be reviewed, it is dependend on Sumo/Solid. Who is using this ?
- Py_RETURN_NONE;//(KX_ReInstanceShapeFromMesh(m_meshobj)) ? Py_RETURN_TRUE : Py_RETURN_FALSE;
+ if(KX_ReInstanceShapeFromMesh(m_meshobj))
+ Py_RETURN_TRUE;
+#endif
+ Py_RETURN_FALSE;
}
PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -341,7 +348,7 @@ bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **object, bool py_none
/* sets the error */
if (*object==NULL) {
- PyErr_Format(PyExc_RuntimeError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
+ PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
return false;
}
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h
index aeecefc09e6..bfdd4be4118 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.h
+++ b/source/gameengine/Ketsji/KX_MeshProxy.h
@@ -34,7 +34,7 @@
/* utility conversion function */
bool ConvertPythonToMesh(PyObject * value, class RAS_MeshObject **object, bool py_none_ok, const char *error_prefix);
-class KX_MeshProxy : public SCA_IObject
+class KX_MeshProxy : public CValue
{
Py_Header;
@@ -51,13 +51,13 @@ public:
virtual const STR_String & GetText();
virtual double GetNumber();
virtual RAS_MeshObject* GetMesh() { return m_meshobj; }
- virtual STR_String GetName();
- virtual void SetName(STR_String name); // Set the name of the value
- virtual void ReplicaSetName(STR_String name);
+ virtual STR_String& GetName();
+ virtual void SetName(const char *name); // Set the name of the value
virtual CValue* GetReplica();
// stuff for python integration
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
KX_PYMETHOD(KX_MeshProxy,GetNumMaterials); // Deprecated
diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp
index b4d58dccfdf..60455d33312 100644
--- a/source/gameengine/Ketsji/KX_MotionState.cpp
+++ b/source/gameengine/Ketsji/KX_MotionState.cpp
@@ -73,6 +73,11 @@ void KX_MotionState::getWorldOrientation(float* ori)
mat.getValue(ori);
}
+void KX_MotionState::setWorldOrientation(const float* ori)
+{
+ m_node->SetLocalOrientation(ori);
+}
+
void KX_MotionState::setWorldPosition(float posX,float posY,float posZ)
{
m_node->SetLocalPosition(MT_Point3(posX,posY,posZ));
diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h
index 7ba3ca2f85c..0e43e88fbeb 100644
--- a/source/gameengine/Ketsji/KX_MotionState.h
+++ b/source/gameengine/Ketsji/KX_MotionState.h
@@ -45,6 +45,7 @@ public:
virtual void setWorldPosition(float posX,float posY,float posZ);
virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal);
virtual void getWorldOrientation(float* ori);
+ virtual void setWorldOrientation(const float* ori);
virtual void calculateWorldTransformations();
};
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 87b5c81392d..fde10a493db 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -86,7 +86,7 @@ void KX_MouseFocusSensor::Init()
m_hitNormal.setValue(0,0,1);
}
-bool KX_MouseFocusSensor::Evaluate(CValue* event)
+bool KX_MouseFocusSensor::Evaluate()
{
bool result = false;
bool obHasFocus = false;
@@ -119,7 +119,7 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event)
* mode is never used, because the converter never makes this
* sensor for a mouse-key event. It is here for
* completeness. */
- result = SCA_MouseSensor::Evaluate(event);
+ result = SCA_MouseSensor::Evaluate();
m_positive_event = (m_val!=0);
}
@@ -197,13 +197,15 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
* division by 0.0...*/
RAS_Rect area, viewport;
+ short m_y_inv = m_kxengine->GetCanvas()->GetHeight()-m_y;
+
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
+ m_y_inv < viewport.m_y2 && // below top
+ m_y_inv > viewport.m_y1) == 0) // above bottom
{
return false;
}
@@ -217,6 +219,10 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
MT_Vector4 frompoint;
MT_Vector4 topoint;
+ /* m_y_inv - inverting for a bounds check is only part of it, now make relative to view bounds */
+ m_y_inv = (viewport.m_y2 - m_y_inv) + viewport.m_y1;
+
+
/* There's some strangeness I don't fully get here... These values
* _should_ be wrong! - see from point Z values */
@@ -229,19 +235,18 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
* behind of the near and far clip planes.
*/
frompoint.setValue( (2 * (m_x-x_lb) / width) - 1.0,
- 1.0 - (2 * (m_y - y_lb) / height),
+ 1.0 - (2 * (m_y_inv - y_lb) / height),
+ /*cam->GetCameraData()->m_perspective ? 0.0:cdata->m_clipstart,*/ /* real clipstart is scaled in ortho for some reason, zero is ok */
0.0, /* nearclip, see above comments */
1.0 );
topoint.setValue( (2 * (m_x-x_lb) / width) - 1.0,
- 1.0 - (2 * (m_y-y_lb) / height),
- 1.0, /* farclip, see above comments */
+ 1.0 - (2 * (m_y_inv-y_lb) / height),
+ cam->GetCameraData()->m_perspective ? 1.0:cam->GetCameraData()->m_clipend, /* farclip, see above comments */
1.0 );
/* camera to world */
MT_Transform wcs_camcs_tranform = cam->GetWorldToCamera();
- if (!cam->GetCameraData()->m_perspective)
- wcs_camcs_tranform.getOrigin()[2] *= 100.0;
MT_Transform cams_wcs_transform;
cams_wcs_transform.invert(wcs_camcs_tranform);
@@ -335,8 +340,13 @@ const MT_Vector3& KX_MouseFocusSensor::HitNormal() const
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_MouseFocusSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_MouseFocusSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -387,6 +397,10 @@ PyObject* KX_MouseFocusSensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_MouseSensor);
}
+PyObject* KX_MouseFocusSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_MouseSensor);
+}
+
const char KX_MouseFocusSensor::GetHitObject_doc[] =
"getHitObject()\n"
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 8de1f88c5c3..29d674eb305 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -63,13 +63,13 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
virtual CValue* GetReplica() {
CValue* replica = new KX_MouseFocusSensor(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
};
/**
* @attention Overrides default evaluate.
*/
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual void Init();
virtual bool IsPositiveTrigger() {
@@ -89,7 +89,8 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayTarget);
KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRaySource);
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 0489b7090e9..44842b7f5b3 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -36,6 +36,7 @@
#include "KX_Scene.h" // needed to create a replica
#include "PHY_IPhysicsEnvironment.h"
#include "PHY_IPhysicsController.h"
+#include "PHY_IMotionState.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -62,7 +63,7 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
{
gameobj->getClientInfo()->m_sensors.remove(this);
- m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::NEAR);
+ m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::SENSOR);
m_client_info->m_sensors.push_back(this);
//DT_ShapeHandle shape = (DT_ShapeHandle) vshape;
@@ -81,81 +82,50 @@ void KX_NearSensor::SynchronizeTransform()
// not linked to the parent object, must synchronize it.
if (m_physCtrl)
{
+ PHY_IMotionState* motionState = m_physCtrl->GetMotionState();
KX_GameObject* parent = ((KX_GameObject*)GetParent());
- MT_Vector3 pos = parent->NodeGetWorldPosition();
- MT_Quaternion orn = parent->NodeGetWorldOrientation().getRotation();
- m_physCtrl->setPosition(pos.x(),pos.y(),pos.z());
- m_physCtrl->setOrientation(orn.x(),orn.y(),orn.z(),orn.w());
- m_physCtrl->calcXform();
+ const MT_Point3& pos = parent->NodeGetWorldPosition();
+ float ori[12];
+ parent->NodeGetWorldOrientation().getValue(ori);
+ motionState->setWorldPosition(pos[0], pos[1], pos[2]);
+ motionState->setWorldOrientation(ori);
+ m_physCtrl->WriteMotionStateToDynamics(true);
}
}
-void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman)
-{
- if (m_physCtrl)
- {
- touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl);
- }
-}
-
-void KX_NearSensor::UnregisterSumo(KX_TouchEventManager* touchman)
+CValue* KX_NearSensor::GetReplica()
{
- if (m_physCtrl)
- {
- touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl);
- }
+ KX_NearSensor* replica = new KX_NearSensor(*this);
+ replica->ProcessReplica();
+ return replica;
}
-CValue* KX_NearSensor::GetReplica()
+void KX_NearSensor::ProcessReplica()
{
- KX_NearSensor* replica = new KX_NearSensor(*this);
- replica->m_colliders = new CListValue();
- replica->Init();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ KX_TouchSensor::ProcessReplica();
- replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR);
+ m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::SENSOR);
- if (replica->m_physCtrl)
+ if (m_physCtrl)
{
- replica->m_physCtrl = replica->m_physCtrl->GetReplica();
- if (replica->m_physCtrl)
+ m_physCtrl = m_physCtrl->GetReplica();
+ if (m_physCtrl)
{
//static_cast<KX_TouchEventManager*>(m_eventmgr)->GetPhysicsEnvironment()->addSensor(replica->m_physCtrl);
- replica->m_physCtrl->SetMargin(m_Margin);
- replica->m_physCtrl->setNewClientInfo(replica->m_client_info);
+ m_physCtrl->SetMargin(m_Margin);
+ m_physCtrl->setNewClientInfo(m_client_info);
}
}
- //Wrong: the parent object could be a child, this code works only if it is a root parent.
- //Anyway, at this stage, the parent object is already synchronized, nothing to do.
- //bool parentUpdated = false;
- //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL, parentUpdated);
- replica->SynchronizeTransform();
-
- return replica;
}
-
-
void KX_NearSensor::ReParent(SCA_IObject* parent)
{
+ SCA_ISensor::ReParent(parent);
m_client_info->m_gameobject = static_cast<KX_GameObject*>(parent);
m_client_info->m_sensors.push_back(this);
-
-
-/* KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
- client_info->m_gameobject = gameobj;
- client_info->m_auxilary_info = NULL;
-
- client_info->m_sensors.push_back(this);
- SCA_ISensor::ReParent(parent);
-*/
- //Not needed, was done in GetReplica() already
- //bool parentUpdated = false;
- //((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
- //SynchronizeTransform();
- SCA_ISensor::ReParent(parent);
+ //Synchronize here with the actual parent.
+ SynchronizeTransform();
}
@@ -177,7 +147,7 @@ KX_NearSensor::~KX_NearSensor()
}
-bool KX_NearSensor::Evaluate(CValue* event)
+bool KX_NearSensor::Evaluate()
{
bool result = false;
// KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent());
@@ -286,8 +256,13 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData
/* ------------------------------------------------------------------------- */
PyTypeObject KX_NearSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_NearSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -334,6 +309,10 @@ PyObject* KX_NearSensor::py_getattro(PyObject *attr)
py_getattro_up(KX_TouchSensor);
}
+PyObject* KX_NearSensor::py_getattro_dict() {
+ py_getattro_dict_up(KX_TouchSensor);
+}
+
int KX_NearSensor::py_setattro(PyObject*attr, PyObject* value)
{
py_setattro_up(KX_TouchSensor);
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
index 26c5feb4e67..63099e181a0 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.h
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -70,19 +70,21 @@ public:
virtual ~KX_NearSensor();
virtual void SynchronizeTransform();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual void ProcessReplica();
+ virtual bool Evaluate();
virtual void ReParent(SCA_IObject* parent);
virtual bool NewHandleCollision(void* obj1,void* obj2,
const PHY_CollData * coll_data);
virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2);
- virtual void RegisterSumo(KX_TouchEventManager *touchman);
- virtual void UnregisterSumo(KX_TouchEventManager* touchman);
+ virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2) { return false; };
+ virtual sensortype GetSensorType() { return ST_NEAR; }
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
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 861c5757971..eaae04d406d 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -31,6 +31,7 @@
#include "KX_ObjectActuator.h"
#include "KX_GameObject.h"
+#include "KX_PyMath.h" // For PyVecTo - should this include be put in PyObjectPlus?
#include "KX_IPhysicsController.h"
#ifdef HAVE_CONFIG_H
@@ -44,6 +45,7 @@
KX_ObjectActuator::
KX_ObjectActuator(
SCA_IObject* gameobj,
+ KX_GameObject* refobj,
const MT_Vector3& force,
const MT_Vector3& torque,
const MT_Vector3& dloc,
@@ -68,6 +70,7 @@ KX_ObjectActuator(
m_previous_error(0.0,0.0,0.0),
m_error_accumulator(0.0,0.0,0.0),
m_bitLocalFlag (flag),
+ m_reference(refobj),
m_active_combined_velocity (false),
m_linear_damping_active(false),
m_angular_damping_active(false)
@@ -76,10 +79,20 @@ KX_ObjectActuator(
{
// in servo motion, the force is local if the target velocity is local
m_bitLocalFlag.Force = m_bitLocalFlag.LinearVelocity;
+
+ m_pid = m_torque;
}
+ if (m_reference)
+ m_reference->RegisterActuator(this);
UpdateFuzzyFlags();
}
+KX_ObjectActuator::~KX_ObjectActuator()
+{
+ if (m_reference)
+ m_reference->UnregisterActuator(this);
+}
+
bool KX_ObjectActuator::Update()
{
@@ -128,11 +141,23 @@ bool KX_ObjectActuator::Update()
if (mass < MT_EPSILON)
return false;
MT_Vector3 v = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
+ if (m_reference)
+ {
+ const MT_Point3& mypos = parent->NodeGetWorldPosition();
+ const MT_Point3& refpos = m_reference->NodeGetWorldPosition();
+ MT_Point3 relpos;
+ relpos = (mypos-refpos);
+ MT_Vector3 vel= m_reference->GetVelocity(relpos);
+ if (m_bitLocalFlag.LinearVelocity)
+ // must convert in local space
+ vel = parent->NodeGetWorldOrientation().transposed()*vel;
+ v -= vel;
+ }
MT_Vector3 e = m_linear_velocity - v;
MT_Vector3 dv = e - m_previous_error;
MT_Vector3 I = m_error_accumulator + e;
- m_force = m_torque.x()*e+m_torque.y()*I+m_torque.z()*dv;
+ m_force = m_pid.x()*e+m_pid.y()*I+m_pid.z()*dv;
// to automatically adapt the PID coefficient to mass;
m_force *= mass;
if (m_bitLocalFlag.Torque)
@@ -253,13 +278,37 @@ CValue* KX_ObjectActuator::GetReplica()
KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName());
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
return replica;
}
+void KX_ObjectActuator::ProcessReplica()
+{
+ SCA_IActuator::ProcessReplica();
+ if (m_reference)
+ m_reference->RegisterActuator(this);
+}
+bool KX_ObjectActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == (SCA_IObject*)m_reference)
+ {
+ // this object is being deleted, we cannot continue to use it as reference.
+ m_reference = NULL;
+ return true;
+ }
+ return false;
+}
+
+void KX_ObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_reference];
+ if (h_obj) {
+ if (m_reference)
+ m_reference->UnregisterActuator(this);
+ m_reference = (KX_GameObject*)(*h_obj);
+ m_reference->RegisterActuator(this);
+ }
+}
/* some 'standard' utilities... */
bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
@@ -277,8 +326,13 @@ bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_ObjectActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_ObjectActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -304,6 +358,7 @@ PyParentObject KX_ObjectActuator::Parents[] = {
};
PyMethodDef KX_ObjectActuator::Methods[] = {
+ // Deprecated ----->
{"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_NOARGS},
{"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS},
{"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_NOARGS},
@@ -327,18 +382,188 @@ PyMethodDef KX_ObjectActuator::Methods[] = {
{"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_NOARGS},
{"getPID", (PyCFunction) KX_ObjectActuator::sPySetPID, METH_VARARGS},
-
+ // <----- Deprecated
{NULL,NULL} //Sentinel
};
PyAttributeDef KX_ObjectActuator::Attributes[] = {
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("force", -1000, 1000, false, KX_ObjectActuator, m_force, PyUpdateFuzzyFlags),
+ KX_PYATTRIBUTE_BOOL_RW("useLocalForce", KX_ObjectActuator, m_bitLocalFlag.Force),
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("torque", -1000, 1000, false, KX_ObjectActuator, m_torque, PyUpdateFuzzyFlags),
+ KX_PYATTRIBUTE_BOOL_RW("useLocalTorque", KX_ObjectActuator, m_bitLocalFlag.Torque),
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("dLoc", -1000, 1000, false, KX_ObjectActuator, m_dloc, PyUpdateFuzzyFlags),
+ KX_PYATTRIBUTE_BOOL_RW("useLocalDLoc", KX_ObjectActuator, m_bitLocalFlag.DLoc),
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("dRot", -1000, 1000, false, KX_ObjectActuator, m_drot, PyUpdateFuzzyFlags),
+ KX_PYATTRIBUTE_BOOL_RW("useLocalDRot", KX_ObjectActuator, m_bitLocalFlag.DRot),
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("linV", -1000, 1000, false, KX_ObjectActuator, m_linear_velocity, PyUpdateFuzzyFlags),
+ KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity),
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("angV", -1000, 1000, false, KX_ObjectActuator, m_angular_velocity, PyUpdateFuzzyFlags),
+ KX_PYATTRIBUTE_BOOL_RW("useLocalAngV", KX_ObjectActuator, m_bitLocalFlag.AngularVelocity),
+ KX_PYATTRIBUTE_SHORT_RW("damping", 0, 1000, false, KX_ObjectActuator, m_damping),
+ KX_PYATTRIBUTE_RW_FUNCTION("forceLimitX", KX_ObjectActuator, pyattr_get_forceLimitX, pyattr_set_forceLimitX),
+ KX_PYATTRIBUTE_RW_FUNCTION("forceLimitY", KX_ObjectActuator, pyattr_get_forceLimitY, pyattr_set_forceLimitY),
+ KX_PYATTRIBUTE_RW_FUNCTION("forceLimitZ", KX_ObjectActuator, pyattr_get_forceLimitZ, pyattr_set_forceLimitZ),
+ KX_PYATTRIBUTE_VECTOR_RW_CHECK("pid", -100, 200, true, KX_ObjectActuator, m_pid, PyCheckPid),
+ KX_PYATTRIBUTE_RW_FUNCTION("reference", KX_ObjectActuator,pyattr_get_reference,pyattr_set_reference),
{ NULL } //Sentinel
};
PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
-};
+}
+
+
+PyObject* KX_ObjectActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
+int KX_ObjectActuator::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(SCA_IActuator);
+}
+
+/* Attribute get/set functions */
+
+PyObject* KX_ObjectActuator::pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[0]));
+ PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.Torque));
+
+ return retVal;
+}
+
+int KX_ObjectActuator::pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
+
+ PyObject* seq = PySequence_Fast(value, "");
+ if (seq && PySequence_Fast_GET_SIZE(seq) == 3)
+ {
+ self->m_drot[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0));
+ self->m_dloc[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1));
+ self->m_bitLocalFlag.Torque = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0);
+
+ if (!PyErr_Occurred())
+ {
+ Py_DECREF(seq);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ }
+
+ Py_XDECREF(seq);
+
+ PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool");
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject* KX_ObjectActuator::pyattr_get_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[1]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[1]));
+ PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.DLoc));
+
+ return retVal;
+}
+
+int KX_ObjectActuator::pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
+
+ PyObject* seq = PySequence_Fast(value, "");
+ if (seq && PySequence_Fast_GET_SIZE(seq) == 3)
+ {
+ self->m_drot[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0));
+ self->m_dloc[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1));
+ self->m_bitLocalFlag.DLoc = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0);
+
+ if (!PyErr_Occurred())
+ {
+ Py_DECREF(seq);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ }
+
+ Py_XDECREF(seq);
+
+ PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool");
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject* KX_ObjectActuator::pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(self->m_drot[2]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(self->m_dloc[2]));
+ PyList_SET_ITEM(retVal, 2, PyBool_FromLong(self->m_bitLocalFlag.DRot));
+
+ return retVal;
+}
+
+int KX_ObjectActuator::pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
+
+ PyObject* seq = PySequence_Fast(value, "");
+ if (seq && PySequence_Fast_GET_SIZE(seq) == 3)
+ {
+ self->m_drot[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0));
+ self->m_dloc[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1));
+ self->m_bitLocalFlag.DRot = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0);
+
+ if (!PyErr_Occurred())
+ {
+ Py_DECREF(seq);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ }
+
+ Py_XDECREF(seq);
+
+ PyErr_SetString(PyExc_ValueError, "expected a sequence of 2 floats and a bool");
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject* KX_ObjectActuator::pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_ObjectActuator* actuator = static_cast<KX_ObjectActuator*>(self);
+ if (!actuator->m_reference)
+ Py_RETURN_NONE;
+
+ return actuator->m_reference->GetProxy();
+}
+
+int KX_ObjectActuator::pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ObjectActuator* actuator = static_cast<KX_ObjectActuator*>(self);
+ KX_GameObject *refOb;
+
+ if (!ConvertPythonToGameObject(value, &refOb, true, "actu.reference = value: KX_ObjectActuator"))
+ return PY_SET_ATTR_FAIL;
+
+ if (actuator->m_reference)
+ actuator->m_reference->UnregisterActuator(actuator);
+
+ if(refOb==NULL) {
+ actuator->m_reference= NULL;
+ }
+ else {
+ actuator->m_reference = refOb;
+ actuator->m_reference->RegisterActuator(actuator);
+ }
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
/* 1. set ------------------------------------------------------------------ */
/* Removed! */
@@ -346,18 +571,20 @@ PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) {
/* 2. getForce */
PyObject* KX_ObjectActuator::PyGetForce()
{
+ ShowDeprecationWarning("getForce()", "the force and the useLocalForce properties");
PyObject *retVal = PyList_New(4);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_force[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_force[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_force[2]));
- PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_force[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_force[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_force[2]));
+ PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force));
return retVal;
}
/* 3. setForce */
PyObject* KX_ObjectActuator::PySetForce(PyObject* args)
{
+ ShowDeprecationWarning("setForce()", "the force and the useLocalForce properties");
float vecArg[3];
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi:setForce", &vecArg[0], &vecArg[1],
@@ -373,18 +600,20 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* args)
/* 4. getTorque */
PyObject* KX_ObjectActuator::PyGetTorque()
{
+ ShowDeprecationWarning("getTorque()", "the torque and the useLocalTorque properties");
PyObject *retVal = PyList_New(4);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
- PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_torque[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_torque[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_torque[2]));
+ PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque));
return retVal;
}
/* 5. setTorque */
PyObject* KX_ObjectActuator::PySetTorque(PyObject* args)
{
+ ShowDeprecationWarning("setTorque()", "the torque and the useLocalTorque properties");
float vecArg[3];
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi:setTorque", &vecArg[0], &vecArg[1],
@@ -400,18 +629,20 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* args)
/* 6. getDLoc */
PyObject* KX_ObjectActuator::PyGetDLoc()
{
+ ShowDeprecationWarning("getDLoc()", "the dLoc and the useLocalDLoc properties");
PyObject *retVal = PyList_New(4);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_dloc[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_dloc[2]));
- PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_dloc[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_dloc[2]));
+ PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc));
return retVal;
}
/* 7. setDLoc */
PyObject* KX_ObjectActuator::PySetDLoc(PyObject* args)
{
+ ShowDeprecationWarning("setDLoc()", "the dLoc and the useLocalDLoc properties");
float vecArg[3];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "fffi:setDLoc", &vecArg[0], &vecArg[1],
@@ -427,18 +658,20 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* args)
/* 8. getDRot */
PyObject* KX_ObjectActuator::PyGetDRot()
{
+ ShowDeprecationWarning("getDRot()", "the dRot and the useLocalDRot properties");
PyObject *retVal = PyList_New(4);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_drot[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_drot[2]));
- PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_drot[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_drot[2]));
+ PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot));
return retVal;
}
/* 9. setDRot */
PyObject* KX_ObjectActuator::PySetDRot(PyObject* args)
{
+ ShowDeprecationWarning("setDRot()", "the dRot and the useLocalDRot properties");
float vecArg[3];
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi:setDRot", &vecArg[0], &vecArg[1],
@@ -453,18 +686,20 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* args)
/* 10. getLinearVelocity */
PyObject* KX_ObjectActuator::PyGetLinearVelocity() {
+ ShowDeprecationWarning("getLinearVelocity()", "the linV and the useLocalLinV properties");
PyObject *retVal = PyList_New(4);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
- PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
+ PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
return retVal;
}
/* 11. setLinearVelocity */
PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) {
+ ShowDeprecationWarning("setLinearVelocity()", "the linV and the useLocalLinV properties");
float vecArg[3];
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi:setLinearVelocity", &vecArg[0], &vecArg[1],
@@ -480,17 +715,19 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* args) {
/* 12. getAngularVelocity */
PyObject* KX_ObjectActuator::PyGetAngularVelocity() {
+ ShowDeprecationWarning("getAngularVelocity()", "the angV and the useLocalAngV properties");
PyObject *retVal = PyList_New(4);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
- PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
+ PyList_SET_ITEM(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
return retVal;
}
/* 13. setAngularVelocity */
PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* args) {
+ ShowDeprecationWarning("setAngularVelocity()", "the angV and the useLocalAngV properties");
float vecArg[3];
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi:setAngularVelocity", &vecArg[0], &vecArg[1],
@@ -505,6 +742,7 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* args) {
/* 13. setDamping */
PyObject* KX_ObjectActuator::PySetDamping(PyObject* args) {
+ ShowDeprecationWarning("setDamping()", "the damping property");
int damping = 0;
if (!PyArg_ParseTuple(args, "i:setDamping", &damping) || damping < 0 || damping > 1000) {
return NULL;
@@ -515,22 +753,25 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* args) {
/* 13. getVelocityDamping */
PyObject* KX_ObjectActuator::PyGetDamping() {
+ ShowDeprecationWarning("getDamping()", "the damping property");
return Py_BuildValue("i",m_damping);
}
/* 6. getForceLimitX */
PyObject* KX_ObjectActuator::PyGetForceLimitX()
{
+ ShowDeprecationWarning("getForceLimitX()", "the forceLimitX property");
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[0]));
- PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[0]));
+ PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque));
return retVal;
}
/* 7. setForceLimitX */
PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* args)
{
+ ShowDeprecationWarning("setForceLimitX()", "the forceLimitX property");
float vecArg[2];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "ffi:setForceLimitX", &vecArg[0], &vecArg[1], &bToggle)) {
@@ -545,17 +786,19 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* args)
/* 6. getForceLimitY */
PyObject* KX_ObjectActuator::PyGetForceLimitY()
{
+ ShowDeprecationWarning("getForceLimitY()", "the forceLimitY property");
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[1]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
- PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[1]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
+ PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc));
return retVal;
}
/* 7. setForceLimitY */
PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* args)
{
+ ShowDeprecationWarning("setForceLimitY()", "the forceLimitY property");
float vecArg[2];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "ffi:setForceLimitY", &vecArg[0], &vecArg[1], &bToggle)) {
@@ -570,17 +813,19 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* args)
/* 6. getForceLimitZ */
PyObject* KX_ObjectActuator::PyGetForceLimitZ()
{
+ ShowDeprecationWarning("getForceLimitZ()", "the forceLimitZ property");
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[2]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[2]));
- PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_drot[2]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_dloc[2]));
+ PyList_SET_ITEM(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot));
return retVal;
}
/* 7. setForceLimitZ */
PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* args)
{
+ ShowDeprecationWarning("setForceLimitZ()", "the forceLimitZ property");
float vecArg[2];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "ffi:setForceLimitZ", &vecArg[0], &vecArg[1], &bToggle)) {
@@ -595,22 +840,24 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* args)
/* 4. getPID */
PyObject* KX_ObjectActuator::PyGetPID()
{
+ ShowDeprecationWarning("getPID()", "the pid property");
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_pid[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_pid[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_pid[2]));
return retVal;
}
/* 5. setPID */
PyObject* KX_ObjectActuator::PySetPID(PyObject* args)
{
+ ShowDeprecationWarning("setPID()", "the pid property");
float vecArg[3];
if (!PyArg_ParseTuple(args, "fff:setPID", &vecArg[0], &vecArg[1], &vecArg[2])) {
return NULL;
}
- m_torque.setValue(vecArg);
+ m_pid.setValue(vecArg);
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index a812942a0ae..f9bd2a0c748 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -35,8 +35,10 @@
#include "SCA_IActuator.h"
#include "MT_Vector3.h"
+class KX_GameObject;
+
//
-// Bitfield that stores the flags for each CValue derived class
+// Stores the flags for each CValue derived class
//
struct KX_LocalFlags {
KX_LocalFlags() :
@@ -55,20 +57,20 @@ struct KX_LocalFlags {
{
}
- unsigned short Force : 1;
- unsigned short Torque : 1;
- unsigned short DRot : 1;
- unsigned short DLoc : 1;
- unsigned short LinearVelocity : 1;
- unsigned short AngularVelocity : 1;
- unsigned short AddOrSetLinV : 1;
- unsigned short ServoControl : 1;
- unsigned short ZeroForce : 1;
- unsigned short ZeroTorque : 1;
- unsigned short ZeroDRot : 1;
- unsigned short ZeroDLoc : 1;
- unsigned short ZeroLinearVelocity : 1;
- unsigned short ZeroAngularVelocity : 1;
+ bool Force;
+ bool Torque;
+ bool DRot;
+ bool DLoc;
+ bool LinearVelocity;
+ bool AngularVelocity;
+ bool AddOrSetLinV;
+ bool ServoControl;
+ bool ZeroForce;
+ bool ZeroTorque;
+ bool ZeroDRot;
+ bool ZeroDLoc;
+ bool ZeroLinearVelocity;
+ bool ZeroAngularVelocity;
};
class KX_ObjectActuator : public SCA_IActuator
@@ -80,7 +82,8 @@ class KX_ObjectActuator : public SCA_IActuator
MT_Vector3 m_dloc;
MT_Vector3 m_drot;
MT_Vector3 m_linear_velocity;
- MT_Vector3 m_angular_velocity;
+ MT_Vector3 m_angular_velocity;
+ MT_Vector3 m_pid;
MT_Scalar m_linear_length2;
MT_Scalar m_angular_length2;
// used in damping
@@ -91,7 +94,7 @@ class KX_ObjectActuator : public SCA_IActuator
MT_Vector3 m_previous_error;
MT_Vector3 m_error_accumulator;
KX_LocalFlags m_bitLocalFlag;
-
+ KX_GameObject* m_reference;
// A hack bool -- oh no sorry everyone
// This bool is used to check if we have informed
// the physics object that we are no longer
@@ -120,6 +123,7 @@ public:
KX_ObjectActuator(
SCA_IObject* gameobj,
+ KX_GameObject* refobj,
const MT_Vector3& force,
const MT_Vector3& torque,
const MT_Vector3& dloc,
@@ -130,8 +134,11 @@ public:
const KX_LocalFlags& flag,
PyTypeObject* T=&Type
);
-
+ ~KX_ObjectActuator();
CValue* GetReplica();
+ void ProcessReplica();
+ bool UnlinkObject(SCA_IObject* clientobj);
+ void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
void SetForceLoc(const double force[3]) { /*m_force=force;*/ }
void UpdateFuzzyFlags()
@@ -154,6 +161,8 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
+ virtual int py_setattro(PyObject *attr, PyObject *value);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce);
KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForce);
@@ -177,6 +186,53 @@ public:
KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForceLimitZ);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetPID);
KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetPID);
+
+ /* Attributes */
+ static PyObject* pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+ // This lets the attribute macros use UpdateFuzzyFlags()
+ static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef)
+ {
+ KX_ObjectActuator* act = reinterpret_cast<KX_ObjectActuator*>(self);
+ act->UpdateFuzzyFlags();
+ return 0;
+ }
+
+ // This is the keep the PID values in check after they are assigned with Python
+ static int PyCheckPid(void *self, const PyAttributeDef *attrdef)
+ {
+ KX_ObjectActuator* act = reinterpret_cast<KX_ObjectActuator*>(self);
+
+ //P 0 to 200
+ if (act->m_pid[0] < 0) {
+ act->m_pid[0] = 0;
+ } else if (act->m_pid[0] > 200) {
+ act->m_pid[0] = 200;
+ }
+
+ //I 0 to 3
+ if (act->m_pid[1] < 0) {
+ act->m_pid[1] = 0;
+ } else if (act->m_pid[1] > 3) {
+ act->m_pid[1] = 3;
+ }
+
+ //D -100 to 100
+ if (act->m_pid[2] < -100) {
+ act->m_pid[2] = -100;
+ } else if (act->m_pid[2] > 100) {
+ act->m_pid[2] = 100;
+ }
+
+ return 0;
+ }
};
#endif //__KX_OBJECTACTUATOR
diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h
index 21b7e632d83..8c3974c38a3 100644
--- a/source/gameengine/Ketsji/KX_OdePhysicsController.h
+++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h
@@ -70,6 +70,7 @@ public:
virtual void setOrientation(const MT_Matrix3x3& orn);
virtual void setPosition(const MT_Point3& pos);
virtual void setScaling(const MT_Vector3& scaling);
+ virtual void SetTransform() {}
virtual MT_Scalar GetMass();
virtual MT_Vector3 getReactionForce();
virtual void setRigidBody(bool rigid);
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 0093cf5f313..cd2ed456c48 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -48,10 +48,14 @@
KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj,
int mode,
+ bool addToCompound,
+ bool ghost,
SCA_IObject *ob,
PyTypeObject* T)
: SCA_IActuator(gameobj, T),
m_mode(mode),
+ m_addToCompound(addToCompound),
+ m_ghost(ghost),
m_ob(ob)
{
if (m_ob)
@@ -73,8 +77,6 @@ CValue* KX_ParentActuator::GetReplica()
KX_ParentActuator* replica = new KX_ParentActuator(*this);
// replication just copy the m_base pointer => common random generator
replica->ProcessReplica();
- CValue::AddDataToReplica(replica);
-
return replica;
}
@@ -123,7 +125,7 @@ bool KX_ParentActuator::Update()
switch (m_mode) {
case KX_PARENT_SET:
if (m_ob)
- obj->SetParent(scene, (KX_GameObject*)m_ob);
+ obj->SetParent(scene, (KX_GameObject*)m_ob, m_addToCompound, m_ghost);
break;
case KX_PARENT_REMOVE:
obj->RemoveParent(scene);
@@ -139,8 +141,13 @@ bool KX_ParentActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_ParentActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_ParentActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -175,6 +182,9 @@ PyMethodDef KX_ParentActuator::Methods[] = {
PyAttributeDef KX_ParentActuator::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object),
+ KX_PYATTRIBUTE_INT_RW("mode", KX_PARENT_NODEF+1, KX_PARENT_MAX-1, true, KX_ParentActuator, m_mode),
+ KX_PYATTRIBUTE_BOOL_RW("compound", KX_ParentActuator, m_addToCompound),
+ KX_PYATTRIBUTE_BOOL_RW("ghost", KX_ParentActuator, m_ghost),
{ NULL } //Sentinel
};
@@ -193,7 +203,7 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE
KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator"))
- return 1; // ConvertPythonToGameObject sets the error
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
if (actuator->m_ob != NULL)
actuator->m_ob->UnregisterActuator(actuator);
@@ -203,7 +213,7 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE
if (actuator->m_ob)
actuator->m_ob->RegisterActuator(actuator);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
@@ -211,6 +221,10 @@ PyObject* KX_ParentActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_ParentActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_ParentActuator::py_setattro(PyObject *attr, PyObject* value) {
py_setattro_up(SCA_IActuator);
}
@@ -259,7 +273,7 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* args)
Py_RETURN_NONE;
if (ret_name_only)
- return PyString_FromString(m_ob->GetName());
+ return PyString_FromString(m_ob->GetName().ReadPtr());
else
return m_ob->GetProxy();
}
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h
index f9f0b73b876..148375e994c 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.h
+++ b/source/gameengine/Ketsji/KX_ParentActuator.h
@@ -46,6 +46,9 @@ class KX_ParentActuator : public SCA_IActuator
/** Mode */
int m_mode;
+ /** option */
+ bool m_addToCompound;
+ bool m_ghost;
/** Object to set as parent */
SCA_IObject *m_ob;
@@ -57,11 +60,14 @@ class KX_ParentActuator : public SCA_IActuator
KX_PARENT_NODEF = 0,
KX_PARENT_SET,
KX_PARENT_REMOVE,
+ KX_PARENT_MAX
};
KX_ParentActuator(class SCA_IObject* gameobj,
int mode,
+ bool addToCompound,
+ bool ghost,
SCA_IObject *ob,
PyTypeObject* T=&Type);
virtual ~KX_ParentActuator();
@@ -77,6 +83,7 @@ class KX_ParentActuator : public SCA_IActuator
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
/* These are used to get and set m_ob */
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
index fda639c09e0..c968e50957e 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
@@ -113,8 +113,13 @@ PyAttributeDef KX_PhysicsObjectWrapper::Attributes[] = {
//python specific stuff
PyTypeObject KX_PhysicsObjectWrapper::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_PhysicsObjectWrapper",
sizeof(PyObjectPlus_Proxy),
0,
@@ -136,11 +141,14 @@ PyParentObject KX_PhysicsObjectWrapper::Parents[] = {
NULL
};
-PyObject* KX_PhysicsObjectWrapper::py_getattro(PyObject *attr)
+PyObject* KX_PhysicsObjectWrapper::py_getattro(PyObject *attr)
{
py_getattro_up(PyObjectPlus);
}
+PyObject* KX_PhysicsObjectWrapper::py_getattro_dict() {
+ py_getattro_dict_up(PyObjectPlus);
+}
int KX_PhysicsObjectWrapper::py_setattro(PyObject *attr,PyObject *pyobj)
{
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
index 7e10dc3ccf4..1b59686babc 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
@@ -37,6 +37,7 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus
Py_Header;
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
public:
KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp
index 2e5dd72db0e..b56b5500c39 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.cpp
+++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp
@@ -39,8 +39,13 @@
#include "KX_PyMath.h"
PyTypeObject KX_PolyProxy::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_PolyProxy",
sizeof(PyObjectPlus_Proxy),
0,
@@ -59,8 +64,8 @@ PyTypeObject KX_PolyProxy::Type = {
PyParentObject KX_PolyProxy::Parents[] = {
&KX_PolyProxy::Type,
- &SCA_IObject::Type,
&CValue::Type,
+ &PyObjectPlus::Type,
NULL
};
@@ -79,6 +84,7 @@ PyMethodDef KX_PolyProxy::Methods[] = {
PyAttributeDef KX_PolyProxy::Attributes[] = {
/* All dummy's so they come up in a dir() */
+ //KX_PYATTRIBUTE_TODO("DummyProps"),
KX_PYATTRIBUTE_DUMMY("matname"),
KX_PYATTRIBUTE_DUMMY("texture"),
KX_PYATTRIBUTE_DUMMY("material"),
@@ -156,7 +162,11 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr)
{
return PyInt_FromLong(m_polygon->IsCollider());
}
- py_getattro_up(SCA_IObject);
+ py_getattro_up(CValue);
+}
+
+PyObject* KX_PolyProxy::py_getattro_dict() {
+ py_getattro_dict_up(CValue);
}
KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
@@ -176,11 +186,9 @@ CValue* KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { re
STR_String sPolyName="polygone";
const STR_String & KX_PolyProxy::GetText() {return sPolyName;};
double KX_PolyProxy::GetNumber() { return -1;}
-STR_String KX_PolyProxy::GetName() { return sPolyName;}
-void KX_PolyProxy::SetName(STR_String) { };
+STR_String& KX_PolyProxy::GetName() { return sPolyName;}
+void KX_PolyProxy::SetName(const char *) { };
CValue* KX_PolyProxy::GetReplica() { return NULL;}
-void KX_PolyProxy::ReplicaSetName(STR_String) {};
-
// stuff for python integration
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h
index 275e65da810..d8fd36fec6c 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.h
+++ b/source/gameengine/Ketsji/KX_PolyProxy.h
@@ -31,7 +31,7 @@
#include "SCA_IObject.h"
-class KX_PolyProxy : public SCA_IObject
+class KX_PolyProxy : public CValue
{
Py_Header;
protected:
@@ -46,14 +46,14 @@ public:
CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
const STR_String & GetText();
double GetNumber();
- STR_String GetName();
- void SetName(STR_String name); // Set the name of the value
- void ReplicaSetName(STR_String name);
+ STR_String& GetName();
+ void SetName(const char *name); // Set the name of the value
CValue* GetReplica();
// stuff for python integration
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
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 46d04486cc6..506c167a905 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -51,22 +51,37 @@
#include "KX_PyMath.h"
-KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
- Material *material,
- int tile,
- int tilexrep,
- int tileyrep,
- int mode,
- int transp,
- bool alpha,
- bool zsort,
- int lightlayer,
- struct MTFace* tface,
- unsigned int* mcol,
- PyTypeObject *T)
+KX_PolygonMaterial::KX_PolygonMaterial(PyTypeObject *T)
: PyObjectPlus(T),
- RAS_IPolyMaterial(texname,
- STR_String(material?material->id.name:""),
+ RAS_IPolyMaterial(),
+
+ m_tface(NULL),
+ m_mcol(NULL),
+ m_material(NULL),
+ m_pymaterial(NULL),
+ m_pass(0)
+{
+}
+
+void KX_PolygonMaterial::Initialize(
+ const STR_String &texname,
+ Material* ma,
+ int materialindex,
+ int tile,
+ int tilexrep,
+ int tileyrep,
+ int mode,
+ int transp,
+ bool alpha,
+ bool zsort,
+ int lightlayer,
+ struct MTFace* tface,
+ unsigned int* mcol)
+{
+ RAS_IPolyMaterial::Initialize(
+ texname,
+ ma?ma->id.name:"",
+ materialindex,
tile,
tilexrep,
tileyrep,
@@ -74,13 +89,12 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
transp,
alpha,
zsort,
- lightlayer),
- m_tface(tface),
- m_mcol(mcol),
- m_material(material),
- m_pymaterial(0),
- m_pass(0)
-{
+ lightlayer);
+ m_tface = tface;
+ m_mcol = mcol;
+ m_material = ma;
+ m_pymaterial = 0;
+ m_pass = 0;
}
KX_PolygonMaterial::~KX_PolygonMaterial()
@@ -158,15 +172,32 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c
rasty->SetLines(true);
else
rasty->SetLines(false);
+ rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
+ rasty->SetShinyness(m_shininess);
+ rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
+ if (m_material)
+ rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
}
- rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
- rasty->SetShinyness(m_shininess);
- rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
- if (m_material)
- rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
+ //rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
+ //rasty->SetShinyness(m_shininess);
+ //rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
+ //if (m_material)
+ // rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
+}
+
+void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
+{
+ if (m_material) {
+ *rgba++ = (unsigned char) (m_material->r*255.0);
+ *rgba++ = (unsigned char) (m_material->g*255.0);
+ *rgba++ = (unsigned char) (m_material->b*255.0);
+ *rgba++ = (unsigned char) (m_material->alpha*255.0);
+ } else
+ RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
}
+
//----------------------------------------------------------------------------
//Python
@@ -189,7 +220,7 @@ PyAttributeDef KX_PolygonMaterial::Attributes[] = {
KX_PYATTRIBUTE_INT_RW("tilexrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tilexrep),
KX_PYATTRIBUTE_INT_RW("tileyrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tileyrep),
KX_PYATTRIBUTE_INT_RW("drawingmode", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_drawingmode),
- KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer),
+ //KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer),
KX_PYATTRIBUTE_BOOL_RW("transparent", KX_PolygonMaterial, m_alpha),
KX_PYATTRIBUTE_BOOL_RW("zsort", KX_PolygonMaterial, m_zsort),
@@ -208,8 +239,13 @@ PyAttributeDef KX_PolygonMaterial::Attributes[] = {
};
PyTypeObject KX_PolygonMaterial::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_PolygonMaterial",
sizeof(PyObjectPlus_Proxy),
0,
@@ -237,6 +273,10 @@ PyObject* KX_PolygonMaterial::py_getattro(PyObject *attr)
py_getattro_up(PyObjectPlus);
}
+PyObject* KX_PolygonMaterial::py_getattro_dict() {
+ py_getattro_dict_up(PyObjectPlus);
+}
+
int KX_PolygonMaterial::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(PyObjectPlus);
@@ -346,10 +386,10 @@ int KX_PolygonMaterial::pyattr_set_diffuse(void *self_v, const KX_PYATTRIBUTE_DE
MT_Vector3 vec;
if (!PyVecTo(value, vec))
- return -1;
+ return PY_SET_ATTR_FAIL;
self->m_diffuse= vec;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_PolygonMaterial::pyattr_get_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -364,8 +404,8 @@ int KX_PolygonMaterial::pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_D
MT_Vector3 vec;
if (!PyVecTo(value, vec))
- return -1;
+ return PY_SET_ATTR_FAIL;
self->m_specular= vec;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index 9865a66e836..89ecb026da9 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -53,14 +53,14 @@ private:
MTFace* m_tface;
unsigned int* m_mcol;
Material* m_material;
-
PyObject* m_pymaterial;
mutable int m_pass;
public:
-
- KX_PolygonMaterial(const STR_String &texname,
+ KX_PolygonMaterial(PyTypeObject *T = &Type);
+ void Initialize(const STR_String &texname,
Material* ma,
+ int materialindex,
int tile,
int tilexrep,
int tileyrep,
@@ -70,8 +70,8 @@ public:
bool zsort,
int lightlayer,
struct MTFace* tface,
- unsigned int* mcol,
- PyTypeObject *T = &Type);
+ unsigned int* mcol);
+
virtual ~KX_PolygonMaterial();
/**
@@ -107,8 +107,8 @@ public:
{
return m_mcol;
}
-
-
+ virtual void GetMaterialRGBAColor(unsigned char *rgba) const;
+
KX_PYMETHOD_DOC(KX_PolygonMaterial, updateTexture);
KX_PYMETHOD_DOC(KX_PolygonMaterial, setTexture);
KX_PYMETHOD_DOC(KX_PolygonMaterial, activate);
@@ -117,6 +117,7 @@ public:
KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram);
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
virtual PyObject* py_repr(void) { return PyString_FromString(m_material ? ((ID *)m_material)->name+2 : ""); }
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 2c65c184a9c..a098d99864f 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -33,6 +33,7 @@
#include "KX_PhysicsObjectWrapper.h"
#include "PHY_IPhysicsController.h"
#include "PHY_IVehicle.h"
+#include "MT_Matrix3x3.h"
#include "PyObjectPlus.h"
@@ -404,6 +405,8 @@ static PyObject* gPyCreateConstraint(PyObject* self,
int physicsid=0,physicsid2 = 0,constrainttype=0,extrainfo=0;
int len = PyTuple_Size(args);
int success = 1;
+ int flag = 0;
+
float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1;
if (len == 3)
{
@@ -420,6 +423,11 @@ static PyObject* gPyCreateConstraint(PyObject* self,
success = PyArg_ParseTuple(args,"iiiffffff",&physicsid,&physicsid2,&constrainttype,
&pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
}
+ else if (len == 10)
+ {
+ success = PyArg_ParseTuple(args,"iiiffffffi",&physicsid,&physicsid2,&constrainttype,
+ &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
+ }
else if (len==4)
{
success = PyArg_ParseTuple(args,"iiii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
@@ -435,7 +443,31 @@ static PyObject* gPyCreateConstraint(PyObject* self,
PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2;
if (physctrl) //TODO:check for existance of this pointer!
{
- int constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0);
+ PHY_ConstraintType ct = (PHY_ConstraintType) constrainttype;
+ int constraintid =0;
+
+ if (ct == PHY_GENERIC_6DOF_CONSTRAINT)
+ {
+ //convert from euler angle into axis
+ float radsPerDeg = 6.283185307179586232f / 360.f;
+
+ //we need to pass a full constraint frame, not just axis
+ //localConstraintFrameBasis
+ MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*axisX,radsPerDeg*axisY,radsPerDeg*axisZ));
+ MT_Vector3 axis0 = localCFrame.getColumn(0);
+ MT_Vector3 axis1 = localCFrame.getColumn(1);
+ MT_Vector3 axis2 = localCFrame.getColumn(2);
+
+ constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
+ pivotX,pivotY,pivotZ,
+ (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
+ (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
+ (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag);
+
+ } else
+ {
+ constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0);
+ }
KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment());
@@ -565,6 +597,19 @@ static struct PyMethodDef physicsconstraints_methods[] = {
};
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef PhysicsConstraints_module_def = {
+ {}, /* m_base */
+ "PhysicsConstraints", /* m_name */
+ PhysicsConstraints_module_documentation, /* m_doc */
+ 0, /* m_size */
+ physicsconstraints_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
PyObject* initPythonConstraintBinding()
{
@@ -573,10 +618,24 @@ PyObject* initPythonConstraintBinding()
PyObject* m;
PyObject* d;
-
- m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods,
+ /* Use existing module where possible
+ * be careful not to init any runtime vars after this */
+ m = PyImport_ImportModule( "PhysicsConstraints" );
+ if(m) {
+ Py_DECREF(m);
+ return m;
+ }
+ else {
+ PyErr_Clear();
+
+#if (PY_VERSION_HEX >= 0x03000000)
+ m = PyModule_Create(&PhysicsConstraints_module_def);
+#else
+ m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods,
PhysicsConstraints_module_documentation,
(PyObject*)NULL,PYTHON_API_VERSION);
+#endif
+ }
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp
index 0093a72808e..051d7ae7dba 100644
--- a/source/gameengine/Ketsji/KX_PyMath.cpp
+++ b/source/gameengine/Ketsji/KX_PyMath.cpp
@@ -75,9 +75,8 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
return false;
}
-bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix)
+bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefix)
{
- MT_Matrix3x3 rot;
int size= PySequence_Size(pyval);
if (size == 4)
diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h
index 00f7c5cad93..a7ce4bc6930 100644
--- a/source/gameengine/Ketsji/KX_PyMath.h
+++ b/source/gameengine/Ketsji/KX_PyMath.h
@@ -40,6 +40,7 @@
#include "MT_Matrix4x4.h"
#include "KX_Python.h"
+#include "PyObjectPlus.h"
inline unsigned int Size(const MT_Matrix4x4&) { return 4; }
inline unsigned int Size(const MT_Matrix3x3&) { return 3; }
@@ -116,6 +117,19 @@ bool PyVecTo(PyObject* pyval, T& vec)
return true;
}
+ else if (BGE_PROXY_CHECK_TYPE(pyval))
+ { /* note, include this check because PySequence_Check does too much introspection
+ * on the PyObject (like getting its __class__, on a BGE type this means searching up
+ * the parent list each time only to discover its not a sequence.
+ * GameObjects are often used as an alternative to vectors so this is a common case
+ * better to do a quick check for it, likely the error below will be ignored.
+ *
+ * This is not 'correct' since we have proxy type CListValues's which could
+ * contain floats/ints but there no cases of CValueLists being this way
+ */
+ PyErr_Format(PyExc_AttributeError, "expected a sequence type");
+ return false;
+ }
else if (PySequence_Check(pyval))
{
unsigned int numitems = PySequence_Size(pyval);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index ffcf7d7162e..fc3e48f504c 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -49,6 +49,9 @@
#include "KX_KetsjiEngine.h"
#include "KX_RadarSensor.h"
#include "KX_RaySensor.h"
+#include "KX_SceneActuator.h"
+#include "KX_GameActuator.h"
+#include "KX_ParentActuator.h"
#include "KX_SCA_DynamicActuator.h"
#include "SCA_IInputDevice.h"
@@ -83,10 +86,16 @@
#include "KX_PythonInitTypes.h"
+/* we only need this to get a list of libraries from the main struct */
+#include "DNA_ID.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! */
+#if PY_VERSION_HEX < 0x03000000
+ #include "Mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use.
+ #include "Geometry.h" // Blender.Geometry module copied here so the blenderlayer can use.
#include "BGL.h"
+#endif
}
#endif
@@ -100,13 +109,13 @@ extern "C" {
//#include "BPY_extern.h"
#endif
+#include "BKE_main.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BLI_blenlib.h"
#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;
@@ -114,6 +123,9 @@ static KX_Scene* gp_KetsjiScene = NULL;
static KX_KetsjiEngine* gp_KetsjiEngine = NULL;
static RAS_IRasterizer* gp_Rasterizer = NULL;
static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = "";
+static char gp_GamePythonPathOrig[FILE_MAXDIR + FILE_MAXFILE] = ""; // not super happy about this, but we need to remember the first loaded file for the global/dict load save
+static PyObject *gp_OrigPythonSysPath= NULL;
+static PyObject *gp_OrigPythonSysModules= NULL;
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
{
@@ -220,13 +232,13 @@ static PyObject* gPyGetSpectrum(PyObject*)
for (int index = 0; index < 512; index++)
{
- PyList_SetItem(resultlist, index, PyFloat_FromDouble(spectrum[index]));
+ PyList_SET_ITEM(resultlist, index, PyFloat_FromDouble(spectrum[index]));
}
}
else {
for (int index = 0; index < 512; index++)
{
- PyList_SetItem(resultlist, index, PyFloat_FromDouble(0.0));
+ PyList_SET_ITEM(resultlist, index, PyFloat_FromDouble(0.0));
}
}
@@ -286,6 +298,36 @@ static PyObject* gPyGetLogicTicRate(PyObject*)
return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate());
}
+static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args)
+{
+ int frame;
+ if (!PyArg_ParseTuple(args, "i:setMaxLogicFrame", &frame))
+ return NULL;
+
+ KX_KetsjiEngine::SetMaxLogicFrame(frame);
+ Py_RETURN_NONE;
+}
+
+static PyObject* gPyGetMaxLogicFrame(PyObject*)
+{
+ return PyInt_FromLong(KX_KetsjiEngine::GetMaxLogicFrame());
+}
+
+static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args)
+{
+ int frame;
+ if (!PyArg_ParseTuple(args, "i:setMaxPhysicsFrame", &frame))
+ return NULL;
+
+ KX_KetsjiEngine::SetMaxPhysicsFrame(frame);
+ Py_RETURN_NONE;
+}
+
+static PyObject* gPyGetMaxPhysicsFrame(PyObject*)
+{
+ return PyInt_FromLong(KX_KetsjiEngine::GetMaxPhysicsFrame());
+}
+
static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args)
{
float ticrate;
@@ -477,6 +519,10 @@ static struct PyMethodDef game_methods[] = {
{"setGravity",(PyCFunction) gPySetGravity, METH_O, (PY_METHODCHAR)"set Gravitation"},
{"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS, (PY_METHODCHAR)"get audio spectrum"},
{"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (PY_METHODCHAR)"stop using the audio dsp (for performance reasons)"},
+ {"getMaxLogicFrame", (PyCFunction) gPyGetMaxLogicFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of logic frame per render frame"},
+ {"setMaxLogicFrame", (PyCFunction) gPySetMaxLogicFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of logic frame per render frame"},
+ {"getMaxPhysicsFrame", (PyCFunction) gPyGetMaxPhysicsFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of physics frame per render frame"},
+ {"setMaxPhysicsFrame", (PyCFunction) gPySetMaxPhysicsFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of physics farme per render frame"},
{"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the logic tic rate"},
{"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (PY_METHODCHAR)"Sets the logic tic rate"},
{"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the physics tic rate"},
@@ -487,7 +533,6 @@ static struct PyMethodDef game_methods[] = {
{NULL, (PyCFunction) NULL, 0, NULL }
};
-
static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args)
{
return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetHeight() : 0));
@@ -636,6 +681,17 @@ static PyObject* gPySetMistColor(PyObject*, PyObject* value)
Py_RETURN_NONE;
}
+static PyObject* gPyDisableMist(PyObject*)
+{
+
+ if (!gp_Rasterizer) {
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
+ return NULL;
+ }
+ gp_Rasterizer->DisableFog();
+
+ Py_RETURN_NONE;
+}
static PyObject* gPySetMistStart(PyObject*, PyObject* args)
@@ -724,7 +780,7 @@ static PyObject* gPyEnableMotionBlur(PyObject*, PyObject* args)
Py_RETURN_NONE;
}
-static PyObject* gPyDisableMotionBlur(PyObject*, PyObject* args)
+static PyObject* gPyDisableMotionBlur(PyObject*)
{
if (!gp_Rasterizer) {
PyErr_SetString(PyExc_RuntimeError, "Rasterizer.disableMotionBlur(), Rasterizer not available");
@@ -780,16 +836,17 @@ static PyObject* gPySetGLSLMaterialSetting(PyObject*,
/* display lists and GLSL materials need to be remade */
if(G.fileflags != fileflags) {
+ GPU_materials_free();
if(gp_KetsjiEngine) {
KX_SceneList *scenes = gp_KetsjiEngine->CurrentScenes();
KX_SceneList::iterator it;
for(it=scenes->begin(); it!=scenes->end(); it++)
- if((*it)->GetBucketManager())
+ if((*it)->GetBucketManager()) {
(*it)->GetBucketManager()->ReleaseDisplayLists();
+ (*it)->GetBucketManager()->ReleaseMaterials();
+ }
}
-
- GPU_materials_free();
}
Py_RETURN_NONE;
@@ -850,7 +907,7 @@ static PyObject* gPyGetMaterialType(PyObject*)
{
int flag;
- if(G.fileflags & (G_FILE_GAME_MAT|G_FILE_GAME_MAT_GLSL))
+ if(G.fileflags & G_FILE_GAME_MAT_GLSL)
flag = KX_BLENDER_GLSL_MATERIAL;
else if(G.fileflags & G_FILE_GAME_MAT)
flag = KX_BLENDER_MULTITEX_MATERIAL;
@@ -904,11 +961,12 @@ static struct PyMethodDef rasterizer_methods[] = {
METH_VARARGS, "setMousePosition(int x,int y)"},
{"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"},
{"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"},
+ {"disableMist",(PyCFunction)gPyDisableMist,METH_NOARGS,"turn off mist"},
{"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"},
{"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
{"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
{"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"},
- {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_VARARGS,"disable motion blur"},
+ {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_NOARGS,"disable motion blur"},
{"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"},
@@ -938,7 +996,19 @@ static char Rasterizer_module_documentation[] =
"This is the Python API for the game engine of Rasterizer"
;
-
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef GameLogic_module_def = {
+ {}, /* m_base */
+ "GameLogic", /* m_name */
+ GameLogic_module_documentation, /* m_doc */
+ 0, /* m_size */
+ game_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack to get gravity hook
{
@@ -950,12 +1020,29 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
gp_KetsjiScene = scene;
gUseVisibilityTemp=false;
-
- // Create the module and add the functions
- m = Py_InitModule4("GameLogic", game_methods,
- GameLogic_module_documentation,
- (PyObject*)NULL,PYTHON_API_VERSION);
-
+
+ PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */
+
+ /* Use existing module where possible
+ * be careful not to init any runtime vars after this */
+ m = PyImport_ImportModule( "GameLogic" );
+ if(m) {
+ Py_DECREF(m);
+ return m;
+ }
+ else {
+ PyErr_Clear();
+
+ // Create the module and add the functions
+#if (PY_VERSION_HEX >= 0x03000000)
+ m = PyModule_Create(&GameLogic_module_def);
+#else
+ m = Py_InitModule4("GameLogic", game_methods,
+ GameLogic_module_documentation,
+ (PyObject*)NULL,PYTHON_API_VERSION);
+#endif
+ }
+
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -1172,6 +1259,28 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_LOCAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCAL);
KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_DOROTFH, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DOROTFH);
+ /* Game Actuator Modes */
+ KX_MACRO_addTypesToDict(d, KX_GAME_LOAD, KX_GameActuator::KX_GAME_LOAD);
+ KX_MACRO_addTypesToDict(d, KX_GAME_START, KX_GameActuator::KX_GAME_START);
+ KX_MACRO_addTypesToDict(d, KX_GAME_RESTART, KX_GameActuator::KX_GAME_RESTART);
+ KX_MACRO_addTypesToDict(d, KX_GAME_QUIT, KX_GameActuator::KX_GAME_QUIT);
+ KX_MACRO_addTypesToDict(d, KX_GAME_SAVECFG, KX_GameActuator::KX_GAME_SAVECFG);
+ KX_MACRO_addTypesToDict(d, KX_GAME_LOADCFG, KX_GameActuator::KX_GAME_LOADCFG);
+
+ /* Scene Actuator Modes */
+ KX_MACRO_addTypesToDict(d, KX_SCENE_RESTART, KX_SceneActuator::KX_SCENE_RESTART);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_SET_SCENE, KX_SceneActuator::KX_SCENE_SET_SCENE);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_SET_CAMERA, KX_SceneActuator::KX_SCENE_SET_CAMERA);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_ADD_FRONT_SCENE, KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_ADD_BACK_SCENE, KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_REMOVE_SCENE, KX_SceneActuator::KX_SCENE_REMOVE_SCENE);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_SUSPEND, KX_SceneActuator::KX_SCENE_SUSPEND);
+ KX_MACRO_addTypesToDict(d, KX_SCENE_RESUME, KX_SceneActuator::KX_SCENE_RESUME);
+
+ /* Parent Actuator Modes */
+ KX_MACRO_addTypesToDict(d, KX_PARENT_SET, KX_ParentActuator::KX_PARENT_SET);
+ KX_MACRO_addTypesToDict(d, KX_PARENT_REMOVE, KX_ParentActuator::KX_PARENT_REMOVE);
+
// Check for errors
if (PyErr_Occurred())
{
@@ -1238,7 +1347,7 @@ PyObject *KXpy_import(PyObject *self, PyObject *args)
/* quick hack for GamePython modules
TODO: register builtin modules properly by ExtendInittab */
if (!strcmp(name, "GameLogic") || !strcmp(name, "GameKeys") || !strcmp(name, "PhysicsConstraints") ||
- !strcmp(name, "Rasterizer") || !strcmp(name, "Mathutils") || !strcmp(name, "BGL")) {
+ !strcmp(name, "Rasterizer") || !strcmp(name, "Mathutils") || !strcmp(name, "BGL") || !strcmp(name, "Geometry")) {
return PyImport_ImportModuleEx(name, globals, locals, fromlist);
}
@@ -1359,20 +1468,141 @@ void setSandbox(TPythonSecurityLevel level)
}
}
+/* Explanation of
+ *
+ * - backupPySysObjects() : stores sys.path in gp_OrigPythonSysPath
+ * - initPySysObjects(main) : initializes the blendfile and library paths
+ * - restorePySysObjects() : restores sys.path from gp_OrigPythonSysPath
+ *
+ * These exist so the current blend dir "//" can always be used to import modules from.
+ * the reason we need a few functions for this is that python is not only used by the game engine
+ * so we cant just add to sys.path all the time, it would leave pythons state in a mess.
+ * It would also be incorrect since loading blend files for new levels etc would alwasy add to sys.path
+ *
+ * To play nice with blenders python, the sys.path is backed up and the current blendfile along
+ * with all its lib paths are added to the sys path.
+ * When loading a new blendfile, the original sys.path is restored and the new paths are added over the top.
+ */
+
+/**
+ * So we can have external modules mixed with our blend files.
+ */
+static void backupPySysObjects(void)
+{
+ PyObject *sys_path= PySys_GetObject("path"); /* should never fail */
+ PyObject *sys_mods= PySys_GetObject("modules"); /* should never fail */
+
+ /* paths */
+ Py_XDECREF(gp_OrigPythonSysPath); /* just incase its set */
+ gp_OrigPythonSysPath = PyList_GetSlice(sys_path, 0, INT_MAX); /* copy the list */
+
+ /* modules */
+ Py_XDECREF(gp_OrigPythonSysModules); /* just incase its set */
+ gp_OrigPythonSysModules = PyDict_Copy(sys_mods); /* copy the list */
+
+}
+
+/* for initPySysObjects only,
+ * takes a blend path and adds a scripts dir from it
+ *
+ * "/home/me/foo.blend" -> "/home/me/scripts"
+ */
+static void initPySysObjects__append(PyObject *sys_path, char *filename)
+{
+ PyObject *item;
+ char expanded[FILE_MAXDIR + FILE_MAXFILE];
+
+ BLI_split_dirfile_basic(filename, expanded, NULL); /* get the dir part of filename only */
+ BLI_convertstringcode(expanded, gp_GamePythonPath); /* filename from lib->filename is (always?) absolute, so this may not be needed but it wont hurt */
+ BLI_cleanup_file(gp_GamePythonPath, expanded); /* Dont use BLI_cleanup_dir because it adds a slash - BREAKS WIN32 ONLY */
+ item= PyString_FromString(expanded);
+
+// printf("SysPath - '%s', '%s', '%s'\n", expanded, filename, gp_GamePythonPath);
+
+ if(PySequence_Index(sys_path, item) == -1) {
+ PyErr_Clear(); /* PySequence_Index sets a ValueError */
+ PyList_Insert(sys_path, 0, item);
+ }
+
+ Py_DECREF(item);
+}
+static void initPySysObjects(Main *maggie)
+{
+ PyObject *sys_path= PySys_GetObject("path"); /* should never fail */
+
+ if (gp_OrigPythonSysPath==NULL) {
+ /* backup */
+ backupPySysObjects();
+ }
+ else {
+ /* get the original sys path when the BGE started */
+ PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath);
+ }
+
+ Library *lib= (Library *)maggie->library.first;
+
+ while(lib) {
+ /* lib->name wont work in some cases (on win32),
+ * even when expanding with gp_GamePythonPath, using lib->filename is less trouble */
+ initPySysObjects__append(sys_path, lib->filename);
+ lib= (Library *)lib->id.next;
+ }
+
+ initPySysObjects__append(sys_path, gp_GamePythonPath);
+
+// fprintf(stderr, "\nNew Path: %d ", PyList_Size(sys_path));
+// PyObject_Print(sys_path, stderr, 0);
+}
+
+static void restorePySysObjects(void)
+{
+ if (gp_OrigPythonSysPath==NULL)
+ return;
+
+ PyObject *sys_path= PySys_GetObject("path"); /* should never fail */
+ PyObject *sys_mods= PySys_GetObject("modules"); /* should never fail */
+
+ /* paths */
+ PyList_SetSlice(sys_path, 0, INT_MAX, gp_OrigPythonSysPath);
+ Py_DECREF(gp_OrigPythonSysPath);
+ gp_OrigPythonSysPath= NULL;
+
+ /* modules */
+ PyDict_Clear(sys_mods);
+ PyDict_Update(sys_mods, gp_OrigPythonSysModules);
+ Py_DECREF(gp_OrigPythonSysModules);
+ gp_OrigPythonSysModules= NULL;
+
+
+// fprintf(stderr, "\nRestore Path: %d ", PyList_Size(sys_path));
+// PyObject_Print(sys_path, stderr, 0);
+}
+
/**
* Python is not initialised.
*/
PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv)
{
+ /* Yet another gotcha in the py api
+ * Cant run PySys_SetArgv more then once because this adds the
+ * binary dir to the sys.path each time.
+ * Id have thaught python being totally restarted would make this ok but
+ * somehow it remembers the sys.path - Campbell
+ */
+ static bool first_time = true;
+
+#if (PY_VERSION_HEX < 0x03000000)
STR_String pname = progname;
Py_SetProgramName(pname.Ptr());
+#endif
Py_NoSiteFlag=1;
Py_FrozenFlag=1;
Py_Initialize();
- if(argv) /* browser plugins dont currently set this */
+#if (PY_VERSION_HEX < 0x03000000)
+ if(argv && first_time) /* browser plugins dont currently set this */
PySys_SetArgv(argc, argv);
-
+#endif
//importBlenderModules()
setSandbox(level);
@@ -1380,24 +1610,37 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
/* XXX 2.5 bpy_import_main_set(maggie); */
+ initPySysObjects(maggie);
+
+ first_time = false;
+
+ PyObjectPlus::ClearDeprecationWarning();
+
PyObject* moduleobj = PyImport_AddModule("__main__");
return PyModule_GetDict(moduleobj);
}
void exitGamePlayerPythonScripting()
-{
- //clearGameModules(); // were closing python anyway
+{
+ /* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */
+ restorePySysObjects(); /* get back the original sys.path and clear the backup */
+
Py_Finalize();
/* XXX 2.5 bpy_import_main_set(NULL); */
+ PyObjectPlus::ClearDeprecationWarning();
}
+
+
/**
* Python is already initialized.
*/
PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie)
{
+#if (PY_VERSION_HEX < 0x03000000)
STR_String pname = progname;
Py_SetProgramName(pname.Ptr());
+#endif
Py_NoSiteFlag=1;
Py_FrozenFlag=1;
@@ -1406,53 +1649,35 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev
/* 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();
+ initPySysObjects(maggie);
+ PyObjectPlus::NullDeprecationWarning();
+
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();
+ restorePySysObjects(); /* get back the original sys.path and clear the backup */
/* XXX 2.5 bpy_import_main_set(NULL); */
+ PyObjectPlus::ClearDeprecationWarning();
}
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef Rasterizer_module_def = {
+ {}, /* m_base */
+ "Rasterizer", /* m_name */
+ Rasterizer_module_documentation, /* m_doc */
+ 0, /* m_size */
+ rasterizer_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
{
@@ -1464,10 +1689,25 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
PyObject* d;
PyObject* item;
- // Create the module and add the functions
- m = Py_InitModule4("Rasterizer", rasterizer_methods,
+ /* Use existing module where possible
+ * be careful not to init any runtime vars after this */
+ m = PyImport_ImportModule( "Rasterizer" );
+ if(m) {
+ Py_DECREF(m);
+ return m;
+ }
+ else {
+ PyErr_Clear();
+
+ // Create the module and add the functions
+#if (PY_VERSION_HEX >= 0x03000000)
+ m = PyModule_Create(&Rasterizer_module_def);
+#else
+ m = Py_InitModule4("Rasterizer", rasterizer_methods,
Rasterizer_module_documentation,
(PyObject*)NULL,PYTHON_API_VERSION);
+#endif
+ }
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -1517,7 +1757,12 @@ static PyObject* gPyEventToString(PyObject*, PyObject* value)
dict = PyModule_GetDict(mod);
while (PyDict_Next(dict, &pos, &key, &val)) {
+#if (PY_VERSION_HEX >= 0x03000000)
+ if (PyObject_RichCompareBool(value, val, Py_EQ)) {
+#else
if (PyObject_Compare(value, val)==0) {
+#endif
+
ret = key;
break;
}
@@ -1559,17 +1804,44 @@ static struct PyMethodDef gamekeys_methods[] = {
};
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef GameKeys_module_def = {
+ {}, /* m_base */
+ "GameKeys", /* m_name */
+ GameKeys_module_documentation, /* m_doc */
+ 0, /* m_size */
+ gamekeys_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
PyObject* initGameKeys()
{
PyObject* m;
PyObject* d;
PyObject* item;
-
- // Create the module and add the functions
- m = Py_InitModule4("GameKeys", gamekeys_methods,
+
+ /* Use existing module where possible */
+ m = PyImport_ImportModule( "GameKeys" );
+ if(m) {
+ Py_DECREF(m);
+ return m;
+ }
+ else {
+ PyErr_Clear();
+
+ // Create the module and add the functions
+#if (PY_VERSION_HEX >= 0x03000000)
+ m = PyModule_Create(&GameKeys_module_def);
+#else
+ m = Py_InitModule4("GameKeys", gamekeys_methods,
GameKeys_module_documentation,
(PyObject*)NULL,PYTHON_API_VERSION);
+#endif
+ }
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -1698,15 +1970,26 @@ PyObject* initGameKeys()
return d;
}
+#if PY_VERSION_HEX < 0x03000000
PyObject* initMathutils()
{
return NULL; //XXX Mathutils_Init("Mathutils"); // Use as a top level module in BGE
}
+PyObject* initGeometry()
+{
+ return NULL; // XXX Geometry_Init("Geometry"); // 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
}
+#else // TODO Py3k conversion
+PyObject* initMathutils() {Py_INCREF(Py_None);return Py_None;}
+PyObject* initGeometry() {Py_INCREF(Py_None);return Py_None;}
+PyObject* initBGL() {Py_INCREF(Py_None);return Py_None;}
+#endif
void KX_SetActiveScene(class KX_Scene* scene)
{
@@ -1794,9 +2077,9 @@ int loadGamePythonConfig(char *marshal_buffer, int marshal_length)
void pathGamePythonConfig( char *path )
{
- int len = strlen(gp_GamePythonPath);
+ int len = strlen(gp_GamePythonPathOrig); // Always use the first loaded blend filename
- BLI_strncpy(path, gp_GamePythonPath, sizeof(gp_GamePythonPath));
+ BLI_strncpy(path, gp_GamePythonPathOrig, sizeof(gp_GamePythonPathOrig));
/* replace extension */
if (BLI_testextensie(path, ".blend")) {
@@ -1809,5 +2092,16 @@ void pathGamePythonConfig( char *path )
void setGamePythonPath(char *path)
{
BLI_strncpy(gp_GamePythonPath, path, sizeof(gp_GamePythonPath));
+ BLI_cleanup_file(NULL, gp_GamePythonPath); /* not absolutely needed but makes resolving path problems less confusing later */
+
+ if (gp_GamePythonPathOrig[0] == '\0')
+ BLI_strncpy(gp_GamePythonPathOrig, path, sizeof(gp_GamePythonPathOrig));
}
+// we need this so while blender is open (not blenderplayer)
+// loading new blendfiles will reset this on starting the
+// engine but loading blend files within the BGE wont overwrite gp_GamePythonPathOrig
+void resetGamePythonPath()
+{
+ gp_GamePythonPathOrig[0] == '\0';
+}
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index 11360197b95..8f102d13a18 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -45,6 +45,7 @@ PyObject* initGameKeys();
PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas);
PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, struct Main *maggie, int argc, char** argv);
PyObject* initMathutils();
+PyObject* initGeometry();
PyObject* initBGL();
PyObject* initVideoTexture(void);
void exitGamePlayerPythonScripting();
@@ -52,6 +53,7 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev
void exitGamePythonScripting();
void setGamePythonPath(char *path);
+void resetGamePythonPath();
void pathGamePythonConfig( char *path );
int saveGamePythonConfig( char **marshal_buffer);
int loadGamePythonConfig(char *marshal_buffer, int marshal_length);
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index dcd11b551a1..83c4dcbb34c 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -51,6 +51,7 @@
#include "KX_PhysicsObjectWrapper.h"
#include "KX_PolyProxy.h"
#include "KX_PolygonMaterial.h"
+#include "KX_PythonSeq.h"
#include "KX_SCA_AddObjectActuator.h"
#include "KX_SCA_EndObjectActuator.h"
#include "KX_SCA_ReplaceMeshActuator.h"
@@ -84,6 +85,7 @@
#include "SCA_PropertySensor.h"
#include "SCA_PythonController.h"
#include "SCA_RandomActuator.h"
+#include "SCA_IController.h"
void initPyObjectPlusType(PyTypeObject **parents)
@@ -225,9 +227,10 @@ void initPyTypes(void)
PyType_Ready_Attr(dict, SCA_RandomSensor);
PyType_Ready_Attr(dict, SCA_XNORController);
PyType_Ready_Attr(dict, SCA_XORController);
+ PyType_Ready_Attr(dict, SCA_IController);
-
-
+ /* Normal python type */
+ PyType_Ready(&KX_PythonSeq_Type);
}
#endif \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp
new file mode 100644
index 00000000000..cc8021fc2e4
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp
@@ -0,0 +1,382 @@
+/**
+ * $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: none of this file.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * Readonly sequence wrapper for lookups on logic bricks
+ */
+
+
+#include "KX_PythonSeq.h"
+#include "KX_GameObject.h"
+#include "SCA_ISensor.h"
+#include "SCA_IController.h"
+#include "SCA_IActuator.h"
+
+
+PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type )
+{
+ KX_PythonSeq *seq = PyObject_NEW( KX_PythonSeq, &KX_PythonSeq_Type);
+ seq->base = base;
+ Py_INCREF(base); /* so we can always access to check if its valid */
+ seq->type = type;
+ seq->iter = -1; /* init */
+ return (PyObject *)seq;
+ }
+
+ static void KX_PythonSeq_dealloc( KX_PythonSeq * self )
+{
+ Py_DECREF(self->base);
+ PyObject_DEL( self );
+}
+
+static Py_ssize_t KX_PythonSeq_len( PyObject * self )
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base);
+
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ return -1;
+ }
+
+ switch(((KX_PythonSeq *)self)->type) {
+ case KX_PYGENSEQ_CONT_TYPE_SENSORS:
+ return ((SCA_IController *)self_plus)->GetLinkedSensors().size();
+ case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
+ return ((SCA_IController *)self_plus)->GetLinkedActuators().size();
+ case KX_PYGENSEQ_OB_TYPE_SENSORS:
+ return ((KX_GameObject *)self_plus)->GetSensors().size();
+ case KX_PYGENSEQ_OB_TYPE_CONTROLLERS:
+ return ((KX_GameObject *)self_plus)->GetControllers().size();
+ case KX_PYGENSEQ_OB_TYPE_ACTUATORS:
+ return ((KX_GameObject *)self_plus)->GetActuators().size();
+ default:
+ /* Should never happen */
+ PyErr_SetString(PyExc_SystemError, "invalid type, internal error");
+ return -1;
+ }
+}
+
+static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index)
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base);
+
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
+ switch(((KX_PythonSeq *)self)->type) {
+ case KX_PYGENSEQ_CONT_TYPE_SENSORS:
+ {
+ vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
+ if(index<0) index += linkedsensors.size();
+ if(index<0 || index>= linkedsensors.size()) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return linkedsensors[index]->GetProxy();
+ }
+ case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
+ {
+ vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
+ if(index<0) index += linkedactuators.size();
+ if(index<0 || index>= linkedactuators.size()) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return linkedactuators[index]->GetProxy();
+ }
+ case KX_PYGENSEQ_OB_TYPE_SENSORS:
+ {
+ SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors();
+ if(index<0) index += linkedsensors.size();
+ if(index<0 || index>= linkedsensors.size()) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return linkedsensors[index]->GetProxy();
+ }
+ case KX_PYGENSEQ_OB_TYPE_CONTROLLERS:
+ {
+ SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers();
+ if(index<0) index += linkedcontrollers.size();
+ if(index<0 || index>= linkedcontrollers.size()) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return linkedcontrollers[index]->GetProxy();
+ }
+ case KX_PYGENSEQ_OB_TYPE_ACTUATORS:
+ {
+ SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators();
+ if(index<0) index += linkedactuators.size();
+ if(index<0 || index>= linkedactuators.size()) {
+ PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
+ return NULL;
+ }
+ return linkedactuators[index]->GetProxy();
+ }
+ }
+
+ PyErr_SetString(PyExc_SystemError, "invalid sequence type, this is a bug");
+ return NULL;
+}
+
+
+static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key)
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base);
+ char *name = NULL;
+
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
+ if (PyInt_Check(key)) {
+ return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key ));
+ } else if ( PyString_Check(key) ) {
+ name = PyString_AsString( key );
+ } else {
+ PyErr_SetString( PyExc_TypeError, "expected a string or an index" );
+ return NULL;
+ }
+
+ switch(((KX_PythonSeq *)self)->type) {
+ case KX_PYGENSEQ_CONT_TYPE_SENSORS:
+ {
+ vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
+ SCA_ISensor* sensor;
+ for (unsigned int index=0;index<linkedsensors.size();index++) {
+ sensor = linkedsensors[index];
+ if (sensor->GetName() == name)
+ return sensor->GetProxy();
+ }
+ break;
+ }
+ case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
+ {
+ vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
+ SCA_IActuator* actuator;
+ for (unsigned int index=0;index<linkedactuators.size();index++) {
+ actuator = linkedactuators[index];
+ if (actuator->GetName() == name)
+ return actuator->GetProxy();
+ }
+ break;
+ }
+ case KX_PYGENSEQ_OB_TYPE_SENSORS:
+ {
+ SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors();
+ SCA_ISensor *sensor;
+ for (unsigned int index=0;index<linkedsensors.size();index++) {
+ sensor= linkedsensors[index];
+ if (sensor->GetName() == name)
+ return sensor->GetProxy();
+ }
+ break;
+ }
+ case KX_PYGENSEQ_OB_TYPE_CONTROLLERS:
+ {
+ SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers();
+ SCA_IController *controller;
+ for (unsigned int index=0;index<linkedcontrollers.size();index++) {
+ controller= linkedcontrollers[index];
+ if (controller->GetName() == name)
+ return controller->GetProxy();
+ }
+ break;
+ }
+ case KX_PYGENSEQ_OB_TYPE_ACTUATORS:
+ {
+ SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators();
+ SCA_IActuator *actuator;
+ for (unsigned int index=0;index<linkedactuators.size();index++) {
+ actuator= linkedactuators[index];
+ if (actuator->GetName() == name)
+ return actuator->GetProxy();
+ }
+ break;
+ }
+ }
+
+ PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name);
+ return NULL;
+}
+
+static PyMappingMethods KX_PythonSeq_as_mapping = {
+ KX_PythonSeq_len, /* mp_length */
+ KX_PythonSeq_subscript, /* mp_subscript */
+ 0, /* mp_ass_subscript */
+};
+
+
+/*
+ * Initialize the interator index
+ */
+
+static PyObject *KX_PythonSeq_getIter(KX_PythonSeq *self)
+{
+ if(BGE_PROXY_REF(self->base)==NULL) {
+ PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
+ /* create a new iterator if were alredy using this one */
+ if (self->iter == -1) {
+ self->iter = 0;
+ Py_INCREF(self);
+ return (PyObject *)self;
+ } else {
+ return KX_PythonSeq_CreatePyObject(self->base, self->type);
+ }
+ }
+
+
+/*
+ * Return next KX_PythonSeq iter.
+ */
+
+static PyObject *KX_PythonSeq_nextIter(KX_PythonSeq *self)
+{
+ PyObject *object = KX_PythonSeq_getIndex((PyObject *)self, self->iter);
+
+ self->iter++;
+ if( object==NULL ) {
+ self->iter= -1; /* for reuse */
+ PyErr_SetString(PyExc_StopIteration, "iterator at end");
+ }
+ return object; /* can be NULL for end of iterator */
+}
+
+
+static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) /* TODO - python3.x wants richcmp */
+{
+ return ( a->type == b->type && a->base == b->base) ? 0 : -1;
+}
+
+/*
+ * repr function
+ * convert to a list and get its string value
+ */
+static PyObject *KX_PythonSeq_repr( KX_PythonSeq * self )
+{
+ PyObject *list = PySequence_List((PyObject *)self);
+ PyObject *repr = PyObject_Repr(list);
+ Py_DECREF(list);
+ return repr;
+}
+
+
+/*****************************************************************************/
+/* Python KX_PythonSeq_Type structure definition: */
+/*****************************************************************************/
+PyTypeObject KX_PythonSeq_Type = {
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
+ /* For printing, in format "<module>.<name>" */
+ "KX_PythonSeq", /* char *tp_name; */
+ sizeof( KX_PythonSeq ), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ ( destructor ) KX_PythonSeq_dealloc, /* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ ( cmpfunc ) KX_PythonSeq_compare, /* cmpfunc tp_compare; */
+ ( reprfunc ) KX_PythonSeq_repr, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ &KX_PythonSeq_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ ( getiterfunc) KX_PythonSeq_getIter, /* getiterfunc tp_iter; */
+ ( iternextfunc ) KX_PythonSeq_nextIter, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ NULL, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NULL, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h
new file mode 100644
index 00000000000..15a016224a9
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PythonSeq.h
@@ -0,0 +1,60 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * Readonly sequence wrapper for lookups on logic bricks
+ */
+
+#ifndef _adr_py_seq_h_ // only process once,
+#define _adr_py_seq_h_ // even if multiply included
+
+#include "PyObjectPlus.h"
+
+// -------------------------
+enum KX_PYGENSEQ_TYPE {
+ KX_PYGENSEQ_CONT_TYPE_SENSORS,
+ KX_PYGENSEQ_CONT_TYPE_ACTUATORS,
+ KX_PYGENSEQ_OB_TYPE_SENSORS,
+ KX_PYGENSEQ_OB_TYPE_CONTROLLERS,
+ KX_PYGENSEQ_OB_TYPE_ACTUATORS
+};
+
+/* The Main PyType Object defined in Main.c */
+extern PyTypeObject KX_PythonSeq_Type;
+
+#define BPy_KX_PythonSeq_Check(v) \
+ ((v)->ob_type == &KX_PythonSeq_Type)
+
+typedef struct {
+ PyObject_VAR_HEAD
+ PyObject *base;
+ short type;
+ short iter;
+} KX_PythonSeq;
+
+PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type);
+
+#endif // _adr_py_seq_h_
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 8277e7ef19c..064dc9126ac 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -30,6 +30,7 @@
#include "KX_GameObject.h"
#include "KX_PyMath.h"
#include "PHY_IPhysicsController.h"
+#include "PHY_IMotionState.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -66,7 +67,7 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr,
m_coneheight(coneheight),
m_axis(axis)
{
- m_client_info->m_type = KX_ClientObjectInfo::RADAR;
+ m_client_info->m_type = KX_ClientObjectInfo::SENSOR;
//m_client_info->m_clientobject = gameobj;
//m_client_info->m_auxilary_info = NULL;
//sumoObj->setClientObject(&m_client_info);
@@ -80,35 +81,10 @@ KX_RadarSensor::~KX_RadarSensor()
CValue* KX_RadarSensor::GetReplica()
{
KX_RadarSensor* replica = new KX_RadarSensor(*this);
- replica->m_colliders = new CListValue();
- replica->Init();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
- replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::RADAR);
-
- if (replica->m_physCtrl)
- {
- replica->m_physCtrl = replica->m_physCtrl->GetReplica();
- if (replica->m_physCtrl)
- {
- replica->m_physCtrl->setNewClientInfo(replica->m_client_info);
- }
- }
-
- //todo: make sure replication works fine!
- //>m_sumoObj = new SM_Object(DT_NewCone(m_coneradius, m_coneheight),NULL,NULL,NULL);
- //replica->m_sumoObj->setMargin(m_Margin);
- //replica->m_sumoObj->setClientObject(replica->m_client_info);
- //Wrong: see KX_TouchSensor
- //bool parentUpdated = false;
- //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
- replica->SynchronizeTransform();
-
+ replica->ProcessReplica();
return replica;
}
-
/**
* Transforms the collision object. A cone is not correctly centered
* for usage. */
@@ -188,11 +164,13 @@ void KX_RadarSensor::SynchronizeTransform()
if (m_physCtrl)
{
- MT_Quaternion orn = trans.getRotation();
- MT_Point3 pos = trans.getOrigin();
- m_physCtrl->setPosition(pos[0],pos[1],pos[2]);
- m_physCtrl->setOrientation(orn[0],orn[1],orn[2],orn[3]);
- m_physCtrl->calcXform();
+ PHY_IMotionState* motionState = m_physCtrl->GetMotionState();
+ const MT_Point3& pos = trans.getOrigin();
+ float ori[12];
+ trans.getBasis().getValue(ori);
+ motionState->setWorldPosition(pos[0], pos[1], pos[2]);
+ motionState->setWorldOrientation(ori);
+ m_physCtrl->WriteMotionStateToDynamics(true);
}
}
@@ -212,9 +190,9 @@ PyObject* KX_RadarSensor::PyGetConeOrigin() {
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_cone_origin[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_cone_origin[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_cone_origin[2]));
return retVal;
}
@@ -228,9 +206,9 @@ PyObject* KX_RadarSensor::PyGetConeTarget() {
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_cone_target[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_cone_target[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_cone_target[2]));
return retVal;
}
@@ -251,8 +229,13 @@ PyObject* KX_RadarSensor::PyGetConeHeight() {
/* Python Integration Hooks */
/* ------------------------------------------------------------------------- */
PyTypeObject KX_RadarSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_RadarSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -294,6 +277,7 @@ PyMethodDef KX_RadarSensor::Methods[] = {
PyAttributeDef KX_RadarSensor::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneOrigin", KX_RadarSensor, m_cone_origin, 3),
KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneTarget", KX_RadarSensor, m_cone_target, 3),
+ KX_PYATTRIBUTE_FLOAT_RO("distance", KX_RadarSensor, m_coneheight),
KX_PYATTRIBUTE_FLOAT_RW("angle", 0, 360, KX_RadarSensor, m_coneradius),
KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RadarSensor, m_axis),
{NULL} //Sentinel
@@ -304,6 +288,10 @@ PyObject* KX_RadarSensor::py_getattro(PyObject *attr)
py_getattro_up(KX_NearSensor);
}
+PyObject* KX_RadarSensor::py_getattro_dict() {
+ py_getattro_dict_up(KX_NearSensor);
+}
+
int KX_RadarSensor::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(KX_NearSensor);
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h
index c3a941696ce..2e5a0e68bed 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.h
+++ b/source/gameengine/Ketsji/KX_RadarSensor.h
@@ -90,7 +90,9 @@ public:
};
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
+ virtual sensortype GetSensorType() { return ST_RADAR; }
//Deprecated ----->
KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin);
diff --git a/source/gameengine/Ketsji/KX_RayEventManager.cpp b/source/gameengine/Ketsji/KX_RayEventManager.cpp
index 1af29151adf..50fa4f5e310 100644
--- a/source/gameengine/Ketsji/KX_RayEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_RayEventManager.cpp
@@ -44,9 +44,10 @@ using namespace std;
void KX_RayEventManager::NextFrame()
{
- for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- (*i)->Activate(m_logicmgr, NULL);
+ (*it)->Activate(m_logicmgr);
}
}
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index 06c04dbf10d..78a61e9d95e 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -88,8 +88,7 @@ KX_RaySensor::~KX_RaySensor()
CValue* KX_RaySensor::GetReplica()
{
KX_RaySensor* replica = new KX_RaySensor(*this);
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
replica->Init();
return replica;
@@ -179,7 +178,7 @@ bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo* client)
return true;
}
-bool KX_RaySensor::Evaluate(CValue* event)
+bool KX_RaySensor::Evaluate()
{
bool result = false;
bool reset = m_reset && m_level;
@@ -321,8 +320,13 @@ bool KX_RaySensor::Evaluate(CValue* event)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_RaySensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_RaySensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -362,7 +366,7 @@ PyAttributeDef KX_RaySensor::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("useMaterial", KX_RaySensor, m_bFindMaterial),
KX_PYATTRIBUTE_BOOL_RW("useXRay", KX_RaySensor, m_bXRay),
KX_PYATTRIBUTE_FLOAT_RW("range", 0, 10000, KX_RaySensor, m_distance),
- KX_PYATTRIBUTE_STRING_RW("property", 0, 100, false, KX_RaySensor, m_propertyname),
+ KX_PYATTRIBUTE_STRING_RW("propName", 0, 100, false, KX_RaySensor, m_propertyname),
KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RaySensor, m_axis),
KX_PYATTRIBUTE_FLOAT_ARRAY_RO("hitPosition", KX_RaySensor, m_hitPosition, 3),
KX_PYATTRIBUTE_FLOAT_ARRAY_RO("rayDirection", KX_RaySensor, m_rayDirection, 3),
@@ -404,9 +408,9 @@ PyObject* KX_RaySensor::PyGetHitPosition()
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_hitPosition[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_hitPosition[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_hitPosition[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_hitPosition[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_hitPosition[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_hitPosition[2]));
return retVal;
}
@@ -420,9 +424,9 @@ PyObject* KX_RaySensor::PyGetRayDirection()
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_rayDirection[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_rayDirection[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_rayDirection[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_rayDirection[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_rayDirection[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_rayDirection[2]));
return retVal;
}
@@ -436,9 +440,9 @@ PyObject* KX_RaySensor::PyGetHitNormal()
PyObject *retVal = PyList_New(3);
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_hitNormal[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_hitNormal[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_hitNormal[2]));
+ PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_hitNormal[0]));
+ PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_hitNormal[1]));
+ PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_hitNormal[2]));
return retVal;
}
@@ -449,6 +453,10 @@ PyObject* KX_RaySensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* KX_RaySensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int KX_RaySensor::py_setattro(PyObject *attr, PyObject *value) {
py_setattro_up(SCA_ISensor);
}
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index a5d7d15c60c..9efb046742f 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -67,7 +67,7 @@ public:
virtual ~KX_RaySensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void Init();
@@ -87,6 +87,7 @@ public:
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// Deprecated ----->
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index c45d89a2815..75435b97797 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -86,7 +86,7 @@ KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator()
if (m_OriginalObject)
m_OriginalObject->UnregisterActuator(this);
if (m_lastCreatedObject)
- m_lastCreatedObject->Release();
+ m_lastCreatedObject->UnregisterActuator(this);
}
@@ -124,7 +124,6 @@ CValue* KX_SCA_AddObjectActuator::GetReplica()
// this will copy properties and so on...
replica->ProcessReplica();
- CValue::AddDataToReplica(replica);
return replica;
}
@@ -145,6 +144,12 @@ bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj)
m_OriginalObject = NULL;
return true;
}
+ if (clientobj == m_lastCreatedObject)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_lastCreatedObject = NULL;
+ return true;
+ }
return false;
}
@@ -166,8 +171,13 @@ void KX_SCA_AddObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_SCA_AddObjectActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SCA_AddObjectActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -231,7 +241,7 @@ int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYAT
KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SCA_AddObjectActuator"))
- return 1; // ConvertPythonToGameObject sets the error
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
if (actuator->m_OriginalObject != NULL)
actuator->m_OriginalObject->UnregisterActuator(actuator);
@@ -241,7 +251,7 @@ int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYAT
if (actuator->m_OriginalObject)
actuator->m_OriginalObject->RegisterActuator(actuator);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
@@ -259,6 +269,10 @@ PyObject* KX_SCA_AddObjectActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_SCA_AddObjectActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_SCA_AddObjectActuator::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(SCA_IActuator);
@@ -347,7 +361,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* args)
Py_RETURN_NONE;
if (ret_name_only)
- return PyString_FromString(m_OriginalObject->GetName());
+ return PyString_FromString(m_OriginalObject->GetName().ReadPtr());
else
return m_OriginalObject->GetProxy();
}
@@ -455,13 +469,21 @@ void KX_SCA_AddObjectActuator::InstantAddObject()
// keep a copy of the last object, to allow python scripters to change it
if (m_lastCreatedObject)
{
- //careful with destruction, it might still have outstanding collision callbacks
- m_scene->DelayedReleaseObject(m_lastCreatedObject);
- m_lastCreatedObject->Release();
+ //Let's not keep a reference to the object: it's bad, if the object is deleted
+ //this will force to keep a "zombie" in the game for no good reason.
+ //m_scene->DelayedReleaseObject(m_lastCreatedObject);
+ //m_lastCreatedObject->Release();
+
+ //Instead we use the registration mechanism
+ m_lastCreatedObject->UnregisterActuator(this);
+ m_lastCreatedObject = NULL;
}
m_lastCreatedObject = replica;
- m_lastCreatedObject->AddRef();
+ // no reference
+ //m_lastCreatedObject->AddRef();
+ // but registration
+ m_lastCreatedObject->RegisterActuator(this);
// finished using replica? then release it
replica->Release();
}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 4ece5a6d83b..6746b7d1bc6 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -111,6 +111,7 @@ public:
Update();
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
SCA_IObject*
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
index 83dfdc2484c..a50764a54e6 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
@@ -50,8 +50,13 @@
PyTypeObject
KX_SCA_DynamicActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SCA_DynamicActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -85,7 +90,7 @@ PyMethodDef KX_SCA_DynamicActuator::Methods[] = {
};
PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = {
- KX_PYATTRIBUTE_SHORT_RW("operation",0,4,false,KX_SCA_DynamicActuator,m_dyn_operation),
+ KX_PYATTRIBUTE_SHORT_RW("mode",0,4,false,KX_SCA_DynamicActuator,m_dyn_operation),
KX_PYATTRIBUTE_FLOAT_RW("mass",0.0,FLT_MAX,KX_SCA_DynamicActuator,m_setmass),
{ NULL } //Sentinel
};
@@ -96,6 +101,10 @@ PyObject* KX_SCA_DynamicActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_SCA_DynamicActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_SCA_DynamicActuator::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(SCA_IActuator);
@@ -112,7 +121,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation,
"\t 3 = disable rigid body\n"
"Change the dynamic status of the parent object.\n")
{
- ShowDeprecationWarning("setOperation()", "the operation property");
+ ShowDeprecationWarning("setOperation()", "the mode property");
int dyn_operation;
if (!PyArg_ParseTuple(args, "i:setOperation", &dyn_operation))
@@ -132,7 +141,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation,
"Returns the operation type of this actuator.\n"
)
{
- ShowDeprecationWarning("getOperation()", "the operation property");
+ ShowDeprecationWarning("getOperation()", "the mode property");
return PyInt_FromLong((long)m_dyn_operation);
}
@@ -210,10 +219,6 @@ CValue* KX_SCA_DynamicActuator::GetReplica()
return NULL;
replica->ProcessReplica();
-
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
return replica;
};
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
index 99855124bdb..4add707f8cd 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
@@ -75,6 +75,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* 1. setOperation */
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
index 3b42577810e..728254e7f48 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
@@ -82,8 +82,6 @@ CValue* KX_SCA_EndObjectActuator::GetReplica()
if (replica == NULL) return NULL;
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
};
@@ -94,8 +92,13 @@ CValue* KX_SCA_EndObjectActuator::GetReplica()
/* ------------------------------------------------------------------------- */
PyTypeObject KX_SCA_EndObjectActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SCA_EndObjectActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -136,4 +139,8 @@ PyObject* KX_SCA_EndObjectActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_SCA_EndObjectActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
/* eof */
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
index 2940246f443..70d72f1f8da 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
@@ -65,6 +65,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
index 38f8d581d55..00842d7012a 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
@@ -53,8 +53,13 @@
PyTypeObject
KX_SCA_ReplaceMeshActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SCA_ReplaceMeshActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -99,6 +104,10 @@ PyObject* KX_SCA_ReplaceMeshActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_SCA_ReplaceMeshActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_SCA_ReplaceMeshActuator::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(SCA_IActuator);
@@ -119,10 +128,10 @@ int KX_SCA_ReplaceMeshActuator::pyattr_set_mesh(void *self, const struct KX_PYAT
RAS_MeshObject* new_mesh;
if (!ConvertPythonToMesh(value, &new_mesh, true, "actuator.mesh = value: KX_SCA_ReplaceMeshActuator"))
- return 1;
+ return PY_SET_ATTR_FAIL;
actuator->m_mesh = new_mesh;
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
/* 1. setMesh */
@@ -213,9 +222,6 @@ CValue* KX_SCA_ReplaceMeshActuator::GetReplica()
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
return replica;
};
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
index 7a18df2356d..0e7f7852701 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -72,6 +72,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
void InstantReplaceMesh();
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
static PyObject* pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
index 0e7571031e8..cb933419c57 100644
--- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
+++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
@@ -125,7 +125,9 @@ UpdateChildCoordinates(
else {
child->SetWorldFromLocalTransform();
}
- child->SetModified(false);
+ child->ClearModified();
+ // this node must always be updated, so reschedule it for next time
+ child->ActivateRecheduleUpdateCallback();
return valid_parent_transform;
}
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
index c3b0c21c8e0..c49b6d671a7 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
@@ -63,7 +63,7 @@ UpdateChildCoordinates(
if (parent==NULL) { /* Simple case */
child->SetWorldFromLocalTransform();
- child->SetModified(false);
+ child->ClearModified();
return true; //false;
}
else {
@@ -75,7 +75,7 @@ UpdateChildCoordinates(
child->SetWorldScale(p_world_scale * child->GetLocalScale());
child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
- child->SetModified(false);
+ child->ClearModified();
return true;
}
}
@@ -137,7 +137,7 @@ UpdateChildCoordinates(
child->SetWorldPosition(child->GetLocalPosition());
child->SetWorldOrientation(child->GetLocalOrientation());
- child->SetModified(false);
+ child->ClearModified();
return true; //parent != NULL;
}
@@ -259,7 +259,9 @@ UpdateChildCoordinates(
child->SetWorldScale(child_w_scale);
child->SetWorldPosition(child_w_pos);
child->SetWorldOrientation(child_w_rotation);
- child->SetModified(false);
+ child->ClearModified();
+ // this node must always be updated, so reschedule it for next time
+ child->ActivateRecheduleUpdateCallback();
return true; //parent != NULL;
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index aa7bd65f240..c0d8a7090c4 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -34,7 +34,7 @@
#include "KX_Scene.h"
#include "MT_assert.h"
-
+#include "SND_Scene.h"
#include "KX_KetsjiEngine.h"
#include "KX_BlenderMaterial.h"
#include "RAS_IPolygonMaterial.h"
@@ -80,6 +80,7 @@
#include "KX_BlenderSceneConverter.h"
#include "KX_MotionState.h"
+#include "BL_ModifierDeformer.h"
#include "BL_ShapeDeformer.h"
#include "BL_DeformableGameObject.h"
@@ -110,7 +111,22 @@ void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene)
return NULL;
};
-SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc,KX_GameObject::UpdateTransformFunc);
+bool KX_Scene::KX_ScenegraphUpdateFunc(SG_IObject* node,void* gameobj,void* scene)
+{
+ return ((SG_Node*)node)->Schedule(((KX_Scene*)scene)->m_sghead);
+}
+
+bool KX_Scene::KX_ScenegraphRescheduleFunc(SG_IObject* node,void* gameobj,void* scene)
+{
+ return ((SG_Node*)node)->Reschedule(((KX_Scene*)scene)->m_sghead);
+}
+
+SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(
+ KX_SceneReplicationFunc,
+ KX_SceneDestructionFunc,
+ KX_GameObject::UpdateTransformFunc,
+ KX_Scene::KX_ScenegraphUpdateFunc,
+ KX_Scene::KX_ScenegraphRescheduleFunc);
// temporarily var until there is a button in the userinterface
// (defined in KX_PythonInit.cpp)
@@ -148,7 +164,6 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_lightlist= new CListValue();
m_inactivelist = new CListValue();
m_euthanasyobjects = new CListValue();
- m_delayReleaseObjects = new CListValue();
m_logicmgr = new SCA_LogicManager();
@@ -192,9 +207,6 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_rootnode = NULL;
m_bucketmanager=new RAS_BucketManager();
-
- m_canvasDesignWidth = 0;
- m_canvasDesignHeight = 0;
m_attr_dict = PyDict_New(); /* new ref */
}
@@ -231,8 +243,6 @@ KX_Scene::~KX_Scene()
if (m_euthanasyobjects)
m_euthanasyobjects->Release();
- if (m_delayReleaseObjects)
- m_delayReleaseObjects->Release();
if (m_logicmgr)
delete m_logicmgr;
@@ -254,13 +264,6 @@ KX_Scene::~KX_Scene()
Py_DECREF(m_attr_dict);
}
-void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
-{
- m_projectionmat = pmat;
-}
-
-
-
RAS_BucketManager* KX_Scene::GetBucketManager()
{
return m_bucketmanager;
@@ -408,11 +411,11 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
if (NewRemoveObject(orgobj) != 0)
{
- // object is not yet deleted (this can happen when it hangs in an add object actuator
- // last object created reference. It's a bad situation, don't know how to fix it exactly
- // The least I can do, is remove the reference to the node in the object as the node
- // will in any case be deleted. This ensures that the object will not try to use the node
- // when it is finally deleted (see KX_GameObject destructor)
+ // object is not yet deleted because a reference is hanging somewhere.
+ // This should not happen anymore since we use proxy object for Python
+ // confident enough to put an assert?
+ //assert(false);
+ printf("Zombie object! name=%s\n", orgobj->GetName().ReadPtr());
orgobj->SetSGNode(NULL);
PHY_IGraphicController* ctrl = orgobj->GetGraphicController();
if (ctrl)
@@ -477,6 +480,8 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
// this is the list of object that are send to the graphics pipeline
m_objectlist->Add(newobj->AddRef());
+ if (newobj->IsLight())
+ m_lightlist->Add(newobj->AddRef());
newobj->AddMeshUser();
// logic cannot be replicated, until the whole hierarchy is replicated.
@@ -537,8 +542,9 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
// disconnect the sensors and actuators
- cont->UnlinkAllSensors();
- cont->UnlinkAllActuators();
+ // do it directly on the list at this controller is not connected to anything at this stage
+ cont->GetLinkedSensors().clear();
+ cont->GetLinkedActuators().clear();
// now relink each sensor
for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
@@ -716,16 +722,20 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
// set the replica's relative scale with the rootnode's scale
replica->NodeSetRelativeScale(newscale);
- MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
- replica->NodeSetLocalOrientation(newori);
MT_Point3 offset(group->dupli_ofs);
MT_Point3 newpos = groupobj->NodeGetWorldPosition() +
newscale*(groupobj->NodeGetWorldOrientation() * (gameobj->NodeGetWorldPosition()-offset));
replica->NodeSetLocalPosition(newpos);
-
+ // set the orientation after position for softbody!
+ MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+ // update scenegraph for entire tree of children
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox());
replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius());
+ // we can now add the graphic controller to the physic engine
+ replica->ActivateGraphicController(true);
+
// done with replica
replica->Release();
}
@@ -836,6 +846,8 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
+ // the size is correct, we can add the graphic controller to the physic engine
+ replica->ActivateGraphicController(true);
// now replicate logic
vector<KX_GameObject*>::iterator git;
@@ -889,7 +901,7 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
{
KX_GameObject* newobj = (KX_GameObject*) gameobj;
- // first disconnect child from parent
+ // disconnect child from parent
SG_Node* node = newobj->GetSGNode();
if (node)
@@ -903,12 +915,6 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
//newobj->SetSGNode(0);
}
-void KX_Scene::DelayedReleaseObject(CValue* gameobj)
-{
- m_delayReleaseObjects->Add(gameobj->AddRef());
-}
-
-
void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
{
//KX_GameObject* newobj = (KX_GameObject*) gameobj;
@@ -925,6 +931,13 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
int ret;
KX_GameObject* newobj = (KX_GameObject*) gameobj;
+ /* Invalidate the python reference, since the object may exist in script lists
+ * its possible that it wont be automatically invalidated, so do it manually here,
+ *
+ * if for some reason the object is added back into the scene python can always get a new Proxy
+ */
+ newobj->InvalidateProxy();
+
// keep the blender->game object association up to date
// note that all the replicas of an object will have the same
// blender object, that's why we need to check the game object
@@ -954,7 +967,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
for (SCA_ActuatorList::iterator ita = actuators.begin();
!(ita==actuators.end());ita++)
{
- m_logicmgr->RemoveDestroyedActuator(*ita);
+ m_logicmgr->RemoveActuator(*ita);
}
// the sensors/controllers/actuators must also be released, this is done in ~SCA_IObject
@@ -1038,6 +1051,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
Object* oldblendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName()));
Mesh* blendmesh = mesh->GetMesh();
+ bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(blendobj);
bool bHasShapeKey = blendmesh->key != NULL && blendmesh->key->type==KEY_RELATIVE;
bool bHasDvert = blendmesh->dvert != NULL;
bool bHasArmature =
@@ -1053,10 +1067,39 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
if (oldblendobj==NULL) {
std::cout << "warning: ReplaceMesh() new mesh is not used in an object from the current scene, you will get incorrect behavior" << std::endl;
- bHasShapeKey= bHasDvert= bHasArmature= false;
+ bHasShapeKey= bHasDvert= bHasArmature=bHasModifier= false;
}
- if (bHasShapeKey)
+ if (bHasModifier)
+ {
+ BL_ModifierDeformer* modifierDeformer;
+ if (bHasShapeKey || bHasArmature)
+ {
+ modifierDeformer = new BL_ModifierDeformer(
+ newobj,
+ m_blenderScene,
+ oldblendobj, blendobj,
+ static_cast<BL_SkinMeshObject*>(mesh),
+ true,
+ static_cast<BL_ArmatureObject*>( parentobj )
+ );
+ releaseParent= false;
+ modifierDeformer->LoadShapeDrivers(blendobj->parent);
+ }
+ else
+ {
+ modifierDeformer = new BL_ModifierDeformer(
+ newobj,
+ m_blenderScene,
+ oldblendobj, blendobj,
+ static_cast<BL_SkinMeshObject*>(mesh),
+ false,
+ NULL
+ );
+ }
+ newobj->SetDeformer(modifierDeformer);
+ }
+ else if (bHasShapeKey)
{
BL_ShapeDeformer* shapeDeformer;
if (bHasArmature)
@@ -1066,6 +1109,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
true,
+ true,
static_cast<BL_ArmatureObject*>( parentobj )
);
releaseParent= false;
@@ -1078,6 +1122,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
false,
+ true,
NULL
);
}
@@ -1090,6 +1135,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
true,
+ true,
static_cast<BL_ArmatureObject*>( parentobj )
);
releaseParent= false;
@@ -1112,24 +1158,6 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
gameobj->AddMeshUser();
}
-
-
-MT_CmMatrix4x4& KX_Scene::GetViewMatrix()
-{
- MT_Scalar cammat[16];
- m_active_camera->GetWorldToCamera().getValue(cammat);
- m_viewmat = cammat;
- return m_viewmat;
-}
-
-
-
-MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix()
-{
- return m_projectionmat;
-}
-
-
KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
{
list<KX_Camera*>::iterator it = m_cameras.begin();
@@ -1423,24 +1451,17 @@ void KX_Scene::LogicEndFrame()
{
m_logicmgr->EndFrame();
int numobj = m_euthanasyobjects->GetCount();
- int i;
- for (i = numobj - 1; i >= 0; i--)
- {
- KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
- // KX_Scene::RemoveObject will also remove the object from this list
- // that's why we start from the end
- this->RemoveObject(gameobj);
- }
- numobj= m_delayReleaseObjects->GetCount();
- for (i = numobj-1;i>=0;i--)
+ KX_GameObject* obj;
+
+ while ((numobj = m_euthanasyobjects->GetCount()) > 0)
{
- KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
- // This list is not for object removal, but just object release
- gameobj->Release();
+ // remove the object from this list to make sure we will not hit it again
+ obj = (KX_GameObject*)m_euthanasyobjects->GetValue(numobj-1);
+ m_euthanasyobjects->Remove(numobj-1);
+ obj->Release();
+ RemoveObject(obj);
}
- // empty the list as we have removed all references
- m_delayReleaseObjects->Resize(0);
}
@@ -1450,15 +1471,28 @@ void KX_Scene::LogicEndFrame()
*/
void KX_Scene::UpdateParents(double curtime)
{
-// int numrootobjects = GetRootParentList()->GetCount();
+ // we use the SG dynamic list
+ SG_Node* node;
- for (int i=0; i<GetRootParentList()->GetCount(); i++)
+ while ((node = SG_Node::GetNextScheduled(m_sghead)) != NULL)
{
- KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
- parentobj->NodeUpdateGS(curtime);
+ node->UpdateWorldData(curtime);
}
-}
+ //for (int i=0; i<GetRootParentList()->GetCount(); i++)
+ //{
+ // KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
+ // parentobj->NodeUpdateGS(curtime);
+ //}
+
+ // the list must be empty here
+ assert(m_sghead.Empty());
+ // some nodes may be ready for reschedule, move them to schedule list for next time
+ while ((node = SG_Node::GetNextRescheduled(m_sghead)) != NULL)
+ {
+ node->Schedule(m_sghead);
+ }
+}
RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool &bucketCreated)
@@ -1579,8 +1613,13 @@ double KX_Scene::getSuspendedDelta()
//Python
PyTypeObject KX_Scene::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_Scene",
sizeof(PyObjectPlus_Proxy),
0,
@@ -1604,9 +1643,9 @@ PyParentObject KX_Scene::Parents[] = {
};
PyMethodDef KX_Scene::Methods[] = {
- KX_PYMETHODTABLE(KX_Scene, getLightList),
- KX_PYMETHODTABLE(KX_Scene, getObjectList),
- KX_PYMETHODTABLE(KX_Scene, getName),
+ KX_PYMETHODTABLE_NOARGS(KX_Scene, getLightList),
+ KX_PYMETHODTABLE_NOARGS(KX_Scene, getObjectList),
+ KX_PYMETHODTABLE_NOARGS(KX_Scene, getName),
KX_PYMETHODTABLE(KX_Scene, addObject),
{NULL,NULL} //Sentinel
@@ -1624,46 +1663,81 @@ PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *a
return self->GetObjectList()->GetProxy();
}
+PyObject* KX_Scene::pyattr_get_objects_inactive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self= static_cast<KX_Scene*>(self_v);
+ return self->GetInactiveList()->GetProxy();
+}
+
+PyObject* KX_Scene::pyattr_get_lights(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self= static_cast<KX_Scene*>(self_v);
+ return self->GetLightList()->GetProxy();
+}
+
+PyObject* KX_Scene::pyattr_get_cameras(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ /* With refcounts in this case...
+ * the new CListValue is owned by python, so its possible python holds onto it longer then the BGE
+ * however this is the same with "scene.objects + []", when you make a copy by adding lists.
+ */
+
+ KX_Scene* self= static_cast<KX_Scene*>(self_v);
+ CListValue* clist = new CListValue();
+
+ /* return self->GetCameras()->GetProxy(); */
+
+ list<KX_Camera*>::iterator it = self->GetCameras()->begin();
+ while (it != self->GetCameras()->end()) {
+ clist->Add((*it)->AddRef());
+ it++;
+ }
+
+ return clist->NewProxy(true);
+}
+
PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Scene* self= static_cast<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)
+
+int KX_Scene::pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
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);
+ KX_Camera *camOb;
- PyDict_Update(dict, self->m_attr_dict);
- return dict;
+ if (!ConvertPythonToCamera(value, &camOb, false, "scene.active_camera = value: KX_Scene"))
+ return PY_SET_ATTR_FAIL;
+
+ self->SetActiveCamera(camOb);
+ return PY_SET_ATTR_SUCCESS;
}
+
PyAttributeDef KX_Scene::Attributes[] = {
- KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name),
- KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects),
- KX_PYATTRIBUTE_RO_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera),
- KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend),
- KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling),
+ KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name),
+ KX_PYATTRIBUTE_RO_FUNCTION("objects", KX_Scene, pyattr_get_objects),
+ KX_PYATTRIBUTE_RO_FUNCTION("objectsInactive", KX_Scene, pyattr_get_objects_inactive), KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights),
+ KX_PYATTRIBUTE_RO_FUNCTION("cameras", KX_Scene, pyattr_get_cameras),
+ KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights),
+ KX_PYATTRIBUTE_RW_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera),
+ 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),
+ KX_PYATTRIBUTE_BOOL_RO("dbvt_culling", KX_Scene, m_dbvt_culling),
{ NULL } //Sentinel
};
-
PyObject* KX_Scene::py_getattro__internal(PyObject *attr)
{
py_getattro_up(PyObjectPlus);
}
-int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *pyvalue)
+int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *value)
{
- return PyObjectPlus::py_setattro(attr, pyvalue);
+ py_setattro_up(PyObjectPlus);
}
PyObject* KX_Scene::py_getattro(PyObject *attr)
@@ -1685,6 +1759,18 @@ PyObject* KX_Scene::py_getattro(PyObject *attr)
return object;
}
+PyObject* KX_Scene::py_getattro_dict() {
+ //py_getattro_dict_up(PyObjectPlus);
+
+ PyObject *dict= py_getattr_dict(PyObjectPlus::py_getattro_dict(), Type.tp_dict);
+ if(dict==NULL)
+ return NULL;
+
+ /* normally just return this but KX_Scene has some more items */
+
+ PyDict_Update(dict, m_attr_dict);
+ return dict;
+}
int KX_Scene::py_setattro(PyObject *attr, PyObject *value)
{
@@ -1715,6 +1801,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
"Returns a list of all lights in the scene.\n"
)
{
+ ShowDeprecationWarning("getLightList()", "the lights property");
return m_lightlist->GetProxy();
}
@@ -1723,7 +1810,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList,
"Returns a list of all game objects in the scene.\n"
)
{
- // ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work?
+ ShowDeprecationWarning("getObjectList()", "the objects property");
return m_objectlist->GetProxy();
}
@@ -1732,6 +1819,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName,
"Returns the name of the scene.\n"
)
{
+ ShowDeprecationWarning("getName()", "the name property");
return PyString_FromString(GetName());
}
@@ -1753,5 +1841,9 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject,
SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
+
+ // release here because AddReplicaObject AddRef's
+ // the object is added to the scene so we dont want python to own a reference
+ replica->Release();
return replica->GetProxy();
-} \ No newline at end of file
+}
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index a06c66ec5dd..79d3f7fd828 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -32,8 +32,6 @@
#include "KX_PhysicsEngineEnums.h"
-#include "MT_CmMatrix4x4.h"
-
#include <vector>
#include <set>
#include <list>
@@ -43,7 +41,7 @@
#include "SG_IObject.h"
#include "SCA_IScene.h"
#include "MT_Transform.h"
-#include "SND_Scene.h"
+
#include "RAS_FramingManager.h"
#include "RAS_Rect.h"
@@ -110,16 +108,16 @@ protected:
* LogicEndFrame() via a call to RemoveObject().
*/
CListValue* m_euthanasyobjects;
- /**
- * The list of objects that couldn't be released during logic update.
- * for example, AddObject actuator sometimes releases an object that was cached from previous frame
- */
- CListValue* m_delayReleaseObjects;
CListValue* m_objectlist;
CListValue* m_parentlist; // all 'root' parents
CListValue* m_lightlist;
CListValue* m_inactivelist; // all objects that are not in the active layer
+
+ SG_QList m_sghead; // list of nodes that needs scenegraph update
+ // the Dlist is not object that must be updated
+ // the Qlist is for objects that needs to be rescheduled
+ // for updates after udpate is over (slow parent, bone parent)
/**
* The tree of objects in the scene.
@@ -191,20 +189,6 @@ protected:
*/
KX_Camera* m_active_camera;
- /**
- * The projection and view matrices of this scene
- * The projection matrix is computed externally by KX_Engine
- * The view mat is stored as a side effect of GetViewMatrix()
- * and is totally unnessary.
- */
- MT_CmMatrix4x4 m_projectionmat;
- MT_CmMatrix4x4 m_viewmat;
-
- /** Desired canvas width set at design time. */
- unsigned int m_canvasDesignWidth;
- /** Desired canvas height set at design time. */
- unsigned int m_canvasDesignHeight;
-
/**
* Another temporary variable outstaying its welcome
* used in AddReplicaObject to map game objects to their
@@ -318,6 +302,8 @@ public:
/**
* Update all transforms according to the scenegraph.
*/
+ static bool KX_ScenegraphUpdateFunc(SG_IObject* node,void* gameobj,void* scene);
+ static bool KX_ScenegraphRescheduleFunc(SG_IObject* node,void* gameobj,void* scene);
void UpdateParents(double curtime);
void DupliGroupRecurse(CValue* gameobj, int level);
bool IsObjectInGroup(CValue* gameobj)
@@ -335,8 +321,6 @@ public:
void RemoveObject(CValue* gameobj);
void DelayedRemoveObject(CValue* gameobj);
- void DelayedReleaseObject(CValue* gameobj);
-
int NewRemoveObject(CValue* gameobj);
void ReplaceMesh(CValue* gameobj,
void* meshobj);
@@ -422,25 +406,6 @@ public:
class KX_Camera*
);
- /** Return the viewmatrix as used by the last frame. */
- MT_CmMatrix4x4&
- GetViewMatrix(
- );
-
- /**
- * Return the projectionmatrix as used by the last frame. This is
- * set by hand :)
- */
- MT_CmMatrix4x4&
- GetProjectionMatrix(
- );
-
- /** Sets the projection matrix. */
- void
- SetProjectionMatrix(
- MT_CmMatrix4x4& pmat
- );
-
/**
* Activates new desired canvas width set at design time.
* @param width The new desired width.
@@ -592,14 +557,16 @@ public:
/* attributes */
static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_objects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_objects_inactive(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_lights(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_cameras(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
- /* for dir(), python3 uses __dir__() */
- static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
+ static int pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
- virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
+ virtual PyObject* py_getattro_dict();
+
+ virtual int py_setattro(PyObject *attr, PyObject *value);
virtual int py_delattro(PyObject *attr);
virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); }
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp
index f54d8542260..1b790ec9824 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp
@@ -76,9 +76,6 @@ CValue* KX_SceneActuator::GetReplica()
{
KX_SceneActuator* replica = new KX_SceneActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
-
return replica;
}
@@ -226,8 +223,13 @@ KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_SceneActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SceneActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -262,7 +264,7 @@ PyMethodDef KX_SceneActuator::Methods[] =
//Deprecated functions ------>
{"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc},
{"setScene", (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc},
- {"setCamera", (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, (PY_METHODCHAR)SetCamera_doc},
+ {"setCamera", (PyCFunction) KX_SceneActuator::sPySetCamera, METH_O, (PY_METHODCHAR)SetCamera_doc},
{"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_NOARGS, (PY_METHODCHAR)GetUseRestart_doc},
{"getScene", (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (PY_METHODCHAR)GetScene_doc},
{"getCamera", (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (PY_METHODCHAR)GetCamera_doc},
@@ -273,6 +275,8 @@ PyMethodDef KX_SceneActuator::Methods[] =
PyAttributeDef KX_SceneActuator::Attributes[] = {
KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
+ KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart),
+ KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode),
{ NULL } //Sentinel
};
@@ -281,6 +285,10 @@ PyObject* KX_SceneActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_SceneActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_IActuator);
@@ -300,51 +308,21 @@ int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_
KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
KX_Camera *camOb;
- if(value==Py_None)
- {
- if (actuator->m_camera)
- actuator->m_camera->UnregisterActuator(actuator);
-
+ if (!ConvertPythonToCamera(value, &camOb, true, "actu.camera = value: KX_SceneActuator"))
+ return PY_SET_ATTR_FAIL;
+
+ if (actuator->m_camera)
+ actuator->m_camera->UnregisterActuator(actuator);
+
+ if(camOb==NULL) {
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);
-
+ else {
actuator->m_camera = camOb;
actuator->m_camera->RegisterActuator(actuator);
- return 0;
- }
-
- if (PyString_Check(value))
- {
- char *camName = PyString_AsString(value);
-
- camOb = actuator->FindCamera(camName);
- if (camOb)
- {
- if (actuator->m_camera)
- actuator->m_camera->UnregisterActuator(actuator);
- actuator->m_camera = camOb;
- actuator->m_camera->RegisterActuator(actuator);
- return 0;
- }
- PyErr_SetString(PyExc_TypeError, "not a valid camera name");
- return 1;
}
- PyErr_SetString(PyExc_TypeError, "expected a string or a camera object reference");
- return 1;
+
+ return PY_SET_ATTR_SUCCESS;
}
@@ -355,7 +333,7 @@ const char KX_SceneActuator::SetUseRestart_doc[] =
"\tSet flag to 1 to restart the scene.\n" ;
PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
{
- ShowDeprecationWarning("setUseRestart()", "(no replacement)");
+ ShowDeprecationWarning("setUseRestart()", "the useRestart property");
int boolArg;
if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
@@ -376,7 +354,7 @@ const char KX_SceneActuator::GetUseRestart_doc[] =
"\tReturn whether the scene will be restarted.\n" ;
PyObject* KX_SceneActuator::PyGetUseRestart()
{
- ShowDeprecationWarning("getUseRestart()", "(no replacement)");
+ ShowDeprecationWarning("getUseRestart()", "the useRestart property");
return PyInt_FromLong(!(m_restart == 0));
}
@@ -423,47 +401,24 @@ const char KX_SceneActuator::SetCamera_doc[] =
"setCamera(camera)\n"
"\t- camera: string\n"
"\tSet the camera to switch to.\n" ;
-PyObject* KX_SceneActuator::PySetCamera(PyObject* args)
+PyObject* KX_SceneActuator::PySetCamera(PyObject* value)
{
ShowDeprecationWarning("setCamera()", "the camera property");
- PyObject *cam;
- if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam))
- {
- KX_Camera *new_camera;
-
- new_camera = static_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= new_camera;
-
- m_camera->RegisterActuator(this);
- Py_RETURN_NONE;
- }
- PyErr_Clear();
-
- /* one argument: a scene, ignore the rest */
- char *camName;
- if(!PyArg_ParseTuple(args, "s:setCamera", &camName))
- {
+ KX_Camera *camOb;
+
+ if (!ConvertPythonToCamera(value, &camOb, true, "actu.setCamera(value): KX_SceneActuator"))
return NULL;
+
+ if (m_camera)
+ m_camera->UnregisterActuator(this);
+
+ if(camOb==NULL) {
+ m_camera= NULL;
}
-
- KX_Camera *camOb = FindCamera(camName);
- if (camOb)
- {
- if (m_camera)
- m_camera->UnregisterActuator(this);
+ else {
m_camera = camOb;
m_camera->RegisterActuator(this);
}
-
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index 803c5106a60..2412dd02590 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -93,6 +93,7 @@ class KX_SceneActuator : public SCA_IActuator
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* 1. set */
@@ -107,7 +108,7 @@ class KX_SceneActuator : public SCA_IActuator
/* 5. getScene: */
KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetScene);
/* 6. setCamera: */
- KX_PYMETHOD_DOC_VARARGS(KX_SceneActuator,SetCamera);
+ KX_PYMETHOD_DOC_O(KX_SceneActuator,SetCamera);
/* 7. getCamera: */
KX_PYMETHOD_DOC_NOARGS(KX_SceneActuator,GetCamera);
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 412be497c5a..5c02a2db646 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -83,19 +83,19 @@ CValue* KX_SoundActuator::GetReplica()
{
KX_SoundActuator* replica = new KX_SoundActuator(*this);
replica->ProcessReplica();
+ return replica;
+};
+
+void KX_SoundActuator::ProcessReplica()
+{
+ SCA_IActuator::ProcessReplica();
if (m_soundObject)
{
SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
- replica->setSoundObject(soundobj);
+ setSoundObject(soundobj);
m_soundScene->AddObject(soundobj);
}
-
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
- return replica;
-};
-
-
+}
bool KX_SoundActuator::Update(double curtime, bool frame)
{
@@ -234,8 +234,13 @@ void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_SoundActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_SoundActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -290,7 +295,7 @@ PyMethodDef KX_SoundActuator::Methods[] = {
};
PyAttributeDef KX_SoundActuator::Attributes[] = {
- KX_PYATTRIBUTE_RW_FUNCTION("filename", KX_SoundActuator, pyattr_get_filename, pyattr_set_filename),
+ KX_PYATTRIBUTE_RW_FUNCTION("fileName", KX_SoundActuator, pyattr_get_filename, pyattr_set_filename),
KX_PYATTRIBUTE_RW_FUNCTION("volume", KX_SoundActuator, pyattr_get_gain, pyattr_set_gain),
KX_PYATTRIBUTE_RW_FUNCTION("pitch", KX_SoundActuator, pyattr_get_pitch, pyattr_set_pitch),
KX_PYATTRIBUTE_RW_FUNCTION("rollOffFactor", KX_SoundActuator, pyattr_get_rollOffFactor, pyattr_set_rollOffFactor),
@@ -298,7 +303,7 @@ PyAttributeDef KX_SoundActuator::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("position", KX_SoundActuator, pyattr_get_position, pyattr_set_position),
KX_PYATTRIBUTE_RW_FUNCTION("velocity", KX_SoundActuator, pyattr_get_velocity, pyattr_set_velocity),
KX_PYATTRIBUTE_RW_FUNCTION("orientation", KX_SoundActuator, pyattr_get_orientation, pyattr_set_orientation),
- KX_PYATTRIBUTE_ENUM_RW("type",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type),
+ KX_PYATTRIBUTE_ENUM_RW("mode",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type),
{ NULL } //Sentinel
};
@@ -340,6 +345,10 @@ PyObject* KX_SoundActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_SoundActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_SoundActuator::py_setattro(PyObject *attr, PyObject* value) {
py_setattro_up(SCA_IActuator);
}
@@ -355,7 +364,7 @@ PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYAT
char* name = objectname.Ptr();
if (!name) {
- PyErr_SetString(PyExc_RuntimeError, "value = actuator.filename: KX_SoundActuator, unable to get sound filename");
+ PyErr_SetString(PyExc_RuntimeError, "value = actuator.fileName: KX_SoundActuator, unable to get sound fileName");
return NULL;
} else
return PyString_FromString(name);
@@ -441,13 +450,13 @@ int KX_SoundActuator::pyattr_set_filename(void *self, const struct KX_PYATTRIBUT
// void *soundPointer = NULL; /*unused*/
if (!PyArg_Parse(value, "s", &soundName))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject) {
actuator->m_soundObject->SetObjectName(soundName);
}
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
@@ -456,12 +465,12 @@ int KX_SoundActuator::pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DE
float gain = 1.0;
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
if (!PyArg_Parse(value, "f", &gain))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject)
actuator->m_soundObject->SetGain(gain);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -469,12 +478,12 @@ int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_D
float pitch = 1.0;
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
if (!PyArg_Parse(value, "f", &pitch))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject)
actuator->m_soundObject->SetPitch(pitch);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -482,12 +491,12 @@ int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATT
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
float rollofffactor = 1.0;
if (!PyArg_Parse(value, "f", &rollofffactor))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject)
actuator->m_soundObject->SetRollOffFactor(rollofffactor);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -495,12 +504,12 @@ int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
int looping = 1;
if (!PyArg_Parse(value, "i", &looping))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject)
actuator->m_soundObject->SetLoopMode(looping);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -510,12 +519,12 @@ int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUT
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
if (!PyArg_ParseTuple(value, "fff", &pos[0], &pos[1], &pos[2]))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject)
actuator->m_soundObject->SetPosition(MT_Vector3(pos));
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -525,12 +534,12 @@ int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUT
if (!PyArg_ParseTuple(value, "fff", &vel[0], &vel[1], &vel[2]))
- return 1;
+ return PY_SET_ATTR_FAIL;
if (actuator->m_soundObject)
actuator->m_soundObject->SetVelocity(MT_Vector3(vel));
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
@@ -542,21 +551,22 @@ int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRI
/* if value is not a sequence PyOrientationTo makes an error */
if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator"))
- return NULL;
+ return PY_SET_ATTR_FAIL;
+ /* Since not having m_soundObject didn't do anything in the old version,
+ * it probably should be kept that way */
if (!actuator->m_soundObject)
- return 0; /* Since not having m_soundObject didn't do anything in the old version,
- * it probably should be kept that way */
+ return PY_SET_ATTR_SUCCESS;
actuator->m_soundObject->SetOrientation(rot);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
// Deprecated ----->
PyObject* KX_SoundActuator::PySetFilename(PyObject* args)
{
char *soundName = NULL;
- ShowDeprecationWarning("setFilename()", "the filename property");
+ ShowDeprecationWarning("setFilename()", "the fileName property");
// void *soundPointer = NULL; /*unused*/
if (!PyArg_ParseTuple(args, "s", &soundName))
@@ -567,7 +577,7 @@ PyObject* KX_SoundActuator::PySetFilename(PyObject* args)
PyObject* KX_SoundActuator::PyGetFilename()
{
- ShowDeprecationWarning("getFilename()", "the filename property");
+ ShowDeprecationWarning("getFilename()", "the fileName property");
if (!m_soundObject)
{
return PyString_FromString("");
@@ -576,7 +586,7 @@ PyObject* KX_SoundActuator::PyGetFilename()
char* name = objectname.Ptr();
if (!name) {
- PyErr_SetString(PyExc_RuntimeError, "Unable to get sound filename");
+ PyErr_SetString(PyExc_RuntimeError, "Unable to get sound fileName");
return NULL;
} else
return PyString_FromString(name);
@@ -750,7 +760,7 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* args)
PyObject* KX_SoundActuator::PySetType(PyObject* args)
{
int typeArg;
- ShowDeprecationWarning("setType()", "the type property");
+ ShowDeprecationWarning("setType()", "the mode property");
if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
return NULL;
@@ -766,7 +776,7 @@ PyObject* KX_SoundActuator::PySetType(PyObject* args)
PyObject* KX_SoundActuator::PyGetType()
{
- ShowDeprecationWarning("getType()", "the type property");
+ ShowDeprecationWarning("getType()", "the mode property");
return PyInt_FromLong(m_type);
}
// <-----
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index d5e678bbecd..a7491355667 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -75,12 +75,14 @@ public:
virtual bool Update(double curtime, bool frame);
CValue* GetReplica();
+ void ProcessReplica();
/* -------------------------------------------------------------------- */
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, startSound);
diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp
index 976e7ea5204..f6979eee0f4 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.cpp
+++ b/source/gameengine/Ketsji/KX_StateActuator.cpp
@@ -55,6 +55,9 @@ KX_StateActuator::~KX_StateActuator(
// intentionally empty
}
+// used to put state actuator to be executed before any other actuators
+SG_QList KX_StateActuator::m_stateActuatorHead;
+
CValue*
KX_StateActuator::GetReplica(
void
@@ -62,8 +65,6 @@ KX_StateActuator::GetReplica(
{
KX_StateActuator* replica = new KX_StateActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
}
@@ -72,7 +73,10 @@ KX_StateActuator::Update()
{
bool bNegativeEvent = IsNegativeEvent();
unsigned int objMask;
-
+
+ // execution of state actuator means that we are in the execution phase, reset this pointer
+ // because all the active actuator of this object will be removed for sure.
+ m_gameobj->m_firstState = NULL;
RemoveAllEvents();
if (bNegativeEvent) return false;
@@ -101,6 +105,31 @@ KX_StateActuator::Update()
return false;
}
+// this function is only used to deactivate actuators outside the logic loop
+// e.g. when an object is deleted.
+void KX_StateActuator::Deactivate()
+{
+ if (QDelink())
+ {
+ // the actuator was in the active list
+ if (m_stateActuatorHead.QEmpty())
+ // no more state object active
+ m_stateActuatorHead.Delink();
+ }
+}
+
+void KX_StateActuator::Activate(SG_DList& head)
+{
+ // sort the state actuators per object on the global list
+ if (QEmpty())
+ {
+ InsertSelfActiveQList(m_stateActuatorHead, &m_gameobj->m_firstState);
+ // add front to make sure it runs before other actuators
+ head.AddFront(&m_stateActuatorHead);
+ }
+}
+
+
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
@@ -109,8 +138,13 @@ KX_StateActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_StateActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_StateActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -156,7 +190,11 @@ PyAttributeDef KX_StateActuator::Attributes[] = {
PyObject* KX_StateActuator::py_getattro(PyObject *attr)
{
py_getattro_up(SCA_IActuator);
-};
+}
+
+PyObject* KX_StateActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
int KX_StateActuator::py_setattro(PyObject *attr, PyObject* value)
{
diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h
index 4a64894259d..a4191a4c5fd 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.h
+++ b/source/gameengine/Ketsji/KX_StateActuator.h
@@ -33,6 +33,13 @@
#include "SCA_IActuator.h"
+
+/*
+ * Use of SG_DList : element of actuator being deactivated
+ * Head: SCA_LogicManager::m_removedActuators
+ * Use of SG_QList : element of global activated state actuator list
+ * Head: KX_StateActuator::m_stateActuatorHead
+ */
class KX_StateActuator : public SCA_IActuator
{
Py_Header;
@@ -46,6 +53,11 @@ class KX_StateActuator : public SCA_IActuator
OP_NEG,
OP_COUNT
};
+ // SG_Dlist: element of objects with active actuators, always put in front of the list
+ // Head: SCA_LogicManager::m_activeActuators
+ // SG_QList: Head of active state actuators list globally
+ // Elements: KX_StateActuator
+ static SG_QList m_stateActuatorHead;
int m_operation;
int m_mask;
@@ -71,11 +83,15 @@ class KX_StateActuator : public SCA_IActuator
virtual bool
Update();
+ virtual void Deactivate();
+ virtual void Activate(SG_DList& head);
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
//KX_PYMETHOD_DOC
KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetOperation);
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
index 083d89896f6..278994c6ae7 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
@@ -53,7 +53,7 @@ public:
class SM_Object* sumoObj,
class PHY_IMotionState* motionstate
,bool dyna)
- : KX_IPhysicsController(dyna,false,NULL) ,
+ : KX_IPhysicsController(dyna,false,false,NULL) ,
SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna)
{
};
@@ -83,6 +83,7 @@ public:
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Matrix3x3& orn);
+ virtual void SetTransform() {}
virtual void setPosition(const MT_Point3& pos);
virtual void setScaling(const MT_Vector3& scaling);
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 48d4cf59a2b..712a512995e 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -85,14 +85,35 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data,
PHY_IPhysicsController* ctrl = static_cast<PHY_IPhysicsController*>(object1);
KX_ClientObjectInfo* info = (ctrl) ? static_cast<KX_ClientObjectInfo*>(ctrl->getNewClientInfo()) : NULL;
// This call back should only be called for controllers of Near and Radar sensor
- if (info &&
- info->m_sensors.size() == 1 &&
- (info->m_type == KX_ClientObjectInfo::NEAR ||
- info->m_type == KX_ClientObjectInfo::RADAR))
+ if (!info)
+ return true;
+
+ switch (info->m_type)
{
- // only one sensor for this type of object
- KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin());
- return touchsensor->BroadPhaseFilterCollision(object1,object2);
+ case KX_ClientObjectInfo::SENSOR:
+ if (info->m_sensors.size() == 1)
+ {
+ // only one sensor for this type of object
+ KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin());
+ return touchsensor->BroadPhaseFilterCollision(object1,object2);
+ }
+ break;
+ case KX_ClientObjectInfo::OBSENSOR:
+ case KX_ClientObjectInfo::OBACTORSENSOR:
+ // this object may have multiple collision sensors,
+ // check is any of them is interested in this object
+ for(std::list<SCA_ISensor*>::iterator it = info->m_sensors.begin();
+ it != info->m_sensors.end();
+ ++it)
+ {
+ if ((*it)->GetSensorType() == SCA_ISensor::ST_TOUCH)
+ {
+ KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*it);
+ if (touchsensor->BroadPhaseSensorFilterCollision(object1, object2))
+ return true;
+ }
+ }
+ return false;
}
return true;
}
@@ -100,7 +121,7 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data,
void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
{
KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
- if (m_sensors.insert(touchsensor).second)
+ if (m_sensors.AddBack(touchsensor))
// the sensor was effectively inserted, register it
touchsensor->RegisterSumo(this);
}
@@ -108,7 +129,7 @@ void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
{
KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
- if (m_sensors.erase(touchsensor))
+ if (touchsensor->Delink())
// the sensor was effectively removed, unregister it
touchsensor->UnregisterSumo(this);
}
@@ -117,12 +138,10 @@ void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
void KX_TouchEventManager::EndFrame()
{
- set<SCA_ISensor*>::iterator it;
- for ( it = m_sensors.begin();
- !(it==m_sensors.end());it++)
+ SG_DList::iterator<KX_TouchSensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- ((KX_TouchSensor*)*it)->EndFrame();
-
+ (*it)->EndFrame();
}
}
@@ -130,12 +149,11 @@ void KX_TouchEventManager::EndFrame()
void KX_TouchEventManager::NextFrame()
{
- if (m_sensors.size() > 0)
+ if (!m_sensors.Empty())
{
- set<SCA_ISensor*>::iterator it;
-
- for (it = m_sensors.begin();!(it==m_sensors.end());++it)
- static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
+ SG_DList::iterator<KX_TouchSensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
+ (*it)->SynchronizeTransform();
for (std::set<NewCollision>::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit)
{
@@ -161,7 +179,7 @@ void KX_TouchEventManager::NextFrame()
m_newCollisions.clear();
- for (it = m_sensors.begin();!(it==m_sensors.end());++it)
- (*it)->Activate(m_logicmgr,NULL);
+ for (it.begin();!it.end();++it)
+ (*it)->Activate(m_logicmgr);
}
}
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 5a6e8e6f501..c06acd4a873 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -66,10 +66,10 @@ void KX_TouchSensor::UnregisterToManager()
{
// before unregistering the sensor, make sure we release all references
EndFrame();
- m_eventmgr->RemoveSensor(this);
+ SCA_ISensor::UnregisterToManager();
}
-bool KX_TouchSensor::Evaluate(CValue* event)
+bool KX_TouchSensor::Evaluate()
{
bool result = false;
bool reset = m_reset && m_level;
@@ -142,13 +142,17 @@ KX_TouchSensor::~KX_TouchSensor()
CValue* KX_TouchSensor::GetReplica()
{
KX_TouchSensor* replica = new KX_TouchSensor(*this);
- replica->m_colliders = new CListValue();
- replica->Init();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
+void KX_TouchSensor::ProcessReplica()
+{
+ SCA_ISensor::ProcessReplica();
+ m_colliders = new CListValue();
+ Init();
+}
+
void KX_TouchSensor::ReParent(SCA_IObject* parent)
{
KX_GameObject *gameobj = static_cast<KX_GameObject *>(parent);
@@ -169,21 +173,69 @@ void KX_TouchSensor::RegisterSumo(KX_TouchEventManager *touchman)
{
if (m_physCtrl)
{
- touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl);
- // collision
- // Deprecated
-
+ if (touchman->GetPhysicsEnvironment()->requestCollisionCallback(m_physCtrl))
+ {
+ KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>(m_physCtrl->getNewClientInfo());
+ if (client_info->isSensor())
+ touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl);
+ }
}
}
-
void KX_TouchSensor::UnregisterSumo(KX_TouchEventManager* touchman)
{
if (m_physCtrl)
{
- touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl);
+ if (touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl))
+ {
+ // no more sensor on the controller, can remove it if it is a sensor object
+ KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>(m_physCtrl->getNewClientInfo());
+ if (client_info->isSensor())
+ touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl);
+ }
}
}
+// this function is called only for sensor objects
+// return true if the controller can collide with the object
+bool KX_TouchSensor::BroadPhaseSensorFilterCollision(void*obj1,void*obj2)
+{
+ assert(obj1==m_physCtrl && obj2);
+
+ KX_GameObject* myobj = (KX_GameObject*)GetParent();
+ KX_GameObject* myparent = myobj->GetParent();
+ KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>(((PHY_IPhysicsController*)obj2)->getNewClientInfo());
+ KX_ClientObjectInfo* my_client_info = static_cast<KX_ClientObjectInfo*>(m_physCtrl->getNewClientInfo());
+ KX_GameObject* otherobj = ( client_info ? client_info->m_gameobject : NULL);
+
+ // first, decrement refcount as GetParent() increases it
+ if (myparent)
+ myparent->Release();
+
+ // we can only check on persistent characteristic: m_link and m_suspended are not
+ // good candidate because they are transient. That must be handled at another level
+ if (!otherobj ||
+ otherobj == myparent || // don't interact with our parent
+ (my_client_info->m_type == KX_ClientObjectInfo::OBACTORSENSOR &&
+ client_info->m_type != KX_ClientObjectInfo::ACTOR)) // only with actor objects
+ return false;
+
+ bool found = m_touchedpropname.IsEmpty();
+ if (!found)
+ {
+ if (m_bFindMaterial)
+ {
+ if (client_info->m_auxilary_info)
+ {
+ found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info));
+ }
+ } else
+ {
+ found = (otherobj->GetProperty(m_touchedpropname) != NULL);
+ }
+ }
+ return found;
+}
+
bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_CollData* colldata)
{
// KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr;
@@ -242,8 +294,13 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
/* ------------------------------------------------------------------------- */
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_TouchSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_TouchSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -283,11 +340,11 @@ PyMethodDef KX_TouchSensor::Methods[] = {
};
PyAttributeDef KX_TouchSensor::Attributes[] = {
- KX_PYATTRIBUTE_STRING_RW("property",0,100,false,KX_TouchSensor,m_touchedpropname),
+ KX_PYATTRIBUTE_STRING_RW("propName",0,100,false,KX_TouchSensor,m_touchedpropname),
KX_PYATTRIBUTE_BOOL_RW("useMaterial",KX_TouchSensor,m_bFindMaterial),
- KX_PYATTRIBUTE_BOOL_RW("pulseCollisions",KX_TouchSensor,m_bTouchPulse),
- KX_PYATTRIBUTE_RO_FUNCTION("objectHit", KX_TouchSensor, pyattr_get_object_hit),
- KX_PYATTRIBUTE_RO_FUNCTION("objectHitList", KX_TouchSensor, pyattr_get_object_hit_list),
+ KX_PYATTRIBUTE_BOOL_RW("usePulseCollision",KX_TouchSensor,m_bTouchPulse),
+ KX_PYATTRIBUTE_RO_FUNCTION("hitObject", KX_TouchSensor, pyattr_get_object_hit),
+ KX_PYATTRIBUTE_RO_FUNCTION("hitObjectList", KX_TouchSensor, pyattr_get_object_hit_list),
{ NULL } //Sentinel
};
@@ -296,6 +353,10 @@ PyObject* KX_TouchSensor::py_getattro(PyObject *attr)
py_getattro_up(SCA_ISensor);
}
+PyObject* KX_TouchSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int KX_TouchSensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ISensor);
@@ -312,7 +373,7 @@ const char KX_TouchSensor::SetProperty_doc[] =
"\tmaterials.";
PyObject* KX_TouchSensor::PySetProperty(PyObject* value)
{
- ShowDeprecationWarning("setProperty()", "the propertyName property");
+ ShowDeprecationWarning("setProperty()", "the propName property");
char *nameArg= PyString_AsString(value);
if (nameArg==NULL) {
PyErr_SetString(PyExc_ValueError, "expected a ");
@@ -329,6 +390,8 @@ const char KX_TouchSensor::GetProperty_doc[] =
"\tgetTouchMaterial() to find out whether this sensor\n"
"\tlooks for properties or materials.";
PyObject* KX_TouchSensor::PyGetProperty() {
+ ShowDeprecationWarning("getProperty()", "the propName property");
+
return PyString_FromString(m_touchedpropname);
}
@@ -337,7 +400,7 @@ const char KX_TouchSensor::GetHitObject_doc[] =
;
PyObject* KX_TouchSensor::PyGetHitObject()
{
- ShowDeprecationWarning("getHitObject()", "the objectHit property");
+ ShowDeprecationWarning("getHitObject()", "the hitObject property");
/* to do: do Py_IncRef if the object is already known in Python */
/* otherwise, this leaks memory */
if (m_hitObject)
@@ -353,7 +416,7 @@ const char KX_TouchSensor::GetHitObjectList_doc[] =
"\tbut only those matching the property/material condition.\n";
PyObject* KX_TouchSensor::PyGetHitObjectList()
{
- ShowDeprecationWarning("getHitObjectList()", "the objectHitList property");
+ ShowDeprecationWarning("getHitObjectList()", "the hitObjectList property");
/* to do: do Py_IncRef if the object is already known in Python */
/* otherwise, this leaks memory */ /* Edit, this seems ok and not to leak memory - Campbell */
return m_colliders->GetProxy();
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index 15ef653c1b2..476c63e89db 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -84,8 +84,9 @@ public:
virtual ~KX_TouchSensor();
virtual CValue* GetReplica();
+ virtual void ProcessReplica();
virtual void SynchronizeTransform();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual void Init();
virtual void ReParent(SCA_IObject* parent);
@@ -102,7 +103,8 @@ public:
// obj1 = sensor physical controller, obj2 = physical controller of second object
// return value = true if collision should be checked on pair of object
virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2) { return true; }
-
+ virtual bool BroadPhaseSensorFilterCollision(void*obj1,void*obj2);
+ virtual sensortype GetSensorType() { return ST_TOUCH; }
virtual bool IsPositiveTrigger() {
@@ -121,6 +123,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
//Deprecated ----->
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index fbf43de6cf4..5a50d0fb944 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -83,6 +83,10 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj,
// if so, store the initial local rotation
// this is needed to revert the effect of the parent inverse node (TBC)
m_parentlocalmat = m_parentobj->GetSGNode()->GetLocalOrientation();
+ // use registration mechanism rather than AddRef, it creates zombie objects
+ m_parentobj->RegisterActuator(this);
+ // GetParent did AddRef, undo here
+ m_parentobj->Release();
}
}
}
@@ -189,7 +193,7 @@ KX_TrackToActuator::~KX_TrackToActuator()
if (m_object)
m_object->UnregisterActuator(this);
if (m_parentobj)
- m_parentobj->Release();
+ m_parentobj->UnregisterActuator(this);
} /* end of destructor */
void KX_TrackToActuator::ProcessReplica()
@@ -198,7 +202,7 @@ void KX_TrackToActuator::ProcessReplica()
if (m_object)
m_object->RegisterActuator(this);
if (m_parentobj)
- m_parentobj->AddRef();
+ m_parentobj->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
@@ -211,6 +215,11 @@ bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj)
m_object = NULL;
return true;
}
+ if (clientobj == m_parentobj)
+ {
+ m_parentobj = NULL;
+ return true;
+ }
return false;
}
@@ -227,9 +236,9 @@ void KX_TrackToActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
void **h_parobj = (*obj_map)[m_parentobj];
if (h_parobj) {
if (m_parentobj)
- m_parentobj->Release();
+ m_parentobj->UnregisterActuator(this);
m_parentobj= (KX_GameObject*)(*h_parobj);
- m_parentobj->AddRef();
+ m_parentobj->RegisterActuator(this);
}
}
@@ -425,8 +434,13 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_TrackToActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_TrackToActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -490,7 +504,7 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT
KX_GameObject *gameobj;
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_TrackToActuator"))
- return 1; // ConvertPythonToGameObject sets the error
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
if (actuator->m_object != NULL)
actuator->m_object->UnregisterActuator(actuator);
@@ -500,7 +514,7 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT
if (actuator->m_object)
actuator->m_object->RegisterActuator(actuator);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
@@ -509,6 +523,10 @@ PyObject* KX_TrackToActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_TrackToActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_TrackToActuator::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(SCA_IActuator);
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
index 99505f93cfe..c4cc2b1f062 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.h
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -61,8 +61,6 @@ class KX_TrackToActuator : public SCA_IActuator
virtual CValue* GetReplica() {
KX_TrackToActuator* replica = new KX_TrackToActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
};
@@ -73,6 +71,7 @@ class KX_TrackToActuator : public SCA_IActuator
/* Python part */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
/* These are used to get and set m_ob */
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index 1a6fb196db5..8146d04a878 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -273,8 +273,13 @@ PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* args)
//python specific stuff
PyTypeObject KX_VehicleWrapper::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_VehicleWrapper",
sizeof(PyObjectPlus_Proxy),
0,
@@ -303,32 +308,13 @@ PyObject* KX_VehicleWrapper::py_getattro(PyObject *attr)
py_getattro_up(PyObjectPlus);
}
-int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* pyobj)
-{
- /* TODO - strange setattr, needs updating */
- PyTypeObject* type = pyobj->ob_type;
- int result = 1;
-
- if (type == &PyList_Type)
- {
- result = 0;
- }
- if (type == &PyFloat_Type)
- {
- result = 0;
+PyObject* KX_VehicleWrapper::py_getattro_dict() {
+ py_getattro_dict_up(PyObjectPlus);
+}
- }
- if (type == &PyInt_Type)
- {
- result = 0;
- }
- if (type == &PyString_Type)
- {
- result = 0;
- }
- if (result)
- result = PyObjectPlus::py_setattro(attr,pyobj);
- return result;
+int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* value)
+{
+ py_setattro_up(PyObjectPlus);
};
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h
index de7fe75cfba..c2b5e3d9251 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.h
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h
@@ -13,6 +13,7 @@ class KX_VehicleWrapper : public PyObjectPlus
{
Py_Header;
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
std::vector<PHY_IMotionState*> m_motionStates;
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index 88f63334285..4b0ad083473 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -37,8 +37,13 @@
#include "KX_PyMath.h"
PyTypeObject KX_VertexProxy::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_VertexProxy",
sizeof(PyObjectPlus_Proxy),
0,
@@ -57,8 +62,8 @@ PyTypeObject KX_VertexProxy::Type = {
PyParentObject KX_VertexProxy::Parents[] = {
&KX_VertexProxy::Type,
- &SCA_IObject::Type,
&CValue::Type,
+ &PyObjectPlus::Type,
NULL
};
@@ -79,6 +84,7 @@ PyMethodDef KX_VertexProxy::Methods[] = {
};
PyAttributeDef KX_VertexProxy::Attributes[] = {
+ //KX_PYATTRIBUTE_TODO("DummyProps"),
KX_PYATTRIBUTE_DUMMY("x"),
KX_PYATTRIBUTE_DUMMY("y"),
@@ -156,7 +162,11 @@ KX_VertexProxy::py_getattro(PyObject *attr)
return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
}
- py_getattro_up(SCA_IObject);
+ py_getattro_up(CValue);
+}
+
+PyObject* KX_VertexProxy::py_getattro_dict() {
+ py_getattro_dict_up(CValue);
}
int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue)
@@ -312,7 +322,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue)
}
}
- return SCA_IObject::py_setattro(attr, pyvalue);
+ return CValue::py_setattro(attr, pyvalue);
}
KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex)
@@ -333,11 +343,9 @@ CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) {
STR_String sVertexName="vertex";
const STR_String & KX_VertexProxy::GetText() {return sVertexName;};
double KX_VertexProxy::GetNumber() { return -1;}
-STR_String KX_VertexProxy::GetName() { return sVertexName;}
-void KX_VertexProxy::SetName(STR_String) { };
+STR_String& KX_VertexProxy::GetName() { return sVertexName;}
+void KX_VertexProxy::SetName(const char *) { };
CValue* KX_VertexProxy::GetReplica() { return NULL;}
-void KX_VertexProxy::ReplicaSetName(STR_String) {};
-
// stuff for python integration
@@ -427,9 +435,10 @@ PyObject* KX_VertexProxy::PyGetUV2()
PyObject* KX_VertexProxy::PySetUV2(PyObject* args)
{
MT_Point2 vec;
- unsigned int unit=0;
+ unsigned int unit= RAS_TexVert::SECOND_UV;
+
PyObject* list= NULL;
- if(!PyArg_ParseTuple(args, "Oi:setUV2", &list, &unit))
+ if(!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
return NULL;
if (!PyVecTo(list, vec))
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index 67a15d96768..42db5fbc322 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -31,7 +31,7 @@
#include "SCA_IObject.h"
-class KX_VertexProxy : public SCA_IObject
+class KX_VertexProxy : public CValue
{
Py_Header;
protected:
@@ -47,14 +47,14 @@ public:
CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
const STR_String & GetText();
double GetNumber();
- STR_String GetName();
- void SetName(STR_String name); // Set the name of the value
- void ReplicaSetName(STR_String name);
+ STR_String& GetName();
+ void SetName(const char *name); // Set the name of the value
CValue* GetReplica();
// stuff for python integration
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
index ba59d0d3d47..d848065ad73 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
@@ -64,8 +64,6 @@ KX_VisibilityActuator::GetReplica(
{
KX_VisibilityActuator* replica = new KX_VisibilityActuator(*this);
replica->ProcessReplica();
- // this will copy properties and so on...
- CValue::AddDataToReplica(replica);
return replica;
}
@@ -94,8 +92,13 @@ KX_VisibilityActuator::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject KX_VisibilityActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"KX_VisibilityActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -133,8 +136,8 @@ KX_VisibilityActuator::Methods[] = {
PyAttributeDef KX_VisibilityActuator::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("visibility", KX_VisibilityActuator, m_visible),
- KX_PYATTRIBUTE_BOOL_RW("occlusion", KX_VisibilityActuator, m_occlusion),
- KX_PYATTRIBUTE_BOOL_RW("recursion", KX_VisibilityActuator, m_recursive),
+ KX_PYATTRIBUTE_BOOL_RW("useOcclusion", KX_VisibilityActuator, m_occlusion),
+ KX_PYATTRIBUTE_BOOL_RW("useRecursion", KX_VisibilityActuator, m_recursive),
{ NULL } //Sentinel
};
@@ -143,6 +146,10 @@ PyObject* KX_VisibilityActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* KX_VisibilityActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int KX_VisibilityActuator::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_IActuator);
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h
index 04633bce665..45aba50f645 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.h
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h
@@ -70,6 +70,7 @@ class KX_VisibilityActuator : public SCA_IActuator
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// Deprecated ----->
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 921aba9c11f..5ab15c9eab3 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -8,25 +8,28 @@ defs = ''
# XXX 2.5
# Mathutils C files.
-#sources.extend([\
-# '#source/blender/python/api2_2x/Mathutils.c',\
-# '#source/blender/python/api2_2x/constant.c',\
-# '#source/blender/python/api2_2x/euler.c',\
-# '#source/blender/python/api2_2x/gen_utils.c',\
-# '#source/blender/python/api2_2x/matrix.c',\
-# '#source/blender/python/api2_2x/point.c',\
-# '#source/blender/python/api2_2x/quat.c',\
-# '#source/blender/python/api2_2x/vector.c',\
-#])
-#
-#sources.extend([\
-# '#source/blender/python/api2_2x/bpy_internal_import.c'
-#])
-#
-#
-#sources.extend([\
-# '#source/blender/python/api2_2x/BGL.c'
-#])
+"""
+if not env['BF_PYTHON_VERSION'].startswith('3'):
+ # TODO - py3 support
+ sources.extend([\
+ '#source/blender/python/api2_2x/Mathutils.c',\
+ '#source/blender/python/api2_2x/Geometry.c',\
+ '#source/blender/python/api2_2x/euler.c',\
+ '#source/blender/python/api2_2x/matrix.c',\
+ '#source/blender/python/api2_2x/quat.c',\
+ '#source/blender/python/api2_2x/vector.c',\
+ '#source/blender/python/api2_2x/constant.c',\
+ ])
+
+ sources.extend([\
+ '#source/blender/python/api2_2x/BGL.c'
+ ])
+
+sources.extend([\
+ '#source/blender/python/api2_2x/bpy_internal_import.c'
+])
+"""
+
incs = '. #source/blender/python/api2_2x' # Only for Mathutils! and bpy_internal_import.h, be very careful