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:
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenloader/intern/readfile.c16
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h8
-rw-r--r--source/blender/src/buttons_logic.c26
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp7
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp48
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp21
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h4
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.h5
-rw-r--r--source/gameengine/PyDoc/GameTypes.py22
12 files changed, 120 insertions, 53 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index d49a5425b61..aa2366661f8 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -41,7 +41,7 @@ struct ListBase;
struct MemFile;
#define BLENDER_VERSION 248
-#define BLENDER_SUBVERSION 4
+#define BLENDER_SUBVERSION 5
#define BLENDER_MINVERSION 245
#define BLENDER_MINSUBVERSION 15
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 0f233410f4e..25c8a928a3b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8106,6 +8106,22 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) {
+ Object *ob;
+ for(ob = main->object.first; ob; ob= ob->id.next) {
+ if(ob->parent) {
+ /* check if top parent has compound shape set and if yes, set this object
+ to compound shaper as well (was the behaviour before, now it's optional) */
+ Object *parent= newlibadr(fd, lib, ob->parent);
+ while (parent->parent != NULL) {
+ parent = newlibadr(fd, lib, parent->parent);
+ }
+ if (parent->gameflag & OB_CHILD)
+ ob->gameflag |= OB_CHILD;
+ }
+ }
+ }
+
if (main->versionfile < 249) {
Scene *sce;
for (sce= main->scene.first; sce; sce= sce->id.next)
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 81c02779cba..f713b4a8acc 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -215,7 +215,8 @@ typedef struct bTwoDFilterActuator{
}bTwoDFilterActuator;
typedef struct bParentActuator {
- char pad[4];
+ char pad[2];
+ short flag;
int type;
struct Object *ob;
} bParentActuator;
@@ -483,6 +484,11 @@ typedef struct FreeCamera {
/* parentactuator->type */
#define ACT_PARENT_SET 0
#define ACT_PARENT_REMOVE 1
+
+/* parentactuator->flag */
+#define ACT_PARENT_COMPOUND 1
+#define ACT_PARENT_GHOST 2
+
#endif
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 2f8933b593b..b7039673dfc 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -2747,11 +2747,22 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
if(parAct->type==ACT_PARENT_SET) {
- ysize= 48;
+ ysize= 68;
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");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOGN, ACT_PARENT_COMPOUND, B_REDR,
+ "Compound",
+ xco + 40, yco - 64, (width - 80)/2, 19, &parAct->flag,
+ 0.0, 0.0, 0, 0,
+ "Add this object shape to the parent shape (only if the parent shape is already compound)");
+ uiDefButBitI(block, TOGN, ACT_PARENT_GHOST, B_REDR,
+ "Ghost",
+ xco + 40 + ((width - 80)/2), yco - 64, (width - 80)/2, 19, &parAct->flag,
+ 0.0, 0.0, 0, 0,
+ "Make this object ghost while parented (only if not compound)");
+ uiBlockEndAlign(block);
}
else if(parAct->type==ACT_PARENT_REMOVE) {
@@ -3480,9 +3491,14 @@ static void buttons_bullet(uiBlock *block, Object *ob)
}
if (ob->body_type!=OB_BODY_TYPE_SOFT)
{
- uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 240,105,110,19,
- &ob->gameflag, 0, 0, 0, 0,
- "Add Children");
+ if (ob->parent)
+ uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Add to parent", 240,105,110,19,
+ &ob->gameflag, 0, 0, 0, 0,
+ "Add this shape to the parent compound shape");
+ else
+ uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 240,105,110,19,
+ &ob->gameflag, 0, 0, 0, 0,
+ "Create a compound shape with the children's shape that are tagged for addition");
}
}
uiBlockEndAlign(block);
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index bf965f677c6..82edd4f218b 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1377,10 +1377,11 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
}
bool isCompoundChild = false;
+ bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD);
- if (parent && (parent->gameflag & OB_DYNAMIC)) {
+ if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) {
- if ((parent->gameflag & OB_CHILD) != 0)
+ if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD))
{
isCompoundChild = true;
}
@@ -1406,7 +1407,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0;
objprop.m_isCompoundChild = isCompoundChild;
- objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0;
+ objprop.m_hasCompoundChildren = hasCompoundChildren;
objprop.m_margin = blenderobject->margin;
// ACTOR is now a separate feature
objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 98df34aa4a9..2b832996c45 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -1123,6 +1123,8 @@ void BL_ConvertActuators(char* maggiename,
{
bParentActuator *parAct = (bParentActuator *) bact->data;
int mode = KX_ParentActuator::KX_PARENT_NODEF;
+ bool addToCompound = true;
+ bool ghost = true;
KX_GameObject *tmpgob = NULL;
switch(parAct->type)
@@ -1130,6 +1132,8 @@ void BL_ConvertActuators(char* maggiename,
case ACT_PARENT_SET:
mode = KX_ParentActuator::KX_PARENT_SET;
tmpgob = converter->FindGameObject(parAct->ob);
+ addToCompound = !(parAct->flag & ACT_PARENT_COMPOUND);
+ ghost = !(parAct->flag & ACT_PARENT_GHOST);
break;
case ACT_PARENT_REMOVE:
mode = KX_ParentActuator::KX_PARENT_REMOVE;
@@ -1140,6 +1144,8 @@ void BL_ConvertActuators(char* maggiename,
KX_ParentActuator *tmpparact
= new KX_ParentActuator(gameobj,
mode,
+ addToCompound,
+ ghost,
tmpgob);
baseact = tmpparact;
break;
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index d81b6d5a653..406339586cc 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -949,39 +949,27 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
assert(colShape->isCompound());
btCompoundShape* compoundShape = (btCompoundShape*)colShape;
- // compute the local transform from parent, this may include a parent inverse node
+ // compute the local transform from parent, this may include several node in the chain
SG_Node* gameNode = gameobj->GetSGNode();
- SG_Node* parentInverseNode = gameNode->GetSGParent();
- if (parentInverseNode && parentInverseNode->GetSGClientObject() != NULL)
- // this is not a parent inverse node, cancel it
- parentInverseNode = NULL;
- // now combine the parent inverse node and the game node
- MT_Point3 childPos = gameNode->GetLocalPosition();
- MT_Matrix3x3 childRot = gameNode->GetLocalOrientation();
- MT_Vector3 childScale = gameNode->GetLocalScale();
- if (parentInverseNode)
- {
- const MT_Point3& parentInversePos = parentInverseNode->GetLocalPosition();
- const MT_Matrix3x3& parentInverseRot = parentInverseNode->GetLocalOrientation();
- const MT_Vector3& parentInverseScale = parentInverseNode->GetLocalScale();
- childRot = parentInverseRot * childRot;
- childScale = parentInverseScale * childScale;
- childPos = parentInversePos+parentInverseScale*(parentInverseRot*childPos);
- }
-
- shapeInfo->m_childScale.setValue(childScale.x(),childScale.y(),childScale.z());
+ SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode();
+ // relative transform
+ MT_Vector3 parentScale = parentNode->GetWorldScaling();
+ parentScale[0] = MT_Scalar(1.0)/parentScale[0];
+ parentScale[1] = MT_Scalar(1.0)/parentScale[1];
+ parentScale[2] = MT_Scalar(1.0)/parentScale[2];
+ MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
+ MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
+ MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
+ MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
+
+ shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
bm->setLocalScaling(shapeInfo->m_childScale);
-
- shapeInfo->m_childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
- float rotval[12];
- childRot.getValue(rotval);
- btMatrix3x3 newRot;
- newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]);
- newRot = newRot.transpose();
-
- shapeInfo->m_childTrans.setBasis(newRot);
+ shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
+ float rot[12];
+ relativeRot.getValue(rot);
+ shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
+
parentShapeInfo->AddShape(shapeInfo);
-
compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
//do some recalc?
//recalc inertia for rigidbody
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 63d508e6250..0c191257f41 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -224,7 +224,7 @@ KX_GameObject* KX_GameObject::GetParent()
}
-void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
+void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj, bool addToCompound, bool ghost)
{
// check on valid node in case a python controller holds a reference to a deleted object
if (obj && GetSGNode() && obj->GetSGNode() && GetSGNode()->GetSGParent() != obj->GetSGNode())
@@ -245,7 +245,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
if (m_pPhysicsController1)
{
- m_pPhysicsController1->SuspendDynamics(true);
+ m_pPhysicsController1->SuspendDynamics(ghost);
}
// Set us to our new scale, position, and orientation
scale2[0] = 1.0/scale2[0];
@@ -266,7 +266,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
Release();
// if the new parent is a compound object, add this object shape to the compound shape.
// step 0: verify this object has physical controller
- if (m_pPhysicsController1)
+ if (m_pPhysicsController1 && addToCompound)
{
// step 1: find the top parent (not necessarily obj)
KX_GameObject* rootobj = (KX_GameObject*)obj->GetSGNode()->GetRootSGParent()->GetSGClientObject();
@@ -1160,7 +1160,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_NOARGS},
{"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS},
{"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O},
- {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
+ {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_VARARGS},
{"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
{"setOcclusion",(PyCFunction) KX_GameObject::sPySetOcclusion, METH_VARARGS},
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
@@ -2147,15 +2147,20 @@ PyObject* KX_GameObject::PyGetParent()
Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PySetParent(PyObject* value)
+PyObject* KX_GameObject::PySetParent(PyObject* args)
{
KX_Scene *scene = KX_GetActiveScene();
+ PyObject* pyobj;
KX_GameObject *obj;
+ int addToCompound=1, ghost=1;
- if (!ConvertPythonToGameObject(value, &obj, false, "gameOb.setParent(value): KX_GameObject"))
+ if (!PyArg_ParseTuple(args,"O|ii:setParent", &pyobj, &addToCompound, &ghost)) {
+ return NULL; // Python sets a simple error
+ }
+ if (!ConvertPythonToGameObject(pyobj, &obj, true, "gameOb.setParent(obj): KX_GameObject"))
return NULL;
-
- this->SetParent(scene, obj);
+ if (obj)
+ this->SetParent(scene, obj, addToCompound, ghost);
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 0011b8407fd..c89b8f30779 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -171,7 +171,7 @@ public:
/**
* Sets the parent of this object to a game object
*/
- void SetParent(KX_Scene *scene, KX_GameObject *obj);
+ void SetParent(KX_Scene *scene, KX_GameObject *obj, bool addToCompound=true, bool ghost=true);
/**
* Removes the parent of this object to a game object
@@ -858,7 +858,7 @@ public:
KX_PYMETHOD_VARARGS(KX_GameObject,ApplyImpulse);
KX_PYMETHOD_O(KX_GameObject,SetCollisionMargin);
KX_PYMETHOD_NOARGS(KX_GameObject,GetParent);
- KX_PYMETHOD_O(KX_GameObject,SetParent);
+ KX_PYMETHOD_VARARGS(KX_GameObject,SetParent);
KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildren);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildrenRecursive);
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 38ad9aec33b..cd2ed456c48 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -48,10 +48,14 @@
KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj,
int mode,
+ bool addToCompound,
+ bool ghost,
SCA_IObject *ob,
PyTypeObject* T)
: SCA_IActuator(gameobj, T),
m_mode(mode),
+ m_addToCompound(addToCompound),
+ m_ghost(ghost),
m_ob(ob)
{
if (m_ob)
@@ -121,7 +125,7 @@ bool KX_ParentActuator::Update()
switch (m_mode) {
case KX_PARENT_SET:
if (m_ob)
- obj->SetParent(scene, (KX_GameObject*)m_ob);
+ obj->SetParent(scene, (KX_GameObject*)m_ob, m_addToCompound, m_ghost);
break;
case KX_PARENT_REMOVE:
obj->RemoveParent(scene);
@@ -179,6 +183,8 @@ PyMethodDef KX_ParentActuator::Methods[] = {
PyAttributeDef KX_ParentActuator::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object),
KX_PYATTRIBUTE_INT_RW("mode", KX_PARENT_NODEF+1, KX_PARENT_MAX-1, true, KX_ParentActuator, m_mode),
+ KX_PYATTRIBUTE_BOOL_RW("compound", KX_ParentActuator, m_addToCompound),
+ KX_PYATTRIBUTE_BOOL_RW("ghost", KX_ParentActuator, m_ghost),
{ NULL } //Sentinel
};
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h
index 6af0888e2ba..148375e994c 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.h
+++ b/source/gameengine/Ketsji/KX_ParentActuator.h
@@ -46,6 +46,9 @@ class KX_ParentActuator : public SCA_IActuator
/** Mode */
int m_mode;
+ /** option */
+ bool m_addToCompound;
+ bool m_ghost;
/** Object to set as parent */
SCA_IObject *m_ob;
@@ -63,6 +66,8 @@ class KX_ParentActuator : public SCA_IActuator
KX_ParentActuator(class SCA_IObject* gameobj,
int mode,
+ bool addToCompound,
+ bool ghost,
SCA_IObject *ob,
PyTypeObject* T=&Type);
virtual ~KX_ParentActuator();
diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py
index 47c27a5c3c9..3f9b627247f 100644
--- a/source/gameengine/PyDoc/GameTypes.py
+++ b/source/gameengine/PyDoc/GameTypes.py
@@ -1896,12 +1896,23 @@ class KX_GameObject(SCA_IObject):
@rtype: L{KX_GameObject}
@return: this object's parent object, or None if this object has no parent.
"""
- def setParent(parent):
+ def setParent(parent,compound,ghost):
"""
- Sets this object's parent.
+ Sets this object's parent.
+ Control the shape status with the optional compound and ghost parameters:
+ compound=1: the object shape should be added to the parent compound shape (default)
+ compound=0: the object should keep its individual shape.
+ In that case you can control if it should be ghost or not:
+ ghost=1 if the object should be made ghost while parented (default)
+ ghost=0 if the object should be solid while parented
+ Note: if the object type is sensor, it stays ghost regardless of ghost parameter
@type parent: L{KX_GameObject}
@param parent: new parent object.
+ @type compound: int
+ @param compound: whether the shape should be added to the parent compound shape
+ @type ghost: int
+ @param ghost: whether the object should be ghost while parented
"""
def removeParent():
"""
@@ -2937,6 +2948,13 @@ class KX_ParentActuator(SCA_IActuator):
@type object: KX_GameObject or None
@ivar mode: The mode of this actuator
@type mode: int from 0 to 1 L{GameLogic.Parent Actuator}
+ @ivar compound: Whether the object shape should be added to the parent compound shape when parenting
+ Effective only if the parent is already a compound shape
+ @type compound: bool
+ @ivar ghost: whether the object should be made ghost when parenting
+ Effective only if the shape is not added to the parent compound shape
+ @type ghost: bool
+
"""
def setObject(object):
"""