[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16567] trunk/blender/source: Fix for bug #4192: game engine armatures that are dynamically added

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Sep 17 03:30:38 CEST 2008


Revision: 16567
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16567
Author:   blendix
Date:     2008-09-17 03:29:54 +0200 (Wed, 17 Sep 2008)

Log Message:
-----------
Fix for bug #4192: game engine armatures that are dynamically added
but don't have an action got the pose of already added armatures, even
though they're not related. This also fixes an issue where the armature
in Blender would end up in the pose from the game after ESC, removes
unneeded copies made during armature evaluation, and also solves the
constraint copying hack.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_action.h
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp
    trunk/blender/source/gameengine/Converter/BL_ArmatureObject.cpp
    trunk/blender/source/gameengine/Converter/BL_ArmatureObject.h
    trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp
    trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp

Modified: trunk/blender/source/blender/blenkernel/BKE_action.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_action.h	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/blender/blenkernel/BKE_action.h	2008-09-17 01:29:54 UTC (rev 16567)
@@ -163,6 +163,10 @@
 /* write values returned by extract_ipochannels_from_action, returns the number of value written */
 int execute_ipochannels(ListBase *lb);
 
+/* functions used by the game engine */
+void game_copy_pose(struct bPose **dst, struct bPose *src);
+void game_free_pose(struct bPose *pose);
+
 #ifdef __cplusplus
 };
 #endif

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/blender/blenkernel/intern/action.c	2008-09-17 01:29:54 UTC (rev 16567)
@@ -62,6 +62,7 @@
 
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
 
 #include "nla.h"
 
@@ -340,6 +341,60 @@
 	}
 }
 
