[Bf-blender-cvs] [fe05f97] master: BGE: Multi-threading animation updates and skinning.
Mitchell Stokes
noreply at git.blender.org
Mon Apr 7 01:46:23 CEST 2014
Commit: fe05f97841c0ee3e2a6e15f2252ad160fefc3509
Author: Mitchell Stokes
Date: Sun Apr 6 16:30:59 2014 -0700
https://developer.blender.org/rBfe05f97841c0ee3e2a6e15f2252ad160fefc3509
BGE: Multi-threading animation updates and skinning.
This required BL_ArmatureObject to have tighter control over armatures and poses.
Also, (Blender) armature objects are now copied instead of shared between
BL_ArmatureObjects to avoid race conditions. Also, due to the armature copy,
shape key drivers need a bit of extra fiddling to get the correct armature copy.
Initially OpenMP was used for threading, but then BLI_task was used due to being
less compiler dependent.
This commit also places time spent on skinning updates in the Animation
profiler category (was previously under the Rasterizer category).
===================================================================
M source/gameengine/Converter/BL_ActionActuator.cpp
M source/gameengine/Converter/BL_ActionActuator.h
M source/gameengine/Converter/BL_ArmatureActuator.cpp
M source/gameengine/Converter/BL_ArmatureObject.cpp
M source/gameengine/Converter/BL_ArmatureObject.h
M source/gameengine/Converter/BL_BlenderDataConversion.cpp
M source/gameengine/Converter/BL_ShapeDeformer.cpp
M source/gameengine/Converter/BL_ShapeDeformer.h
M source/gameengine/Converter/BL_SkinDeformer.cpp
M source/gameengine/Ketsji/BL_Action.cpp
M source/gameengine/Ketsji/BL_Action.h
M source/gameengine/Ketsji/KX_KetsjiEngine.cpp
M source/gameengine/Ketsji/KX_KetsjiEngine.h
M source/gameengine/Ketsji/KX_Scene.cpp
===================================================================
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index a289062..34d3684 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -93,9 +93,6 @@ BL_ActionActuator::BL_ActionActuator(SCA_IObject *gameobj,
m_priority(priority),
m_layer(layer),
m_ipo_flags(ipo_flags),
- m_pose(NULL),
- m_blendpose(NULL),
- m_userpose(NULL),
m_action(action),
m_propname(propname),
m_framepropname(framepropname)
@@ -106,20 +103,12 @@ BL_ActionActuator::BL_ActionActuator(SCA_IObject *gameobj,
BL_ActionActuator::~BL_ActionActuator()
{
- if (m_pose)
- game_free_pose(m_pose);
- if (m_userpose)
- game_free_pose(m_userpose);
- if (m_blendpose)
- game_free_pose(m_blendpose);
}
void BL_ActionActuator::ProcessReplica()
{
SCA_IActuator::ProcessReplica();
-
- m_pose = NULL;
- m_blendpose = NULL;
+
m_localtime=m_startframe;
m_lastUpdate=-1;
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index 4579a21..f488b0c 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -134,9 +134,6 @@ protected:
short m_priority;
short m_layer;
short m_ipo_flags;
- struct bPose* m_pose;
- struct bPose* m_blendpose;
- struct bPose* m_userpose;
struct bAction *m_action;
STR_String m_propname;
STR_String m_framepropname;
diff --git a/source/gameengine/Converter/BL_ArmatureActuator.cpp b/source/gameengine/Converter/BL_ArmatureActuator.cpp
index f0c4b3d..e38cb6e 100644
--- a/source/gameengine/Converter/BL_ArmatureActuator.cpp
+++ b/source/gameengine/Converter/BL_ArmatureActuator.cpp
@@ -155,7 +155,7 @@ bool BL_ArmatureActuator::Update(double curtime, bool frame)
switch (m_type) {
case ACT_ARM_RUN:
result = true;
- obj->SetActiveAction(NULL, 0, curtime);
+ obj->UpdateTimestep(curtime);
break;
case ACT_ARM_ENABLE:
if (m_constraint)
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index 619797a..3eb7829 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -42,7 +42,13 @@
#include "BIK_api.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_object.h"
#include "BKE_library.h"
+#include "BKE_global.h"
+
+extern "C" {
+#include "BKE_animsys.h"
+}
#include "BKE_constraint.h"
#include "CTR_Map.h"
@@ -53,6 +59,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_constraint_types.h"
+#include "RNA_access.h"
#include "KX_PythonSeq.h"
#include "KX_PythonInit.h"
#include "KX_KetsjiEngine.h"
@@ -70,7 +77,7 @@
* When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
* Blender objects and restore after the evaluation.
*/
-void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
+static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
{
bPose *out;
bPoseChannel *pchan, *outpchan;
@@ -85,7 +92,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
return;
}
else if (*dst==src) {
- printf("BKE_pose_copy_data source and target are the same\n");
+ printf("game_copy_pose source and target are the same\n");
*dst=NULL;
return;
}
@@ -142,7 +149,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
/* Only allowed for Poses with identical channels */
-void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
+static void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
{
bPoseChannel *dchan;
const bPoseChannel *schan;
@@ -202,23 +209,6 @@ void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
dst->ctime= src->ctime;
}
-void game_free_pose(bPose *pose)
-{
- if (pose) {
- /* free pose-channels and constraints */
- BKE_pose_channels_free(pose);
-
- /* free IK solver state */
- BIK_clear_data(pose);
-
- /* free IK solver param */
- if (pose->ikparam)
- MEM_freeN(pose->ikparam);
-
- MEM_freeN(pose);
- }
-}
-
BL_ArmatureObject::BL_ArmatureObject(
void* sgReplicationInfo,
SG_Callbacks callbacks,
@@ -229,26 +219,18 @@ BL_ArmatureObject::BL_ArmatureObject(
: KX_GameObject(sgReplicationInfo,callbacks),
m_controlledConstraints(),
m_poseChannels(),
- m_objArma(armature),
- m_framePose(NULL),
m_scene(scene), // maybe remove later. needed for BKE_pose_where_is
m_lastframe(0.0),
m_timestep(0.040),
- m_activeAct(NULL),
- m_activePriority(999),
m_vert_deform_type(vert_deform_type),
m_constraintNumber(0),
m_channelNumber(0),
m_lastapplyframe(0.0)
{
- m_armature = (bArmature *)armature->data;
-
- /* we make a copy of blender object's pose, and then always swap it with
- * the original pose before calling into blender functions, to deal with
- * replica's or other objects using the same blender object */
- m_pose = NULL;
- game_copy_pose(&m_pose, m_objArma->pose, 1);
- // store the original armature object matrix
+ m_origObjArma = armature; // Keep a copy of the original armature so we can fix drivers later
+ m_objArma = BKE_object_copy(armature);
+ m_objArma->data = BKE_armature_copy((bArmature *)armature->data);
+ m_pose = m_objArma->pose;
memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat));
}
@@ -262,10 +244,9 @@ BL_ArmatureObject::~BL_ArmatureObject()
while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) {
delete channel;
}
- if (m_pose)
- game_free_pose(m_pose);
- if (m_framePose)
- game_free_pose(m_framePose);
+
+ if (m_objArma)
+ BKE_libblock_free(G.main, m_objArma);
}
@@ -431,12 +412,12 @@ CValue* BL_ArmatureObject::GetReplica()
void BL_ArmatureObject::ProcessReplica()
{
- bPose *pose= m_pose;
KX_GameObject::ProcessReplica();
- m_pose = NULL;
- m_framePose = NULL;
- game_copy_pose(&m_pose, pose, 1);
+ bArmature* tmp = (bArmature*)m_objArma->data;
+ m_objArma = BKE_object_copy(m_objArma);
+ m_objArma->data = BKE_armature_copy(tmp);
+ m_pose = m_objArma->pose;
}
void BL_ArmatureObject::ReParentLogic()
@@ -506,48 +487,32 @@ void BL_ArmatureObject::SetPose(bPose *pose)
m_lastapplyframe = -1.0;
}
-bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority, double curtime)
+void BL_ArmatureObject::SetPoseByAction(bAction *action, float localtime)
+{
+ Object *arm = GetArmatureObject();
+
+ PointerRNA ptrrna;
+ RNA_id_pointer_create(&arm->id, &ptrrna);
+
+ animsys_evaluate_action(&ptrrna, action, NULL, localtime);
+}
+
+void BL_ArmatureObject::BlendInPose(bPose *blend_pose, float weight, short mode)
+{
+ game_blend_poses(m_pose, blend_pose, weight, mode);
+}
+
+bool BL_ArmatureObject::UpdateTimestep(double curtime)
{
if (curtime != m_lastframe) {
- m_activePriority = 9999;
// compute the timestep for the underlying IK algorithm
m_timestep = curtime-m_lastframe;
m_lastframe= curtime;
- m_activeAct = NULL;
- // remember the pose at the start of the frame
- GetPose(&m_framePose);
}
- if (act)
- {
- if (priority<=m_activePriority)
- {
- if (priority<m_activePriority) {
- // this action overwrites the previous ones, start from initial pose to cancel their effects
- SetPose(m_framePose);
- if (m_activeAct && (m_activeAct!=act))
- /* Reset the blend timer since this new action cancels the old one */
- m_activeAct->SetBlendTime(0.0);
- }
- m_activeAct = act;
- m_activePriority = priority;
- m_lastframe = curtime;
-
- return true;
- }
- else {
- act->SetBlendTime(0.0);
- return false;
- }
- }
return false;
}
-BL_ActionActuator * BL_ArmatureObject::GetActiveAction()
-{
- return m_activeAct;
-}
-
void BL_ArmatureObject::GetPose(bPose **pose)
{
/* If the caller supplies a null pose, create a new one. */
@@ -570,22 +535,6 @@ void BL_ArmatureObject::GetPose(bPose **pose)
}
}
-void BL_ArmatureObject::GetMRDPose(bPose **pose)
-{
- /* If the caller supplies a null pose, create a new one. */
- /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
-
- if (!*pose)
- game_copy_pose(pose, m_pose, 0);
- else
- extract_pose_from_pose(*pose, m_pose);
-}
-
-short BL_ArmatureObject::GetActivePriority()
-{
- return m_activePriority;
-}
-
double BL_ArmatureObject::GetLastFrame()
{
return m_lastframe;
@@ -671,7 +620,7 @@ KX_PYMETHODDEF_DOC_NOARGS(BL_ArmatureObject, update,
"This is automatically done if a KX_ArmatureActuator with mode run is active\n"
"or if an action is playing. This function is useful in other cases.\n")
{
- SetActiveAction(NULL, 0, KX_GetActiveEngine()->GetFrameTime());
+ UpdateTimestep(KX_GetActiveEngine()->GetFrameTime());
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h
index 8138835..691e73d 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.h
+++ b/source/gameengine/Converter/BL_ArmatureObject.h
@@ -55,14 +55,11 @@ class BL_ArmatureObject : public KX_GameObject
public:
double GetLastFrame ();
- short GetActivePriority();
virtual void ProcessReplica();
virtual void ReParentLogic();
virtual void Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map);
virtual bool UnlinkObject(SCA_IObject* clientobj);
- class BL_ActionActuator * GetActiveAction();
-
BL_ArmatureObject(
void* sgReplicationInfo,
SG_Callbacks callbacks,
@@ -73,21 +70,23 @@ public:
virtual ~BL_ArmatureObject();
virtual CValue* GetReplica();
- void GetMRDPose(struct bPose **pose);
void GetPose(struct bPose **pose);
void SetPose (struct bPose *pose);
struct bPose *GetOrigPose() {return m_pose;} // never edit this, only for accessing names
void ApplyPose();
+ void SetPoseByAction(struct bAction* action, float localtime);
+ void BlendInPose(struct bPose *blend_pose, float weight, short mode);
void RestorePose();
- bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
+ bool UpdateTimestep(double curtime);
- struct bArmature *GetArmature() { return m_armature; }
- const struct
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list