[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14342] trunk/blender: Commit patch #8799: Realtime SetParent function in the BGE

Benoit Bolsee benoit.bolsee at online.be
Sun Apr 6 20:30:52 CEST 2008


Revision: 14342
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14342
Author:   ben2610
Date:     2008-04-06 20:30:52 +0200 (Sun, 06 Apr 2008)

Log Message:
-----------
Commit patch #8799: Realtime SetParent function in the BGE

This patch consists in new KX_GameObject::SetParent() and KX_GameObject::RemoveParent() functions to create and destroy parent relation during game. These functions are accessible through python and through a new actuator KX_ParentActuator. Function documentation in PyDoc.
The object keeps its orientation, position and scale when it is parented but will further rotate, move and scale with its parent from that point on. When the parent relation is broken, the object keeps the orientation, position and scale it had at that time.
The function has no effect if any of the X/Y/Z scale of the object or its new parent are below Epsilon.

Modified Paths:
--------------
    trunk/blender/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
    trunk/blender/source/blender/blenkernel/intern/sca.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_actuator_types.h
    trunk/blender/source/blender/src/buttons_logic.c
    trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
    trunk/blender/source/gameengine/PyDoc/KX_GameObject.py

Added Paths:
-----------
    trunk/blender/source/gameengine/Ketsji/KX_ParentActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_ParentActuator.h
    trunk/blender/source/gameengine/PyDoc/KX_ParentActuator.py

Modified: trunk/blender/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
===================================================================
--- trunk/blender/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj	2008-04-06 18:30:52 UTC (rev 14342)
@@ -454,6 +454,9 @@
 					RelativePath="..\..\..\source\gameengine\Ketsji\KX_ObjectActuator.cpp">
 				</File>
 				<File
+					RelativePath="..\..\..\source\gameengine\Ketsji\KX_ParentActuator.cpp">
+				</File>
+				<File
 					RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.cpp">
 				</File>
 				<File
@@ -669,6 +672,9 @@
 					RelativePath="..\..\..\source\gameengine\Ketsji\KX_ObjectActuator.h">
 				</File>
 				<File
+					RelativePath="..\..\..\source\gameengine\Ketsji\KX_ParentActuator.h">
+				</File>
+				<File
 					RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.h">
 				</File>
 				<File

Modified: trunk/blender/source/blender/blenkernel/intern/sca.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/sca.c	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/blender/blenkernel/intern/sca.c	2008-04-06 18:30:52 UTC (rev 14342)
@@ -464,6 +464,9 @@
     case ACT_2DFILTER:
         act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
         break;
+    case ACT_PARENT:
+        act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
+        break;
 	default:
 		; /* this is very severe... I cannot make any memory for this        */
 		/* logic brick...                                                    */

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2008-04-06 18:30:52 UTC (rev 14342)
@@ -2982,6 +2982,10 @@
 					bTwoDFilterActuator *_2dfa = act->data; 
 					_2dfa->text= newlibadr(fd, ob->id.lib, _2dfa->text);
 				}
+				else if(act->type==ACT_PARENT) {
+					bParentActuator *parenta = act->data; 
+					parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
+				}
 				act= act->next;
 			}
 

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c	2008-04-06 18:30:52 UTC (rev 14342)
@@ -738,6 +738,9 @@
 		case ACT_2DFILTER:
 			writestruct(wd, DATA, "bTwoDFilterActuator", 1, act->data);
 			break;
+		case ACT_PARENT:
+			writestruct(wd, DATA, "bParentActuator", 1, act->data);
+			break;
 		default:
 			; /* error: don't know how to write this file */
 		}

Modified: trunk/blender/source/blender/makesdna/DNA_actuator_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_actuator_types.h	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/blender/makesdna/DNA_actuator_types.h	2008-04-06 18:30:52 UTC (rev 14342)
@@ -205,6 +205,12 @@
 	struct Text *text;
 }bTwoDFilterActuator;
 
