[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19746] trunk/blender/source/gameengine: BGE bug #18168: Get local orientation of object using game engine python script system.

Benoit Bolsee benoit.bolsee at online.be
Wed Apr 15 23:17:08 CEST 2009


Revision: 19746
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19746
Author:   ben2610
Date:     2009-04-15 23:17:08 +0200 (Wed, 15 Apr 2009)

Log Message:
-----------
BGE bug #18168: Get local orientation of object using game engine python script system. Added localOrientation and worldOrientation. orientation attribute deprecated. Same for position and scaling. World attributes are read-only except for worldPosition. Add systematic check on NULL SGNode in all python functions. This is necessary to handle zombie objects (deleted by the game but kept alive by a reference in a list).

Modified Paths:
--------------
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
    trunk/blender/source/gameengine/PyDoc/KX_GameObject.py

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2009-04-15 21:03:23 UTC (rev 19745)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2009-04-15 21:17:08 UTC (rev 19746)
@@ -76,6 +76,10 @@
 #include "KX_SG_NodeRelationships.h"
 
 static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
+static MT_Vector3 dummy_scaling = MT_Vector3(1.0, 1.0, 1.0);
+static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3(	1.0, 0.0, 0.0,
+														0.0, 1.0, 0.0,
+														0.0, 0.0, 1.0);
 
 KX_GameObject::KX_GameObject(
 	void* sgReplicationInfo,
@@ -373,11 +377,14 @@
 
 void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
 {
-	if (m_pPhysicsController1) // (IsDynamic())
+	if (GetSGNode()) 
 	{
-		m_pPhysicsController1->RelativeTranslate(dloc,local);
+		if (m_pPhysicsController1) // (IsDynamic())
+		{
+			m_pPhysicsController1->RelativeTranslate(dloc,local);
+		}
+		GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
 	}
-	GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
 }
 
 
@@ -385,11 +392,13 @@
 void KX_GameObject::ApplyRotation(const MT_Vector3& drot,bool local)
 {
 	MT_Matrix3x3 rotmat(drot);
+	
+	if (GetSGNode()) {
+		GetSGNode()->RelativeRotate(rotmat,local);
 
-	GetSGNode()->RelativeRotate(rotmat,local);
-
-	if (m_pPhysicsController1) { // (IsDynamic())
-		m_pPhysicsController1->RelativeRotate(rotmat,local); 
+		if (m_pPhysicsController1) { // (IsDynamic())
+			m_pPhysicsController1->RelativeRotate(rotmat,local); 
+		}
 	}
 }
 
@@ -402,16 +411,17 @@
 {
 	// todo: optimize and only update if necessary
 	double* fl = m_OpenGL_4x4Matrix.getPointer();
-	MT_Transform trans;
+	if (GetSGNode()) {
+		MT_Transform trans;
 	
-	trans.setOrigin(GetSGNode()->GetWorldPosition());
-	trans.setBasis(GetSGNode()->GetWorldOrientation());
+		trans.setOrigin(GetSGNode()->GetWorldPosition());
+		trans.setBasis(GetSGNode()->GetWorldOrientation());
 	
-	MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
-	m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false;
-	trans.scale(scaling[0], scaling[1], scaling[2]);
-	trans.getValue(fl);
-
+		MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
+		m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false;
+		trans.scale(scaling[0], scaling[1], scaling[2]);
+		trans.getValue(fl);
+	}
 	return fl;
 }
 
@@ -442,13 +452,15 @@
 
 void KX_GameObject::UpdateBuckets( bool recursive )
 {
-	double* fl = GetOpenGLMatrixPtr()->getPointer();
+	if (GetSGNode()) {
+		double* fl = GetOpenGLMatrixPtr()->getPointer();
 
-	for (size_t i=0;i<m_meshes.size();i++)
-		m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
+		for (size_t i=0;i<m_meshes.size();i++)
+			m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
 	
-	if (recursive) {
-		UpdateBuckets_recursive(m_pSGNode);
+		if (recursive) {
+			UpdateBuckets_recursive(GetSGNode());
+		}
 	}
 }
 
@@ -599,9 +611,11 @@
 	bool recursive
 	)
 {
-	m_bVisible = v;
-	if (recursive)
-		setVisible_recursive(m_pSGNode, v);
+	if (GetSGNode()) {
+		m_bVisible = v;
+		if (recursive)
+			setVisible_recursive(GetSGNode(), v);
+	}
 }
 
 static void setOccluder_recursive(SG_Node* node, bool v)
@@ -627,9 +641,11 @@
 	bool recursive
 	)
 {
-	m_bOccluder = v;
-	if (recursive)
-		setOccluder_recursive(m_pSGNode, v);
+	if (GetSGNode()) {
+		m_bOccluder = v;
+		if (recursive)
+			setOccluder_recursive(GetSGNode(), v);
+	}
 }
 
 void
@@ -929,7 +945,9 @@
 
 void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans)
 {
-	SG_Node* parent = m_pSGNode->GetSGParent();
+	if (!GetSGNode())
+		return;
+	SG_Node* parent = GetSGNode()->GetSGParent();
 	if (parent != NULL)
 	{
 		// Make sure the objects have some scale
@@ -964,13 +982,9 @@
 
 const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
 {
-	static MT_Matrix3x3 defaultOrientation = MT_Matrix3x3(	1.0, 0.0, 0.0,
-															0.0, 1.0, 0.0,
-															0.0, 0.0, 1.0);
-
 	// check on valid node in case a python controller holds a reference to a deleted object
 	if (!GetSGNode())
-		return defaultOrientation;
+		return dummy_orientation;
 	return GetSGNode()->GetWorldOrientation();
 }
 
@@ -978,11 +992,9 @@
 
 const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
 {
-	static MT_Vector3 defaultScaling = MT_Vector3(1.0, 1.0, 1.0);
-
 	// check on valid node in case a python controller holds a reference to a deleted object
 	if (!GetSGNode())
-		return defaultScaling;
+		return dummy_scaling;
 
 	return GetSGNode()->GetWorldScaling();
 }
@@ -1091,13 +1103,19 @@
 	KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMax",		KX_GameObject, pyattr_get_lin_vel_max, pyattr_set_lin_vel_max),
 	KX_PYATTRIBUTE_RW_FUNCTION("visible",	KX_GameObject, pyattr_get_visible,	pyattr_set_visible),
 	KX_PYATTRIBUTE_BOOL_RW    ("occlusion", KX_GameObject, m_bOccluder),
-	KX_PYATTRIBUTE_RW_FUNCTION("position",	KX_GameObject, pyattr_get_position,	pyattr_set_position),
+	KX_PYATTRIBUTE_RW_FUNCTION("position",	KX_GameObject, pyattr_get_worldPosition,	pyattr_set_localPosition),
 	KX_PYATTRIBUTE_RO_FUNCTION("localInertia",	KX_GameObject, pyattr_get_localInertia),
-	KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_orientation,pyattr_set_orientation),
-	KX_PYATTRIBUTE_RW_FUNCTION("scaling",	KX_GameObject, pyattr_get_scaling,	pyattr_set_scaling),
+	KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_worldOrientation,pyattr_set_localOrientation),
+	KX_PYATTRIBUTE_RW_FUNCTION("scaling",	KX_GameObject, pyattr_get_worldScaling,	pyattr_set_localScaling),
 	KX_PYATTRIBUTE_RW_FUNCTION("timeOffset",KX_GameObject, pyattr_get_timeOffset,pyattr_set_timeOffset),
 	KX_PYATTRIBUTE_RW_FUNCTION("state",		KX_GameObject, pyattr_get_state,	pyattr_set_state),
 	KX_PYATTRIBUTE_RO_FUNCTION("meshes",	KX_GameObject, pyattr_get_meshes),