+void game_copy_pose(bPose **dst, bPose *src)
+{
+	bPose *out;
+	bPoseChannel *pchan, *outpchan;
+	GHash *ghash;
+	
+	/* the game engine copies the current armature pose and then swaps
+	 * the object pose pointer. this makes it possible to change poses
+	 * without affecting the original blender data. */
+
+	if (!src) {
+		*dst=NULL;
+		return;
+	}
+	else if (*dst==src) {
+		printf("copy_pose source and target are the same\n");
+		*dst=NULL;
+		return;
+	}
+	
+	out= MEM_dupallocN(src);
+	out->agroups.first= out->agroups.last= NULL;
+	duplicatelist(&out->chanbase, &src->chanbase);
+
+	/* remap pointers */
+	ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+	pchan= src->chanbase.first;
+	outpchan= out->chanbase.first;
+	for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
+		BLI_ghash_insert(ghash, pchan, outpchan);
+
+	for (pchan=out->chanbase.first; pchan; pchan=pchan->next) {
+		pchan->parent= BLI_ghash_lookup(ghash, pchan->parent);
+		pchan->child= BLI_ghash_lookup(ghash, pchan->child);
+		pchan->path= NULL;
+	}
+
+	BLI_ghash_free(ghash, NULL, NULL);
+	
+	*dst=out;
+}
+
+void game_free_pose(bPose *pose)
+{
+	if (pose) {
+		/* we don't free constraints, those are owned by the original pose */
+		if(pose->chanbase.first)
+			BLI_freelistN(&pose->chanbase);
+		
+		MEM_freeN(pose);
+	}
+}
+
 static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
 {
 	bConstraint *pcon, *con;

Modified: trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp	2008-09-17 01:29:54 UTC (rev 16567)
@@ -59,11 +59,11 @@
 BL_ActionActuator::~BL_ActionActuator()
 {
 	if (m_pose)
-		free_pose(m_pose);
+		game_free_pose(m_pose);
 	if (m_userpose)
-		free_pose(m_userpose);
+		game_free_pose(m_userpose);
 	if (m_blendpose)
-		free_pose(m_blendpose);
+		game_free_pose(m_blendpose);
 }
 
 void BL_ActionActuator::ProcessReplica(){

Modified: trunk/blender/source/gameengine/Converter/BL_ArmatureObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ArmatureObject.cpp	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/gameengine/Converter/BL_ArmatureObject.cpp	2008-09-17 01:29:54 UTC (rev 16567)
@@ -45,7 +45,6 @@
 #include <config.h>
 #endif
 
-
 BL_ArmatureObject::BL_ArmatureObject(
 				void* sgReplicationInfo, 
 				SG_Callbacks callbacks, 
@@ -65,7 +64,7 @@
 	 * the original pose before calling into blender functions, to deal with
 	 * replica's or other objects using the same blender object */
 	m_pose = NULL;
-	copy_pose(&m_pose, m_objArma->pose, 1 /* copy_constraint_channels_hack */);
+	game_copy_pose(&m_pose, m_objArma->pose);
 }
 
 CValue* BL_ArmatureObject::GetReplica()
@@ -84,32 +83,30 @@
 	KX_GameObject::ProcessReplica(replica);
 
 	replica->m_pose = NULL;
-	copy_pose(&replica->m_pose, m_pose, 1 /* copy_constraint_channels_hack */);
+	game_copy_pose(&replica->m_pose, m_pose);
 }
 
 BL_ArmatureObject::~BL_ArmatureObject()
 {
 	if (m_pose)
-		free_pose(m_pose);
+		game_free_pose(m_pose);
 }
 
-bool BL_ArmatureObject::VerifyPose()
+void BL_ArmatureObject::ApplyPose()
 {
+	m_armpose = m_objArma->pose;
+	m_objArma->pose = m_pose;
+
 	if(m_lastapplyframe != m_lastframe) {
-		extract_pose_from_pose(m_objArma->pose, m_pose);
 		where_is_pose(m_objArma);
 		m_lastapplyframe = m_lastframe;
-		extract_pose_from_pose(m_pose, m_objArma->pose);
-		return false;
 	}
-	else
-		return true;
 }
 
-void BL_ArmatureObject::ApplyPose()
+void BL_ArmatureObject::RestorePose()
 {
-	if(VerifyPose())
-		extract_pose_from_pose(m_objArma->pose, m_pose);
+	m_objArma->pose = m_armpose;
+	m_armpose = NULL;
 }
 
 void BL_ArmatureObject::SetPose(bPose *pose)
@@ -164,8 +161,7 @@
 			a crash and memory leakage when 
 			&BL_ActionActuator::m_pose is freed
 		*/
-		int copy_constraint_channels_hack = 1;
-		copy_pose(pose, m_pose, copy_constraint_channels_hack);
+		game_copy_pose(pose, m_pose);
 	}
 	else {
 		if (*pose == m_pose)
@@ -181,17 +177,10 @@
 	/* 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) {
-		// must duplicate the constraints too otherwise we have corruption in free_pose_channels()
-		// because it will free the blender constraints. 
-		// Ideally, blender should rememeber that the constraints were not copied so that
-		// free_pose_channels() would not free them.
-		copy_pose(pose, m_pose, 1);
-	}
-	else {
+	if (!*pose)
+		game_copy_pose(pose, m_pose);
+	else
 		extract_pose_from_pose(*pose, m_pose);
-	}
-
 }
 
 short BL_ArmatureObject::GetActivePriority()
@@ -210,13 +199,11 @@
 
 	ApplyPose();
 	pchan = get_pose_channel(m_objArma->pose, bone->name);
-
-	if(pchan) {
+	if(pchan)
 		matrix.setValue(&pchan->pose_mat[0][0]);
-		return true;
-	}
+	RestorePose();
 
-	return false;
+	return (pchan != NULL);
 }
 
 float BL_ArmatureObject::GetBoneLength(Bone* bone) const

Modified: trunk/blender/source/gameengine/Converter/BL_ArmatureObject.h
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ArmatureObject.h	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/gameengine/Converter/BL_ArmatureObject.h	2008-09-17 01:29:54 UTC (rev 16567)
@@ -61,7 +61,7 @@
 	void SetPose (struct bPose *pose);
 
 	void ApplyPose();
-	bool VerifyPose();
+	void RestorePose();
 
 	bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
 	
@@ -82,6 +82,7 @@
 	Object				*m_objArma;
 	struct bArmature	*m_armature;
 	struct bPose		*m_pose;
+	struct bPose		*m_armpose;
 	struct bPose		*m_framePose;
 	double	m_lastframe;
 	class BL_ActionActuator *m_activeAct;

Modified: trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/gameengine/Converter/BL_ShapeDeformer.cpp	2008-09-17 01:29:54 UTC (rev 16567)
@@ -109,6 +109,7 @@
 		vector<IpoCurve*>::iterator it;
 		void *poin;
 		int type;
+
 		// the shape drivers use the bone matrix as input. Must 
 		// update the matrix now
 		m_armobj->ApplyPose();
@@ -121,7 +122,10 @@
 			if (poin) 
 				write_ipo_poin(poin, type, icu->curval);
 		}
+
 		ForceUpdate();
+		m_armobj->RestorePose();
+
 		return true;
 	}
 	return false;

Modified: trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/gameengine/Converter/BL_SkinDeformer.cpp	2008-09-17 01:29:54 UTC (rev 16567)
@@ -197,6 +197,8 @@
 		/* Update the current frame */
 		m_lastArmaUpdate=m_armobj->GetLastFrame();
 
+		m_armobj->RestorePose();
+
 		/* indicate that the m_transverts and normals are up to date */
 		return true;
 	}

Modified: trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
===================================================================
--- trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp	2008-09-16 23:23:33 UTC (rev 16566)
+++ trunk/blender/source/gameengine/GamePlayer/ghost/GPG_Application.cpp	2008-09-17 01:29:54 UTC (rev 16567)
@@ -139,7 +139,7 @@
 GPG_Application::~GPG_Application(void)
 {
     if(m_pyGlobalDictString) {
-		delete m_pyGlobalDictString;
+		delete [] m_pyGlobalDictString;
 		m_pyGlobalDictString = 0;
 		m_pyGlobalDictString_Length = 0;
 	}
@@ -729,7 +729,7 @@
 	// m_pyGlobalDictString so we can restore after python has stopped
 	// and started between .blend file loads.
 	if(m_pyGlobalDictString) {
-		delete m_pyGlobalDictString;
+		delete [] m_pyGlobalDictString;
 		m_pyGlobalDictString = 0;
 	}
 





More information about the Bf-blender-cvs mailing list