+typedef struct bParentActuator {
+	char pad[4];
+	int type;
+	struct Object *ob;
+} bParentActuator;
+
 typedef struct bActuator {
 	struct bActuator *next, *prev, *mynew;
 	short type;
@@ -274,6 +280,7 @@
 #define ACT_GAME		17
 #define ACT_VISIBILITY          18
 #define ACT_2DFILTER	19
+#define ACT_PARENT      20
 
 /* actuator flag */
 #define ACT_SHOW		1
@@ -423,6 +430,10 @@
 #define ACT_2DFILTER_INVERT				11
 #define ACT_2DFILTER_CUSTOMFILTER		12
 #define ACT_2DFILTER_NUMBER_OF_FILTERS	13
+
+/* parentactuator->type */
+#define ACT_PARENT_SET      0
+#define ACT_PARENT_REMOVE   1
 #endif
 
 

Modified: trunk/blender/source/blender/src/buttons_logic.c
===================================================================
--- trunk/blender/source/blender/src/buttons_logic.c	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/blender/src/buttons_logic.c	2008-04-06 18:30:52 UTC (rev 14342)
@@ -714,6 +714,8 @@
 		return "Visibility";
 	case ACT_2DFILTER:
 		return "2D Filter";
+	case ACT_PARENT:
+		return "Parent";
 	}
 	return "unknown";
 }
@@ -729,13 +731,13 @@
 		return "Actuators  %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
 			"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
 			"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
-			"|Visibility %x18|2D Filter %x19";
+			"|Visibility %x18|2D Filter %x19|Parent %x20";
 		break;
 	default:
 		return "Actuators  %t|Motion %x0|Constraint %x9|Ipo %x1"
 			"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
 			"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
-			"|Visibility %x18|2D Filter %x19";
+			"|Visibility %x18|2D Filter %x19|Parent %x20";
 	}
 }
 
@@ -1474,6 +1476,7 @@
 	bGameActuator	    *gma     = NULL;
 	bVisibilityActuator *visAct  = NULL;
 	bTwoDFilterActuator	*tdfa	 = NULL;
+	bParentActuator     *parAct  = NULL;
 	
 	float *fp;
 	short ysize = 0, wval;
@@ -2222,6 +2225,29 @@
 		
 		yco -= ysize;
         break;
+	case ACT_PARENT:
+  		parAct = act->data; 
+
+  		if(parAct->type==ACT_PARENT_SET) { 
+			
+  			ysize= 48; 
+  			glRects(xco, yco-ysize, xco+width, yco); 
+  			uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
+	 
+  			uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",		xco+40, yco-44, (width-80), 19, &(parAct->ob), "Set this object as parent"); 
+  		}
+  		else if(parAct->type==ACT_PARENT_REMOVE) { 
+			
+  			ysize= 28; 
+  			glRects(xco, yco-ysize, xco+width, yco); 
+  			uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
+ 		}
+
+		str= "Parent %t|Set Parent %x0|Remove Parent %x1";
+		uiDefButI(block, MENU, B_REDR, str,		xco+40, yco-24, (width-80), 19, &parAct->type, 0.0, 0.0, 0, 0, ""); 
+
+  		yco-= ysize; 
+  		break; 
  	default:
 		ysize= 4;
 

Modified: trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp	2008-04-06 18:30:52 UTC (rev 14342)
@@ -49,7 +49,6 @@
 #include "SCA_RandomActuator.h"
 #include "SCA_2DFilterActuator.h"
 
-
 // Ketsji specific logicbricks
 #include "KX_SceneActuator.h"
 #include "KX_IpoActuator.h"
@@ -64,6 +63,7 @@
 #include "KX_SCA_AddObjectActuator.h"
 #include "KX_SCA_EndObjectActuator.h"
 #include "KX_SCA_ReplaceMeshActuator.h"
+#include "KX_ParentActuator.h"
 
 #include "KX_Scene.h"
 #include "KX_KetsjiEngine.h"
@@ -917,6 +917,32 @@
 			
 		}
 		break;