+	KX_PYATTRIBUTE_RW_FUNCTION("localOrientation",KX_GameObject,pyattr_get_localOrientation,pyattr_set_localOrientation),
+	KX_PYATTRIBUTE_RO_FUNCTION("worldOrientation",KX_GameObject,pyattr_get_worldOrientation),
+	KX_PYATTRIBUTE_RW_FUNCTION("localPosition",	KX_GameObject, pyattr_get_localPosition,	pyattr_set_localPosition),
+	KX_PYATTRIBUTE_RW_FUNCTION("worldPosition",	KX_GameObject, pyattr_get_worldPosition,    pyattr_set_worldPosition),
+	KX_PYATTRIBUTE_RW_FUNCTION("localScaling",	KX_GameObject, pyattr_get_localScaling,	pyattr_set_localScaling),
+	KX_PYATTRIBUTE_RO_FUNCTION("worldScaling",	KX_GameObject, pyattr_get_worldScaling),
 	
 	KX_PYATTRIBUTE_RO_FUNCTION("__dict__",	KX_GameObject, pyattr_get_dir_dict),
 	
@@ -1448,19 +1466,40 @@
 	return 0;
 }
 
-PyObject* KX_GameObject::pyattr_get_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
 	return PyObjectFrom(self->NodeGetWorldPosition());
 }
 
-int KX_GameObject::pyattr_set_position(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
 	MT_Point3 pos;
 	if (!PyVecTo(value, pos))
 		return 1;
 	
+	self->NodeSetWorldPosition(pos);
+	self->NodeUpdateGS(0.f);
+	return 0;
+}
+
+PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+	if (self->GetSGNode())
+		return PyObjectFrom(self->GetSGNode()->GetLocalPosition());
+	else
+		return PyObjectFrom(dummy_point);
+}
+
+int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+	MT_Point3 pos;
+	if (!PyVecTo(value, pos))
+		return 1;
+	
 	self->NodeSetLocalPosition(pos);
 	self->NodeUpdateGS(0.f);
 	return 0;
@@ -1476,15 +1515,24 @@
 	return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f);
 }
 
-PyObject* KX_GameObject::pyattr_get_orientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
 	return PyObjectFrom(self->NodeGetWorldOrientation());
 }
 
-int KX_GameObject::pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+	if (self->GetSGNode())
+		return PyObjectFrom(self->GetSGNode()->GetLocalOrientation());
+	else
+		return PyObjectFrom(dummy_orientation);
+}
+
+int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
 	if (!PySequence_Check(value)) {
 		PyErr_SetString(PyExc_AttributeError, "'orientation' attribute needs to be a sequence");
 		return 1;
@@ -1530,15 +1578,24 @@
 	return 1;
 }
 
-PyObject* KX_GameObject::pyattr_get_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
 	return PyObjectFrom(self->NodeGetWorldScaling());
 }
 
-int KX_GameObject::pyattr_set_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+	if (self->GetSGNode())
+		return PyObjectFrom(self->GetSGNode()->GetLocalScale());
+	else
+		return PyObjectFrom(dummy_scaling);
+}
+
+int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
 	MT_Vector3 scale;
 	if (!PyVecTo(value, scale))
 		return 1;
@@ -1551,8 +1608,8 @@
 PyObject* KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list