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:
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp70
-rw-r--r--source/gameengine/Ketsji/BL_Action.h19
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.cpp42
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.h15
-rw-r--r--source/gameengine/Ketsji/KX_CharacterWrapper.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h10
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp147
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h30
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h5
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp27
-rw-r--r--source/gameengine/Ketsji/KX_RayCast.h27
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp60
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h1
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SteeringActuator.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_WorldInfo.cpp70
-rw-r--r--source/gameengine/Ketsji/KX_WorldInfo.h8
-rw-r--r--source/gameengine/Ketsji/SConscript3
28 files changed, 390 insertions, 235 deletions
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index 9bae119107e..5889f5ed412 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -56,6 +56,15 @@ extern "C" {
#include "BKE_library.h"
#include "BKE_global.h"
+#include "BLI_threads.h" // for lock
+
+/* Lock to solve animation thread issues.
+ * A spin lock is better than a mutex in case of short wait
+ * because spin lock stop the thread by a loop contrary to mutex
+ * which switch all memory, process.
+ */
+static SpinLock BL_ActionLock;
+
BL_Action::BL_Action(class KX_GameObject* gameobj)
:
m_action(NULL),
@@ -65,8 +74,7 @@ BL_Action::BL_Action(class KX_GameObject* gameobj)
m_obj(gameobj),
m_startframe(0.f),
m_endframe(0.f),
- m_endtime(0.f),
- m_localtime(0.f),
+ m_localframe(0.f),
m_blendin(0.f),
m_blendframe(0.f),
m_blendstart(0.f),
@@ -252,12 +260,11 @@ bool BL_Action::Play(const char* name,
// Now that we have an action, we have something we can play
m_starttime = -1.f; // We get the start time on our first update
- m_startframe = m_localtime = start;
+ m_startframe = m_localframe = start;
m_endframe = end;
m_blendin = blendin;
m_playmode = play_mode;
m_blendmode = blend_mode;
- m_endtime = 0.f;
m_blendframe = 0.f;
m_blendstart = 0.f;
m_speed = playback_speed;
@@ -268,11 +275,6 @@ bool BL_Action::Play(const char* name,
return true;
}
-void BL_Action::Stop()
-{
- m_done = true;
-}
-
bool BL_Action::IsDone()
{
return m_done;
@@ -298,7 +300,19 @@ bAction *BL_Action::GetAction()
float BL_Action::GetFrame()
{
- return m_localtime;
+ return m_localframe;
+}
+
+const char *BL_Action::GetName()
+{
+ if (m_action != NULL) {
+ return m_action->id.name + 2;
+ }
+ else {
+ return "";
+ }
+
+
}
void BL_Action::SetFrame(float frame)
@@ -309,7 +323,7 @@ void BL_Action::SetFrame(float frame)
else if (frame > max(m_startframe, m_endframe))
frame = max(m_startframe, m_endframe);
- m_localtime = frame;
+ m_localframe = frame;
m_calc_localtime = false;
}
@@ -331,12 +345,12 @@ void BL_Action::SetLocalTime(float curtime)
if (m_endframe < m_startframe)
dt = -dt;
- m_localtime = m_startframe + dt;
+ m_localframe = m_startframe + dt;
}
void BL_Action::ResetStartTime(float curtime)
{
- float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime;
+ float dt = (m_localframe > m_startframe) ? m_localframe - m_startframe : m_startframe - m_localframe;
m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
SetLocalTime(curtime);
@@ -384,7 +398,7 @@ void BL_Action::Update(float curtime)
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
- // Grab the start time here so we don't end up with a negative m_localtime when
+ // Grab the start time here so we don't end up with a negative m_localframe when
// suspending and resuming scenes.
if (m_starttime < 0)
m_starttime = curtime;
@@ -398,16 +412,16 @@ void BL_Action::Update(float curtime)
}
// Handle wrap around
- if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe)) {
+ if (m_localframe < min(m_startframe, m_endframe) || m_localframe > max(m_startframe, m_endframe)) {
switch (m_playmode) {
case ACT_MODE_PLAY:
// Clamp
- m_localtime = m_endframe;
+ m_localframe = m_endframe;
m_done = true;
break;
case ACT_MODE_LOOP:
// Put the time back to the beginning
- m_localtime = m_startframe;
+ m_localframe = m_startframe;
m_starttime = curtime;
break;
case ACT_MODE_PING_PONG:
@@ -430,7 +444,7 @@ void BL_Action::Update(float curtime)
obj->GetPose(&m_blendpose);
// Extract the pose from the action
- obj->SetPoseByAction(m_tmpaction, m_localtime);
+ obj->SetPoseByAction(m_tmpaction, m_localframe);
// Handle blending between armature actions
if (m_blendin && m_blendframe<m_blendin)
@@ -464,7 +478,7 @@ void BL_Action::Update(float curtime)
PointerRNA ptrrna;
RNA_id_pointer_create(&key->id, &ptrrna);
- animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localtime);
+ animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localframe);
// Handle blending between shape actions
if (m_blendin && m_blendframe < m_blendin)
@@ -494,15 +508,23 @@ void BL_Action::Update(float curtime)
}
}
- // This isn't thread-safe, so we move it into it's own function for now
- //m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_lock(&BL_ActionLock);
+ /* This function is not thread safe because of recursive scene graph transform
+ * updates on children. e.g: If an object and one of its children is animated,
+ * the both can write transform at the same time. A thread lock avoid problems. */
+ m_obj->UpdateIPO(m_localframe, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_unlock(&BL_ActionLock);
if (m_done)
ClearControllerList();
}
-void BL_Action::UpdateIPOs()
+void BL_Action::InitLock()
+{
+ BLI_spin_init(&BL_ActionLock);
+}
+
+void BL_Action::EndLock()
{
- if (!m_done)
- m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_end(&BL_ActionLock);
}
diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h
index dd1cd1f69ff..f41b2ef9460 100644
--- a/source/gameengine/Ketsji/BL_Action.h
+++ b/source/gameengine/Ketsji/BL_Action.h
@@ -48,9 +48,9 @@ private:
float m_startframe;
float m_endframe;
+ /// The current action frame.
+ float m_localframe;
float m_starttime;
- float m_endtime;
- float m_localtime;
float m_blendin;
float m_blendframe;
@@ -94,10 +94,6 @@ public:
float playback_speed,
short blend_mode);
/**
- * Stop playing the action
- */
- void Stop();
- /**
* Whether or not the action is still playing
*/
bool IsDone();
@@ -105,13 +101,11 @@ public:
* Update the action's frame, etc.
*/
void Update(float curtime);
- /**
- * Update object IPOs (note: not thread-safe!)
- */
- void UpdateIPOs();
// Accessors
float GetFrame();
+ const char *GetName();
+
struct bAction *GetAction();
// Mutators
@@ -142,6 +136,11 @@ public:
ACT_IPOFLAG_CHILD = 8,
};
+ /// Initialize a lock for animation thread issues.
+ static void InitLock();
+ /// Finalize a lock for animation thread issues.
+ static void EndLock();
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_Action")
#endif
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
index 975f9ea6da8..491be035d66 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.cpp
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -53,19 +53,17 @@ BL_Action *BL_ActionManager::GetAction(short layer)
return (it != m_layers.end()) ? it->second : 0;
}
-BL_Action* BL_ActionManager::AddAction(short layer)
+float BL_ActionManager::GetActionFrame(short layer)
{
- BL_Action *action = new BL_Action(m_obj);
- m_layers[layer] = action;
+ BL_Action *action = GetAction(layer);
- return action;
+ return action ? action->GetFrame() : 0.f;
}
-float BL_ActionManager::GetActionFrame(short layer)
+const char *BL_ActionManager::GetActionName(short layer)
{
BL_Action *action = GetAction(layer);
-
- return action ? action->GetFrame() : 0.f;
+ return action ? action->GetName() : "";
}
void BL_ActionManager::SetActionFrame(short layer, float frame)
@@ -110,8 +108,10 @@ bool BL_ActionManager::PlayAction(const char* name,
{
// Only this method will create layer if non-existent
BL_Action *action = GetAction(layer);
- if (!action)
- action = AddAction(layer);
+ if (!action) {
+ action = new BL_Action(m_obj);
+ m_layers[layer] = action;
+ }
// Disable layer blending on the first layer
if (layer == 0) layer_weight = -1.f;
@@ -123,7 +123,10 @@ void BL_ActionManager::StopAction(short layer)
{
BL_Action *action = GetAction(layer);
- if (action) action->Stop();
+ if (action) {
+ m_layers.erase(layer);
+ delete action;
+ }
}
void BL_ActionManager::RemoveTaggedActions()
@@ -152,25 +155,10 @@ void BL_ActionManager::Update(float curtime)
m_prevUpdate = curtime;
BL_ActionMap::iterator it;
- for (it = m_layers.begin(); it != m_layers.end(); )
+ for (it = m_layers.begin(); it != m_layers.end(); ++it)
{
- if (it->second->IsDone()) {
- delete it->second;
- m_layers.erase(it++);
- }
- else {
+ if (!it->second->IsDone()) {
it->second->Update(curtime);
- ++it;
}
}
}
-
-void BL_ActionManager::UpdateIPOs()
-{
- BL_ActionMap::iterator it;
- for (it = m_layers.begin(); it != m_layers.end(); ++it)
- {
- if (!it->second->IsDone())
- it->second->UpdateIPOs();
- }
-}
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
index 00e536655c7..69c6d611df0 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.h
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -59,11 +59,6 @@ private:
*/
BL_Action* GetAction(short layer);
- /**
- * Add new action with given layer
- */
- BL_Action* AddAction(short layer);
-
public:
BL_ActionManager(class KX_GameObject* obj);
~BL_ActionManager();
@@ -85,6 +80,11 @@ public:
float GetActionFrame(short layer);
/**
+ * Gets the name of the current action
+ */
+ const char *GetActionName(short layer);
+
+ /**
* Sets the current frame of an action
*/
void SetActionFrame(short layer, float frame);
@@ -124,11 +124,6 @@ public:
*/
void Update(float);
- /**
- * Update object IPOs (note: not thread-safe!)
- */
- void UpdateIPOs();
-
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_ActionManager")
#endif
diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
index fdf4fa01b03..44f06a9f1eb 100644
--- a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
@@ -25,6 +25,7 @@
#include "KX_CharacterWrapper.h"
#include "PHY_ICharacter.h"
#include "KX_PyMath.h"
+#include "BLI_utildefines.h"
KX_CharacterWrapper::KX_CharacterWrapper(PHY_ICharacter* character) :
PyObjectPlus(),
@@ -116,7 +117,9 @@ int KX_CharacterWrapper::pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE
return PY_SET_ATTR_FAIL;
}
- self->m_character->SetMaxJumps((int)param);
+ CLAMP(param, 0, 255);
+
+ self->m_character->SetMaxJumps(param);
return PY_SET_ATTR_SUCCESS;
}
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index e07660cef72..fecd60eb212 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -117,7 +117,7 @@ KX_ConstraintActuator::~KX_ConstraintActuator()
// there's nothing to be done here, really....
} /* end of destructor */
-bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
+bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data))
{
m_hitObject = client->m_gameobject;
@@ -153,7 +153,7 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *resu
/* This function is used to pre-filter the object before casting the ray on them.
* This is useful for "X-Ray" option when we want to see "through" unwanted object.
*/
-bool KX_ConstraintActuator::NeedRayCast(KX_ClientObjectInfo *client)
+bool KX_ConstraintActuator::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data))
{
if (client->m_type > KX_ClientObjectInfo::ACTOR)
{
@@ -347,7 +347,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
spc = parent->GetPhysicsController();
}
}
- KX_RayCast::Callback<KX_ConstraintActuator> callback(this,dynamic_cast<PHY_IPhysicsController*>(spc));
+ KX_RayCast::Callback<KX_ConstraintActuator, void> callback(this,dynamic_cast<PHY_IPhysicsController*>(spc));
result = KX_RayCast::RayTest(pe, position, topoint, callback);
if (result) {
MT_Vector3 newnormal = callback.m_hitNormal;
@@ -459,7 +459,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
m_hitObject = NULL;
// distance of Fh area is stored in m_minimum
MT_Point3 topoint = position + (m_minimumBound+spc->GetRadius()) * direction;
- KX_RayCast::Callback<KX_ConstraintActuator> callback(this, spc);
+ KX_RayCast::Callback<KX_ConstraintActuator, void> callback(this, spc);
result = KX_RayCast::RayTest(pe, position, topoint, callback);
// we expect a hit object
if (!m_hitObject)
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index edb2e5e0180..af617655d5e 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -37,6 +37,8 @@
#include "MT_Vector3.h"
#include "KX_ClientObjectInfo.h"
+#include "BLI_utildefines.h"
+
class KX_RayCast;
class KX_GameObject;
@@ -113,9 +115,11 @@ protected:
KX_ACT_CONSTRAINT_LOCAL = 1024,
KX_ACT_CONSTRAINT_DOROTFH = 2048
};
- bool IsValidMode(KX_CONSTRAINTTYPE m);
- bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
- bool NeedRayCast(KX_ClientObjectInfo*);
+ bool IsValidMode(KX_CONSTRAINTTYPE m);
+ /// \see KX_RayCast
+ bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data));
+ /// \see KX_RayCast
+ bool NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data));
KX_ConstraintActuator(SCA_IObject* gameobj,
int posDamptime,
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index a23af680104..f1bd253f8b3 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -41,6 +41,7 @@
#include "KX_Scene.h"
#include "KX_KetsjiEngine.h"
#include "KX_PythonInit.h" /* for config load/saving */
+#include "RAS_ICanvas.h"
#include <stdio.h>
#include <stdlib.h>
@@ -204,6 +205,17 @@ bool KX_GameActuator::Update()
break;
#endif // WITH_PYTHON
}
+ case KX_GAME_SCREENSHOT:
+ {
+ RAS_ICanvas *canvas = m_ketsjiengine->GetCanvas();
+ if (canvas) {
+ canvas->MakeScreenShot(m_filename);
+ }
+ else {
+ printf("KX_GAME_SCREENSHOT error: Rasterizer not available");
+ }
+ break;
+ }
default:
; /* do nothing? this is an internal error !!! */
}
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
index 0c1c4f0c277..57472836bb2 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.h
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -59,6 +59,7 @@ protected:
KX_GAME_QUIT,
KX_GAME_SAVECFG,
KX_GAME_LOADCFG,
+ KX_GAME_SCREENSHOT,
KX_GAME_MAX
};
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 536670dde1a..1dbcf14af89 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -47,7 +47,6 @@
#include "KX_MeshProxy.h"
#include "KX_PolyProxy.h"
#include <stdio.h> // printf
-#include <climits> // USHRT_MAX
#include "SG_Controller.h"
#include "PHY_IGraphicController.h"
#include "SG_Node.h"
@@ -108,8 +107,6 @@ KX_GameObject::KX_GameObject(
m_bOccluder(false),
m_pPhysicsController(NULL),
m_pGraphicController(NULL),
- m_xray(false),
- m_pHitObject(NULL),
m_pObstacleSimulation(NULL),
m_pInstanceObjects(NULL),
m_pDupliGroupObject(NULL),
@@ -484,14 +481,14 @@ void KX_GameObject::UpdateActionManager(float curtime)
GetActionManager()->Update(curtime);
}
-void KX_GameObject::UpdateActionIPOs()
+float KX_GameObject::GetActionFrame(short layer)
{
- GetActionManager()->UpdateIPOs();
+ return GetActionManager()->GetActionFrame(layer);
}
-float KX_GameObject::GetActionFrame(short layer)
+const char *KX_GameObject::GetActionName(short layer)
{
- return GetActionManager()->GetActionFrame(layer);
+ return GetActionManager()->GetActionName(layer);
}
void KX_GameObject::SetActionFrame(short layer, float frame)
@@ -947,6 +944,9 @@ void KX_GameObject::InitIPO(bool ipo_as_force,
void KX_GameObject::UpdateIPO(float curframetime,
bool recurse)
{
+ /* This function shouldn't call BL_Action::Update, not even indirectly,
+ * as it will cause deadlock due to the lock in BL_Action::Update. */
+
// just the 'normal' update procedure.
GetSGNode()->SetSimulatedTime(curframetime,recurse);
GetSGNode()->UpdateWorldData(curframetime);
@@ -1611,7 +1611,8 @@ void KX_GameObject::Resume(void)
{
if (m_suspended) {
SCA_IObject::Resume();
- if (GetPhysicsController())
+ // Child objects must be static, so we block changing to dynamic
+ if (GetPhysicsController() && !GetParent())
GetPhysicsController()->RestoreDynamics();
m_suspended = false;
@@ -1669,10 +1670,11 @@ CListValue* KX_GameObject::GetChildrenRecursive()
KX_Scene* KX_GameObject::GetScene()
{
SG_Node* node = this->GetSGNode();
- if (node == NULL)
- // this happens for object in non active layers, rely on static scene then
- return KX_GetActiveScene();
- return static_cast<KX_Scene*>(node->GetSGClientInfo());
+ if (node == NULL) {
+ // this happens for object in non active layers, rely on static scene then
+ return KX_GetActiveScene();
+ }
+ return static_cast<KX_Scene*>(node->GetSGClientInfo());
}
/* ---------------------------------------------------------------------
@@ -1957,6 +1959,7 @@ PyMethodDef KX_GameObject::Methods[] = {
KX_PYMETHODTABLE_KEYWORDS(KX_GameObject, playAction),
KX_PYMETHODTABLE(KX_GameObject, stopAction),
KX_PYMETHODTABLE(KX_GameObject, getActionFrame),
+ KX_PYMETHODTABLE(KX_GameObject, getActionName),
KX_PYMETHODTABLE(KX_GameObject, setActionFrame),
KX_PYMETHODTABLE(KX_GameObject, isPlayingAction),
@@ -2353,8 +2356,8 @@ int KX_GameObject::pyattr_set_collisionGroup(void *self_v, const KX_PYATTRIBUTE_
return PY_SET_ATTR_FAIL;
}
- if (val < 0 || val > USHRT_MAX) {
- PyErr_Format(PyExc_AttributeError, "gameOb.collisionGroup = int: KX_GameObject, expected a int bit field between 0 and %i", USHRT_MAX);
+ if (val == 0 || val & ~((1 << OB_MAX_COL_MASKS) - 1)) {
+ PyErr_Format(PyExc_AttributeError, "gameOb.collisionGroup = int: KX_GameObject, expected a int bit field, 0 < group < %i", (1 << OB_MAX_COL_MASKS));
return PY_SET_ATTR_FAIL;
}
@@ -2378,8 +2381,8 @@ int KX_GameObject::pyattr_set_collisionMask(void *self_v, const KX_PYATTRIBUTE_D
return PY_SET_ATTR_FAIL;
}
- if (val < 0 || val > USHRT_MAX) {
- PyErr_Format(PyExc_AttributeError, "gameOb.collisionMask = int: KX_GameObject, expected a int bit field between 0 and %i", USHRT_MAX);
+ if (val == 0 || val & ~((1 << OB_MAX_COL_MASKS) - 1)) {
+ PyErr_Format(PyExc_AttributeError, "gameOb.collisionMask = int: KX_GameObject, expected a int bit field, 0 < mask < %i", (1 << OB_MAX_COL_MASKS));
return PY_SET_ATTR_FAIL;
}
@@ -3431,7 +3434,8 @@ PyObject *KX_GameObject::PySuspendDynamics(PyObject *args)
PyObject *KX_GameObject::PyRestoreDynamics()
{
- if (GetPhysicsController())
+ // Child objects must be static, so we block changing to dynamic
+ if (GetPhysicsController() && !GetParent())
GetPhysicsController()->RestoreDynamics();
Py_RETURN_NONE;
}
@@ -3563,15 +3567,32 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo,
return returnValue;
}
-bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
+struct KX_GameObject::RayCastData
+{
+ RayCastData(STR_String prop, bool xray, short mask)
+ :m_prop(prop),
+ m_xray(xray),
+ m_mask(mask),
+ m_hitObject(NULL)
+ {
+ }
+
+ STR_String m_prop;
+ bool m_xray;
+ unsigned short m_mask;
+ KX_GameObject *m_hitObject;
+};
+
+bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, RayCastData *rayData)
{
KX_GameObject* hitKXObj = client->m_gameobject;
-
+
// if X-ray option is selected, the unwnted objects were not tested, so get here only with true hit
// if not, all objects were tested and the front one may not be the correct one.
- if (m_xray || m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
+ if ((rayData->m_xray || rayData->m_prop.Length() == 0 || hitKXObj->GetProperty(rayData->m_prop) != NULL) &&
+ hitKXObj->GetUserCollisionGroup() & rayData->m_mask)
{
- m_pHitObject = hitKXObj;
+ rayData->m_hitObject = hitKXObj;
return true;
}
// return true to stop RayCast::RayTest from looping, the above test was decisive
@@ -3582,10 +3603,10 @@ bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void
/* this function is used to pre-filter the object before casting the ray on them.
* This is useful for "X-Ray" option when we want to see "through" unwanted object.
*/
-bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client)
+bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client, RayCastData *rayData)
{
KX_GameObject* hitKXObj = client->m_gameobject;
-
+
if (client->m_type > KX_ClientObjectInfo::ACTOR)
{
// Unknown type of object, skip it.
@@ -3596,7 +3617,8 @@ bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client)
// if X-Ray option is selected, skip object that don't match the criteria as we see through them
// if not, test all objects because we don't know yet which one will be on front
- if (!m_xray || m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
+ if ((!rayData->m_xray || rayData->m_prop.Length() == 0 || hitKXObj->GetProperty(rayData->m_prop) != NULL) &&
+ hitKXObj->GetUserCollisionGroup() & rayData->m_mask)
{
return true;
}
@@ -3643,17 +3665,11 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
KX_GameObject *parent = GetParent();
if (!spc && parent)
spc = parent->GetPhysicsController();
-
- m_pHitObject = NULL;
- if (propName)
- m_testPropName = propName;
- else
- m_testPropName.SetLength(0);
- KX_RayCast::Callback<KX_GameObject> callback(this,spc);
- KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
- if (m_pHitObject)
- return m_pHitObject->GetProxy();
+ RayCastData rayData(propName, false, (1 << OB_MAX_COL_MASKS) - 1);
+ KX_RayCast::Callback<KX_GameObject, RayCastData> callback(this, spc, &rayData);
+ if (KX_RayCast::RayTest(pe, fromPoint, toPoint, callback))
+ return rayData.m_hitObject->GetProxy();
Py_RETURN_NONE;
}
@@ -3704,7 +3720,7 @@ static PyObject *none_tuple_5()
}
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) or 4-tuple (object,hit,normal,polygon,hituv) of contact point with object within dist that matches prop.\n"
+ "rayCast(to,from,dist,prop,face,xray,poly,mask): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) or 4-tuple (object,hit,normal,polygon,hituv) of contact point with object within dist that matches prop.\n"
" If no hit, return (None,None,None) or (None,None,None,None) or (None,None,None,None,None).\n"
" to = 3-tuple or object reference for destination of ray (if object, use center of object)\n"
" from = 3-tuple or object reference for origin of ray (if object, use center of object)\n"
@@ -3718,6 +3734,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
" 2=>return value is a 5-tuple, the 4th element is the KX_PolyProxy object\n"
" and the 5th element is the vector of UV coordinates at the hit point of the None if there is no UV mapping\n"
" If 0 or omitted, return value is a 3-tuple\n"
+" mask = collision mask: the collision mask that ray can hit, 0 < mask < 65536\n"
"Note: The object on which you call this method matters: the ray will ignore it.\n"
" prop and xray option interact as follow:\n"
" prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray\n"
@@ -3733,8 +3750,9 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
char *propName = NULL;
KX_GameObject *other;
int face=0, xray=0, poly=0;
+ int mask = (1 << OB_MAX_COL_MASKS) - 1;
- if (!PyArg_ParseTuple(args,"O|Ofsiii:rayCast", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) {
+ if (!PyArg_ParseTuple(args,"O|Ofsiiii:rayCast", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly, &mask)) {
return NULL; // Python sets a simple error
}
@@ -3764,11 +3782,16 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
fromPoint = other->NodeGetWorldPosition();
} else
{
- PyErr_SetString(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly): KX_GameObject, the second optional argument to rayCast must be a vector or a KX_GameObject");
+ PyErr_SetString(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly,mask): KX_GameObject, the second optional argument to rayCast must be a vector or a KX_GameObject");
return NULL;
}
}
-
+
+ if (mask == 0 || mask & ~((1 << OB_MAX_COL_MASKS) - 1)) {
+ PyErr_Format(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly,mask): KX_GameObject, mask argument to rayCast must be a int bitfield, 0 < mask < %i", (1 << OB_MAX_COL_MASKS));
+ return NULL;
+ }
+
if (dist != 0.0f) {
MT_Vector3 toDir = toPoint-fromPoint;
if (MT_fuzzyZero(toDir.length2())) {
@@ -3787,22 +3810,16 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
KX_GameObject *parent = GetParent();
if (!spc && parent)
spc = parent->GetPhysicsController();
-
- m_pHitObject = NULL;
- if (propName)
- m_testPropName = propName;
- else
- m_testPropName.SetLength(0);
- m_xray = xray;
+
// to get the hit results
- KX_RayCast::Callback<KX_GameObject> callback(this,spc,NULL,face,(poly==2));
- KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
+ RayCastData rayData(propName, xray, mask);
+ KX_RayCast::Callback<KX_GameObject, RayCastData> callback(this, spc, &rayData, face, (poly == 2));
- if (m_pHitObject)
+ if (KX_RayCast::RayTest(pe, fromPoint, toPoint, callback))
{
PyObject *returnValue = (poly == 2) ? PyTuple_New(5) : (poly) ? PyTuple_New(4) : PyTuple_New(3);
if (returnValue) { // unlikely this would ever fail, if it does python sets an error
- PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->GetProxy());
+ PyTuple_SET_ITEM(returnValue, 0, rayData.m_hitObject->GetProxy());
PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(callback.m_hitPoint));
PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(callback.m_hitNormal));
if (poly)
@@ -3921,7 +3938,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, stopAction,
"stopAction(layer=0)\n"
"Stop playing the action on the given layer\n")
{
- short layer=0;
+ short layer = 0;
if (!PyArg_ParseTuple(args, "|h:stopAction", &layer))
return NULL;
@@ -3937,7 +3954,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getActionFrame,
"getActionFrame(layer=0)\n"
"Gets the current frame of the action playing in the supplied layer\n")
{
- short layer=0;
+ short layer = 0;
if (!PyArg_ParseTuple(args, "|h:getActionFrame", &layer))
return NULL;
@@ -3947,11 +3964,25 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getActionFrame,
return PyFloat_FromDouble(GetActionFrame(layer));
}
+KX_PYMETHODDEF_DOC(KX_GameObject, getActionName,
+ "getActionName(layer=0)\n"
+ "Gets the name of the current action playing in the supplied layer\n")
+{
+ short layer = 0;
+
+ if (!PyArg_ParseTuple(args, "|h:getActionName", &layer))
+ return NULL;
+
+ layer_check(layer, "getActionName");
+
+ return PyUnicode_FromString(GetActionName(layer));
+}
+
KX_PYMETHODDEF_DOC(KX_GameObject, setActionFrame,
"setActionFrame(frame, layer=0)\n"
"Set the current frame of the action playing in the supplied layer\n")
{
- short layer=0;
+ short layer = 0;
float frame;
if (!PyArg_ParseTuple(args, "f|h:setActionFrame", &frame, &layer))
@@ -3968,7 +3999,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, isPlayingAction,
"isPlayingAction(layer=0)\n"
"Checks to see if there is an action playing in the given layer\n")
{
- short layer=0;
+ short layer = 0;
if (!PyArg_ParseTuple(args, "|h:isPlayingAction", &layer))
return NULL;
@@ -4066,11 +4097,11 @@ bool ConvertPythonToGameObject(PyObject *value, KX_GameObject **object, bool py_
}
}
- if ( PyObject_TypeCheck(value, &KX_GameObject::Type) ||
- PyObject_TypeCheck(value, &KX_LightObject::Type) ||
- PyObject_TypeCheck(value, &KX_Camera::Type) ||
- PyObject_TypeCheck(value, &KX_FontObject::Type) ||
- PyObject_TypeCheck(value, &KX_NavMeshObject::Type))
+ if (PyObject_TypeCheck(value, &KX_GameObject::Type) ||
+ PyObject_TypeCheck(value, &KX_LightObject::Type) ||
+ PyObject_TypeCheck(value, &KX_Camera::Type) ||
+ PyObject_TypeCheck(value, &KX_FontObject::Type) ||
+ PyObject_TypeCheck(value, &KX_NavMeshObject::Type))
{
*object = static_cast<KX_GameObject*>BGE_PROXY_REF(value);
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 99c8a6d718b..c2c455dab6a 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -111,9 +111,6 @@ protected:
PHY_IPhysicsController* m_pPhysicsController;
PHY_IGraphicController* m_pGraphicController;
- STR_String m_testPropName;
- bool m_xray;
- KX_GameObject* m_pHitObject;
SG_Node* m_pSGNode;
@@ -131,10 +128,19 @@ protected:
BL_ActionManager* GetActionManager();
bool m_bRecordAnimation;
+
public:
bool m_isDeformable;
/**
+ * KX_GameObject custom infos for ray cast, it contains property name,
+ * collision mask, xray flag and hited object.
+ * This structure is created during ray cast and passed as argument
+ * "data" to functions KX_GameObject::NeedRayCast and KX_GameObject::RayHit.
+ */
+ struct RayCastData;
+
+ /**
* Helper function for modules that can't include KX_ClientObjectInfo.h
*/
static KX_GameObject* GetClientObject(KX_ClientObjectInfo* info);
@@ -277,6 +283,11 @@ public:
float GetActionFrame(short layer);
/**
+ * Gets the name of the current action
+ */
+ const char *GetActionName(short layer);
+
+ /**
* Sets the current frame of an action
*/
void SetActionFrame(short layer, float frame);
@@ -316,12 +327,6 @@ public:
*/
void UpdateActionManager(float curtime);
- /**
- * Have the action manager update IPOs
- * note: not thread-safe!
- */
- void UpdateActionIPOs();
-
/*********************************
* End Animation API
*********************************/
@@ -656,8 +661,10 @@ public:
return (m_pSGNode && m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsVertexParent());
}
- bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
- bool NeedRayCast(KX_ClientObjectInfo* client);
+ /// \see KX_RayCast
+ bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, RayCastData *rayData);
+ /// \see KX_RayCast
+ bool NeedRayCast(KX_ClientObjectInfo *client, RayCastData *rayData);
/**
@@ -1037,6 +1044,7 @@ public:
KX_PYMETHOD_DOC(KX_GameObject, playAction);
KX_PYMETHOD_DOC(KX_GameObject, stopAction);
KX_PYMETHOD_DOC(KX_GameObject, getActionFrame);
+ KX_PYMETHOD_DOC(KX_GameObject, getActionName);
KX_PYMETHOD_DOC(KX_GameObject, setActionFrame);
KX_PYMETHOD_DOC(KX_GameObject, isPlayingAction);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index c7cf556a2d3..c6e5f734c16 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -75,6 +75,8 @@
#include "KX_NavMeshObject.h"
+#include "BL_Action.h" // For managing action lock.
+
#define DEFAULT_LOGIC_TIC_RATE 60.0
//#define DEFAULT_PHYSICS_TIC_RATE 60.0
@@ -181,6 +183,8 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
#endif
m_taskscheduler = BLI_task_scheduler_create(TASK_SCHEDULER_AUTO_THREADS);
+
+ BL_Action::InitLock();
}
@@ -200,6 +204,8 @@ KX_KetsjiEngine::~KX_KetsjiEngine()
if (m_taskscheduler)
BLI_task_scheduler_free(m_taskscheduler);
+
+ BL_Action::EndLock();
}
@@ -1019,6 +1025,10 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect
void KX_KetsjiEngine::UpdateAnimations(KX_Scene *scene)
{
+ if (scene->IsSuspended()) {
+ return;
+ }
+
// Handle the animations independently of the logic time step
if (GetRestrictAnimationFPS()) {
double anim_timestep = 1.0 / KX_GetActiveScene()->GetAnimationFPS();
@@ -1750,6 +1760,16 @@ void KX_KetsjiEngine::SetAnimRecordMode(bool animation_record, int startFrame)
m_currentFrame = startFrame;
}
+int KX_KetsjiEngine::getAnimRecordFrame() const
+{
+ return m_currentFrame;
+}
+
+void KX_KetsjiEngine::setAnimRecordFrame(int framenr)
+{
+ m_currentFrame = framenr;
+}
+
bool KX_KetsjiEngine::GetUseFixedTime(void) const
{
return m_bFixedTime;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index b4bd8a64f78..04e09c8db15 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -225,6 +225,9 @@ public:
KX_ISceneConverter* GetSceneConverter() { return m_sceneconverter; }
void SetAnimRecordMode(bool animation_record, int startFrame);
+ int getAnimRecordFrame() const;
+ void setAnimRecordFrame(int framenr);
+
RAS_IRasterizer* GetRasterizer() { return m_rasterizer; }
RAS_ICanvas* GetCanvas() { return m_canvas; }
SCA_IInputDevice* GetKeyboardDevice() { return m_keyboarddevice; }
@@ -257,7 +260,7 @@ public:
void ConvertAndAddScene(const STR_String& scenename,bool overlay);
void RemoveScene(const STR_String& scenename);
- bool ReplaceScene(const STR_String& oldscene,const STR_String& newscene);
+ bool ReplaceScene(const STR_String& oldscene,const STR_String& newscene);
void SuspendScene(const STR_String& scenename);
void ResumeScene(const STR_String& scenename);
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 46f27e1a2df..db2cb1fdcfd 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -144,7 +144,7 @@ bool KX_MouseFocusSensor::Evaluate()
return result;
}
-bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *result, void * const data)
+bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *result, void *UNUSED(data))
{
KX_GameObject* hitKXObj = client_info->m_gameobject;
@@ -198,7 +198,7 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *r
/* this function is used to pre-filter the object before casting the ray on them.
* This is useful for "X-Ray" option when we want to see "through" unwanted object.
*/
-bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo* client)
+bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data))
{
KX_GameObject *hitKXObj = client->m_gameobject;
@@ -356,7 +356,7 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment();
// get UV mapping
- KX_RayCast::Callback<KX_MouseFocusSensor> callback(this,physics_controller,NULL,false,true);
+ KX_RayCast::Callback<KX_MouseFocusSensor, void> callback(this,physics_controller,NULL,false,true);
KX_RayCast::RayTest(physics_environment, m_prevSourcePoint, m_prevTargetPoint, callback);
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 0c7c8ab676a..dd9295b2ff4 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -35,6 +35,8 @@
#include "SCA_MouseSensor.h"
+#include "BLI_utildefines.h"
+
class KX_RayCast;
/**
@@ -90,8 +92,10 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
return result;
};
- bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
- bool NeedRayCast(KX_ClientObjectInfo* client);
+ /// \see KX_RayCast
+ bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data));
+ /// \see KX_RayCast
+ bool NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data));
const MT_Point3& RaySource() const;
const MT_Point3& RayTarget() const;
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 5877df5f289..a0084662490 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -583,7 +583,7 @@ static PyObject *gPyRemoveConstraint(PyObject *self,
{
if (PHY_GetActiveEnvironment())
{
- PHY_GetActiveEnvironment()->RemoveConstraint(constraintid);
+ PHY_GetActiveEnvironment()->RemoveConstraintById(constraintid);
}
}
else {
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 4cb632ed739..37768c75ba5 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -37,9 +37,6 @@
#endif
#ifdef WITH_PYTHON
-# ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-# endif
# ifdef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
# endif
@@ -526,6 +523,27 @@ static PyObject *gPyGetPhysicsTicRate(PyObject *)
return PyFloat_FromDouble(PHY_GetActiveEnvironment()->GetFixedTimeStep());
}
+static PyObject *gPySetAnimRecordFrame(PyObject *, PyObject *args)
+{
+ int anim_record_frame;
+
+ if (!PyArg_ParseTuple(args, "i:setAnimRecordFrame", &anim_record_frame))
+ return NULL;
+
+ if (anim_record_frame < 0 && (U.flag & USER_NONEGFRAMES)) {
+ PyErr_Format(PyExc_ValueError, "Frame number must be non-negative (was %i).", anim_record_frame);
+ return NULL;
+ }
+
+ gp_KetsjiEngine->setAnimRecordFrame(anim_record_frame);
+ Py_RETURN_NONE;
+}
+
+static PyObject *gPyGetAnimRecordFrame(PyObject *)
+{
+ return PyLong_FromLong(gp_KetsjiEngine->getAnimRecordFrame());
+}
+
static PyObject *gPyGetAverageFrameRate(PyObject *)
{
return PyFloat_FromDouble(KX_KetsjiEngine::GetAverageFrameRate());
@@ -887,6 +905,8 @@ static struct PyMethodDef game_methods[] = {
{"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (const char *)"Sets the logic tic rate"},
{"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (const char *)"Gets the physics tic rate"},
{"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, (const char *)"Sets the physics tic rate"},
+ {"getAnimRecordFrame", (PyCFunction) gPyGetAnimRecordFrame, METH_NOARGS, (const char *)"Gets the current frame number used for animation recording"},
+ {"setAnimRecordFrame", (PyCFunction) gPySetAnimRecordFrame, METH_VARARGS, (const char *)"Sets the current frame number used for animation recording"},
{"getExitKey", (PyCFunction) gPyGetExitKey, METH_NOARGS, (const char *)"Gets the key used to exit the game engine"},
{"setExitKey", (PyCFunction) gPySetExitKey, METH_VARARGS, (const char *)"Sets the key used to exit the game engine"},
{"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"},
@@ -1781,6 +1801,7 @@ PyMODINIT_FUNC initGameLogicPythonBinding()
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);
+ KX_MACRO_addTypesToDict(d, KX_GAME_SCREENSHOT, KX_GameActuator::KX_GAME_SCREENSHOT);
/* Scene Actuator Modes */
KX_MACRO_addTypesToDict(d, KX_SCENE_RESTART, KX_SceneActuator::KX_SCENE_RESTART);
diff --git a/source/gameengine/Ketsji/KX_RayCast.h b/source/gameengine/Ketsji/KX_RayCast.h
index e47ac676eb1..c977fb8f385 100644
--- a/source/gameengine/Ketsji/KX_RayCast.h
+++ b/source/gameengine/Ketsji/KX_RayCast.h
@@ -44,12 +44,15 @@ struct KX_ClientObjectInfo;
/**
* Defines a function for doing a ray cast.
*
- * eg KX_RayCast::RayTest(ignore_physics_controller, physics_environment, frompoint, topoint, result_point, result_normal, KX_RayCast::Callback<KX_MyClass>(this, data)
+ * eg KX_RayCast::RayTest(ignore_physics_controller, physics_environment, frompoint, topoint, result_point, result_normal, KX_RayCast::Callback<MyClass, MyDataClass>(this, data)
*
- * Calls myclass->RayHit(client, hit_point, hit_normal, data) for all client
+ * Calls myclass->NeedRayCast(client, data) for all client in environment
+ * and myclass->RayHit(client, hit_point, hit_normal, data) for all client
* between frompoint and topoint
*
- * myclass->RayHit should return true to end the raycast, false to ignore the current client.
+ * myclass->NeedRayCast should return true to ray test the current client.
+ *
+ * myclass->RayHit should return true to end the raycast, false to ignore the current client and to continue.
*
* Returns true if a client was accepted, false if nothing found.
*/
@@ -80,10 +83,10 @@ public:
/**
* Callback wrapper.
*
- * Construct with KX_RayCast::Callback<MyClass>(this, data)
+ * Construct with KX_RayCast::Callback<MyClass, MyDataClass>(this, data)
* and pass to KX_RayCast::RayTest
*/
- template<class T> class Callback;
+ template<class T, class dataT> class Callback;
/// Public interface.
/// Implement bool RayHit in your class to receive ray callbacks.
@@ -99,12 +102,18 @@ public:
#endif
};
-template<class T> class KX_RayCast::Callback : public KX_RayCast
+template<class T, class dataT>
+class KX_RayCast::Callback : public KX_RayCast
{
T *self;
- void *data;
+ /**
+ * Some user info passed as argument in constructor.
+ * It contains all info needed to check client in NeedRayCast
+ * and RayHit.
+ */
+ dataT *data;
public:
- Callback(T *_self, PHY_IPhysicsController* controller=NULL, void *_data = NULL, bool faceNormal=false, bool faceUV=false)
+ Callback(T *_self, PHY_IPhysicsController *controller = NULL, dataT *_data = NULL, bool faceNormal = false, bool faceUV = false)
: KX_RayCast(controller, faceNormal, faceUV),
self(_self),
data(_data)
@@ -127,7 +136,7 @@ public:
MT_assert(info && "Physics controller with no client object info");
return false;
}
- return self->NeedRayCast(info);
+ return self->NeedRayCast(info, data);
}
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index c97d233a67b..4ffb5f332db 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -107,7 +107,7 @@ bool KX_RaySensor::IsPositiveTrigger()
return result;
}
-bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
+bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data))
{
KX_GameObject* hitKXObj = client->m_gameobject;
@@ -158,7 +158,7 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void
/* this function is used to pre-filter the object before casting the ray on them.
* This is useful for "X-Ray" option when we want to see "through" unwanted object.
*/
-bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client)
+bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data))
{
KX_GameObject *hitKXObj = client->m_gameobject;
@@ -282,7 +282,7 @@ bool KX_RaySensor::Evaluate()
PHY_IPhysicsEnvironment* physics_environment = this->m_scene->GetPhysicsEnvironment();
- KX_RayCast::Callback<KX_RaySensor> callback(this, spc);
+ KX_RayCast::Callback<KX_RaySensor, void> callback(this, spc);
KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback);
/* now pass this result to some controller */
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index 4604863a233..1901bb04f86 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -38,6 +38,8 @@
#include "SCA_IScene.h" /* only for scene replace */
#include "KX_Scene.h" /* only for scene replace */
+#include "BLI_utildefines.h"
+
struct KX_ClientObjectInfo;
class KX_RayCast;
@@ -74,8 +76,10 @@ public:
virtual bool IsPositiveTrigger();
virtual void Init();
- bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
- bool NeedRayCast(KX_ClientObjectInfo* client);
+ /// \see KX_RayCast
+ bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data));
+ /// \see KX_RayCast
+ bool NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data));
virtual void Replace_IScene(SCA_IScene *val)
{
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
index e02eca3db63..96e1cc29de3 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
@@ -121,7 +121,9 @@ bool KX_SCA_DynamicActuator::Update()
switch (m_dyn_operation)
{
case 0:
- controller->RestoreDynamics();
+ // Child objects must be static, so we block changing to dynamic
+ if (!obj->GetParent())
+ controller->RestoreDynamics();
break;
case 1:
controller->SuspendDynamics();
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index fd709a87def..16d1fdd6ea2 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -584,6 +584,10 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
newctrl->SetNewClientInfo(newobj->getClientInfo());
newobj->SetPhysicsController(newctrl, newobj->IsDynamic());
newctrl->PostProcessReplica(motionstate, parentctrl);
+
+ // Child objects must be static
+ if (parent)
+ newctrl->SuspendDynamics();
}
return newobj;
@@ -1002,17 +1006,28 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
//newobj->SetSGNode(0);
}
+void KX_Scene::RemoveDupliGroup(class CValue *gameobj)
+{
+ KX_GameObject *newobj = (KX_GameObject *) gameobj;
+
+ if (newobj->IsDupliGroup()) {
+ for (int i = 0; i < newobj->GetInstanceObjects()->GetCount(); i++) {
+ CValue *obj = newobj->GetInstanceObjects()->GetValue(i);
+ DelayedRemoveObject(obj);
+ }
+ }
+}
+
void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
{
- //KX_GameObject* newobj = (KX_GameObject*) gameobj;
+ RemoveDupliGroup(gameobj);
+
if (!m_euthanasyobjects->SearchValue(gameobj))
{
m_euthanasyobjects->Add(gameobj->AddRef());
- }
+ }
}
-
-
int KX_Scene::NewRemoveObject(class CValue* gameobj)
{
int ret;
@@ -1674,10 +1689,6 @@ void KX_Scene::UpdateAnimations(double curtime)
BLI_task_pool_work_and_wait(pool);
BLI_task_pool_free(pool);
-
- for (int i=0; i<m_animatedlist->GetCount(); ++i) {
- ((KX_GameObject*)m_animatedlist->GetValue(i))->UpdateActionIPOs();
- }
}
void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
@@ -2015,8 +2026,12 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
to->GetLogicManager()->RegisterGameObjectName(gameobj->GetName(), gameobj);
to->GetLogicManager()->RegisterGameObj(gameobj->GetBlenderObject(), gameobj);
- for (int i=0; i<gameobj->GetMeshCount(); ++i)
- to->GetLogicManager()->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), gameobj->GetBlenderObject());
+ for (int i = 0; i < gameobj->GetMeshCount(); ++i) {
+ RAS_MeshObject *meshobj = gameobj->GetMesh(i);
+ // Register the mesh object by name and blender object.
+ to->GetLogicManager()->RegisterGameMeshName(meshobj->GetName(), gameobj->GetBlenderObject());
+ to->GetLogicManager()->RegisterMeshName(meshobj->GetName(), meshobj);
+ }
}
bool KX_Scene::MergeScene(KX_Scene *other)
@@ -2060,6 +2075,28 @@ bool KX_Scene::MergeScene(KX_Scene *other)
MergeScene_GameObject(gameobj, this, other);
}
+ if (env) {
+ env->MergeEnvironment(env_other);
+ CListValue *otherObjects = other->GetObjectList();
+
+ // List of all physics objects to merge (needed by ReplicateConstraints).
+ std::vector<KX_GameObject *> physicsObjects;
+ for (unsigned int i = 0; i < otherObjects->GetCount(); ++i) {
+ KX_GameObject *gameobj = (KX_GameObject *)otherObjects->GetValue(i);
+ if (gameobj->GetPhysicsController()) {
+ physicsObjects.push_back(gameobj);
+ }
+ }
+
+ for (unsigned int i = 0; i < physicsObjects.size(); ++i) {
+ KX_GameObject *gameobj = physicsObjects[i];
+ // Replicate all constraints in the right physics environment.
+ gameobj->GetPhysicsController()->ReplicateConstraints(gameobj, physicsObjects);
+ gameobj->ClearConstraints();
+ }
+ }
+
+
GetTempObjectList()->MergeList(other->GetTempObjectList());
other->GetTempObjectList()->ReleaseAndRemoveAll();
@@ -2075,9 +2112,6 @@ bool KX_Scene::MergeScene(KX_Scene *other)
GetLightList()->MergeList(other->GetLightList());
other->GetLightList()->ReleaseAndRemoveAll();
- if (env)
- env->MergeEnvironment(env_other);
-
/* move materials across, assume they both use the same scene-converters
* Do this after lights are merged so materials can use the lights in shaders
*/
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 4f7ad98f30d..046ad25c09c 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -339,6 +339,7 @@ public:
void RemoveNodeDestructObject(SG_IObject* node,
CValue* gameobj);
void RemoveObject(CValue* gameobj);
+ void RemoveDupliGroup(CValue *gameobj);
void DelayedRemoveObject(CValue* gameobj);
int NewRemoveObject(CValue* gameobj);
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 14f0598d088..f6f09dd3bda 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -65,7 +65,7 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
KX_SOUNDACT_TYPE type)//,
: SCA_IActuator(gameobj, KX_ACT_SOUND)
{
- m_sound = AUD_Sound_copy(sound);
+ m_sound = sound ? AUD_Sound_copy(sound) : NULL;
m_handle = NULL;
m_volume = volume;
m_pitch = pitch;
@@ -122,7 +122,9 @@ void KX_SoundActuator::play()
break;
}
- //m_handle = AUD_Device_play(BKE_sound_get_device(), sound, false);
+ AUD_Device* device = AUD_Device_getCurrent();
+ m_handle = AUD_Device_play(device, sound, false);
+ AUD_Device_free(device);
// in case of pingpong, we have to free the sound
if(sound != m_sound)
diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp
index 83597f9125a..cd2cd2bae0b 100644
--- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp
@@ -561,7 +561,7 @@ PyAttributeDef KX_SteeringActuator::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec),
KX_PYATTRIBUTE_SHORT_RW("facingMode", 0, 6, true, KX_SteeringActuator, m_facingMode),
KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod),
- KX_PYATTRIBUTE_BOOL_RW("lockZVelocity", KX_SteeringActuator, m_lockzvel),
+ KX_PYATTRIBUTE_BOOL_RW("lockZVelocity", KX_SteeringActuator, m_lockzvel),
{ NULL } //Sentinel
};
@@ -610,8 +610,7 @@ int KX_SteeringActuator::pyattr_set_navmesh(void *self, const struct KX_PYATTRIB
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SteeringActuator"))
return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
- if (dynamic_cast<KX_NavMeshObject *>(gameobj) == NULL)
- {
+ if (dynamic_cast<KX_NavMeshObject *>(gameobj) == NULL) {
PyErr_Format(PyExc_TypeError, "KX_NavMeshObject is expected");
return PY_SET_ATTR_FAIL;
}
diff --git a/source/gameengine/Ketsji/KX_WorldInfo.cpp b/source/gameengine/Ketsji/KX_WorldInfo.cpp
index 111d81cad2e..be8b1ce92fc 100644
--- a/source/gameengine/Ketsji/KX_WorldInfo.cpp
+++ b/source/gameengine/Ketsji/KX_WorldInfo.cpp
@@ -253,11 +253,11 @@ PyAttributeDef KX_WorldInfo::Attributes[] = {
/*----------------------mathutils callbacks ----------------------------*/
/* subtype */
-#define MATHUTILS_VEC_CB_MIST_COLOR 1
-#define MATHUTILS_VEC_CB_BACK_COLOR 2
-#define MATHUTILS_VEC_CB_AMBIENT_COLOR 3
+#define MATHUTILS_COL_CB_MIST_COLOR 1
+#define MATHUTILS_COL_CB_BACK_COLOR 2
+#define MATHUTILS_COL_CB_AMBIENT_COLOR 3
-static unsigned char mathutils_world_vector_cb_index = -1; /* index for our callbacks */
+static unsigned char mathutils_world_color_cb_index = -1; /* index for our callbacks */
static int mathutils_world_generic_check(BaseMathObject *bmo)
{
@@ -268,20 +268,20 @@ static int mathutils_world_generic_check(BaseMathObject *bmo)
return 0;
}
-static int mathutils_world_vector_get(BaseMathObject *bmo, int subtype)
+static int mathutils_world_color_get(BaseMathObject *bmo, int subtype)
{
KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
if (self == NULL)
return -1;
switch (subtype) {
- case MATHUTILS_VEC_CB_MIST_COLOR:
+ case MATHUTILS_COL_CB_MIST_COLOR:
copy_v3_v3(bmo->data, self->m_mistcolor);
break;
- case MATHUTILS_VEC_CB_BACK_COLOR:
+ case MATHUTILS_COL_CB_BACK_COLOR:
copy_v3_v3(bmo->data, self->m_backgroundcolor);
break;
- case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ case MATHUTILS_COL_CB_AMBIENT_COLOR:
copy_v3_v3(bmo->data, self->m_ambientcolor);
break;
default:
@@ -290,7 +290,7 @@ static int mathutils_world_vector_get(BaseMathObject *bmo, int subtype)
return 0;
}
-static int mathutils_world_vector_set(BaseMathObject *bmo, int subtype)
+static int mathutils_world_color_set(BaseMathObject *bmo, int subtype)
{
KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
@@ -298,13 +298,13 @@ static int mathutils_world_vector_set(BaseMathObject *bmo, int subtype)
return -1;
switch (subtype) {
- case MATHUTILS_VEC_CB_MIST_COLOR:
+ case MATHUTILS_COL_CB_MIST_COLOR:
self->setMistColor(bmo->data[0], bmo->data[1], bmo->data[2]);
break;
- case MATHUTILS_VEC_CB_BACK_COLOR:
+ case MATHUTILS_COL_CB_BACK_COLOR:
self->setBackColor(bmo->data[0], bmo->data[1], bmo->data[2]);
break;
- case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ case MATHUTILS_COL_CB_AMBIENT_COLOR:
self->setAmbientColor(bmo->data[0], bmo->data[1], bmo->data[2]);
break;
default:
@@ -313,7 +313,7 @@ static int mathutils_world_vector_set(BaseMathObject *bmo, int subtype)
return 0;
}
-static int mathutils_world_vector_get_index(BaseMathObject *bmo, int subtype, int index)
+static int mathutils_world_color_get_index(BaseMathObject *bmo, int subtype, int index)
{
KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
@@ -321,19 +321,19 @@ static int mathutils_world_vector_get_index(BaseMathObject *bmo, int subtype, in
return -1;
switch (subtype) {
- case MATHUTILS_VEC_CB_MIST_COLOR:
+ case MATHUTILS_COL_CB_MIST_COLOR:
{
const float *color = self->m_mistcolor;
bmo->data[index] = color[index];
}
break;
- case MATHUTILS_VEC_CB_BACK_COLOR:
+ case MATHUTILS_COL_CB_BACK_COLOR:
{
const float *color = self->m_backgroundcolor;
bmo->data[index] = color[index];
}
break;
- case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ case MATHUTILS_COL_CB_AMBIENT_COLOR:
{
const float *color = self->m_ambientcolor;
bmo->data[index] = color[index];
@@ -345,7 +345,7 @@ static int mathutils_world_vector_get_index(BaseMathObject *bmo, int subtype, in
return 0;
}
-static int mathutils_world_vector_set_index(BaseMathObject *bmo, int subtype, int index)
+static int mathutils_world_color_set_index(BaseMathObject *bmo, int subtype, int index)
{
KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
@@ -354,17 +354,17 @@ static int mathutils_world_vector_set_index(BaseMathObject *bmo, int subtype, in
float color[4];
switch (subtype) {
- case MATHUTILS_VEC_CB_MIST_COLOR:
+ case MATHUTILS_COL_CB_MIST_COLOR:
copy_v3_v3(color, self->m_mistcolor);
color[index] = bmo->data[index];
self->setMistColor(color[0], color[1], color[2]);
break;
- case MATHUTILS_VEC_CB_BACK_COLOR:
+ case MATHUTILS_COL_CB_BACK_COLOR:
copy_v3_v3(color, self->m_backgroundcolor);
color[index] = bmo->data[index];
self->setBackColor(color[0], color[1], color[2]);
break;
- case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ case MATHUTILS_COL_CB_AMBIENT_COLOR:
copy_v3_v3(color, self->m_ambientcolor);
color[index] = bmo->data[index];
self->setAmbientColor(color[0], color[1], color[2]);
@@ -375,18 +375,18 @@ static int mathutils_world_vector_set_index(BaseMathObject *bmo, int subtype, in
return 0;
}
-static Mathutils_Callback mathutils_world_vector_cb = {
+static Mathutils_Callback mathutils_world_color_cb = {
mathutils_world_generic_check,
- mathutils_world_vector_get,
- mathutils_world_vector_set,
- mathutils_world_vector_get_index,
- mathutils_world_vector_set_index
+ mathutils_world_color_get,
+ mathutils_world_color_set,
+ mathutils_world_color_get_index,
+ mathutils_world_color_set_index
};
void KX_WorldInfo_Mathutils_Callback_Init()
{
// register mathutils callbacks, ok to run more than once.
- mathutils_world_vector_cb_index = Mathutils_RegisterCallback(&mathutils_world_vector_cb);
+ mathutils_world_color_cb_index = Mathutils_RegisterCallback(&mathutils_world_color_cb);
}
#endif // USE_MATHUTILS
@@ -418,9 +418,9 @@ PyObject *KX_WorldInfo::pyattr_get_mist_typeconst(void *self_v, const KX_PYATTRI
PyObject *KX_WorldInfo::pyattr_get_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(
- BGE_PROXY_FROM_REF_BORROW(self_v), 3,
- mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_MIST_COLOR);
+ return Color_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v),
+ mathutils_world_color_cb_index, MATHUTILS_COL_CB_MIST_COLOR);
#else
KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
return PyObjectFrom(MT_Vector3(self->m_mistcolor));
@@ -444,9 +444,9 @@ PyObject *KX_WorldInfo::pyattr_get_back_color(void *self_v, const KX_PYATTRIBUTE
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(
- BGE_PROXY_FROM_REF_BORROW(self_v), 3,
- mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_BACK_COLOR);
+ return Color_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v),
+ mathutils_world_color_cb_index, MATHUTILS_COL_CB_BACK_COLOR);
#else
KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
return PyObjectFrom(MT_Vector3(self->m_backgroundcolor));
@@ -469,9 +469,9 @@ int KX_WorldInfo::pyattr_set_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *
PyObject *KX_WorldInfo::pyattr_get_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(
- BGE_PROXY_FROM_REF_BORROW(self_v), 3,
- mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_AMBIENT_COLOR);
+ return Color_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v),
+ mathutils_world_color_cb_index, MATHUTILS_COL_CB_AMBIENT_COLOR);
#else
KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
return PyObjectFrom(MT_Vector3(self->m_ambientcolor));
diff --git a/source/gameengine/Ketsji/KX_WorldInfo.h b/source/gameengine/Ketsji/KX_WorldInfo.h
index f2b37ec5587..b155faf2837 100644
--- a/source/gameengine/Ketsji/KX_WorldInfo.h
+++ b/source/gameengine/Ketsji/KX_WorldInfo.h
@@ -36,10 +36,6 @@
#include "KX_KetsjiEngine.h"
#include "EXP_PyObjectPlus.h"
-#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
-#endif
-
#ifdef USE_MATHUTILS
void KX_WorldInfo_Mathutils_Callback_Init(void);
#endif
@@ -104,10 +100,6 @@ public:
static int pyattr_set_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
virtual PyObject *py_repr(void);
#endif
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GE:KX_WorldInfo")
-#endif
};
#endif /* __KX_WORLDINFO_H__ */
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 5b2807d8172..d8dfd3d9bca 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -30,7 +30,8 @@ import sys
Import ('env')
sources = env.Glob('*.cpp')
-defs = env['BF_GL_DEFINITIONS']
+defs = []
+defs += env['BF_GL_DEFINITIONS']
incs = [
'.',