+		case ACT_PARENT:
+			{
+				bParentActuator *parAct = (bParentActuator *) bact->data;
+				int mode = KX_ParentActuator::KX_PARENT_NODEF;
+				KX_GameObject *tmpgob;
+
+				switch(parAct->type)
+				{
+					case ACT_PARENT_SET:
+						mode = KX_ParentActuator::KX_PARENT_SET;
+						tmpgob = converter->FindGameObject(parAct->ob);
+						break;
+					case ACT_PARENT_REMOVE:
+						mode = KX_ParentActuator::KX_PARENT_REMOVE;
+						tmpgob = NULL;
+						break;
+				}
+	
+				KX_ParentActuator *tmpparact
+					= new KX_ParentActuator(gameobj,
+					mode,
+					tmpgob);
+				baseact = tmpparact;
+				break;
+			}
+		
 		default:
 			; /* generate some error */
 		}

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2008-04-06 17:11:14 UTC (rev 14341)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2008-04-06 18:30:52 UTC (rev 14342)
@@ -62,7 +62,7 @@
 #include "KX_ClientObjectInfo.h"
 #include "RAS_BucketManager.h"
 #include "KX_RayCast.h"
-
+#include "KX_PythonInit.h"
 #include "KX_PyMath.h"
 
 // This file defines relationships between parents and children
@@ -88,7 +88,7 @@
 	m_ignore_activity_culling = false;
 	m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
 	m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
-	
+
 	// define the relationship between this node and it's parent.
 	
 	KX_NormalParentRelation * parent_relation = 
@@ -204,8 +204,63 @@
 	
 }
 
+void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
+{
+	if (obj && GetSGNode()->GetSGParent() != obj->GetSGNode())
+	{
+		// Make sure the objects have some scale
+		MT_Vector3 scale1 = NodeGetWorldScaling();
+		MT_Vector3 scale2 = obj->NodeGetWorldScaling();
+		if (fabs(scale2[0]) < FLT_EPSILON || 
+			fabs(scale2[1]) < FLT_EPSILON || 
+			fabs(scale2[2]) < FLT_EPSILON || 
+			fabs(scale1[0]) < FLT_EPSILON || 
+			fabs(scale1[1]) < FLT_EPSILON || 
+			fabs(scale1[2]) < FLT_EPSILON) { return; }
 
+		// Remove us from our old parent and set our new parent
+		RemoveParent(scene);
+		obj->GetSGNode()->AddChild(GetSGNode());
 
+		// Set us to our new scale, position, and orientation
+		scale1[0] = scale1[0]/scale2[0];
+		scale1[1] = scale1[1]/scale2[1];
+		scale1[2] = scale1[2]/scale2[2];
+		MT_Matrix3x3 invori = obj->NodeGetWorldOrientation().inverse();
+		MT_Vector3 newpos = invori*(NodeGetWorldPosition()-obj->NodeGetWorldPosition())*scale1;
+
+		NodeSetLocalScale(scale1);
+		NodeSetLocalPosition(MT_Point3(newpos[0],newpos[1],newpos[2]));
+		NodeSetLocalOrientation(NodeGetWorldOrientation()*invori);
+		NodeUpdateGS(0.f,true);
+		// object will now be a child, it must be removed from the parent list
+		CListValue* rootlist = scene->GetRootParentList();
+		if (rootlist->RemoveValue(this))
+			// the object was in parent list, decrement ref count as it's now removed
+			Release();
+	}
+}
+
+void KX_GameObject::RemoveParent(KX_Scene *scene)
+{
+	if (GetSGNode()->GetSGParent())
+	{
+		// Set us to the right spot 
+		GetSGNode()->SetLocalScale(GetSGNode()->GetWorldScaling());
+		GetSGNode()->SetLocalOrientation(GetSGNode()->GetWorldOrientation());
+		GetSGNode()->SetLocalPosition(GetSGNode()->GetWorldPosition());
+
+		// Remove us from our parent
+		GetSGNode()->DisconnectFromParent();
+		NodeUpdateGS(0.f,true);
+		// the object is now a root object, add it to the parentlist
+		CListValue* rootlist = scene->GetRootParentList();

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list