Game Engine: Option to record static objects animation
authorJames Yonan <james@openvpn.net>
Mon, 9 Dec 2013 11:26:52 +0000 (22:26 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 9 Dec 2013 11:28:38 +0000 (22:28 +1100)
doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
release/scripts/startup/bl_ui/properties_game.py
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_object.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h

index 5d699637eb72594bdc06fe3eaa2c38298f6976b2..af4852d6ab1499ed670ff22a2e3da3605a0c2f84 100644 (file)
@@ -151,11 +151,17 @@ base class --- :class:`SCA_IObject`
       visibility flag.
 
       :type: boolean
-      
+
       .. note::
-      
+
          Game logic will still run for invisible objects.
 
+   .. attribute:: record_animation
+
+      Record animation for this object.
+
+      :type: boolean
+
    .. attribute:: color
 
       The object color of the object. [r, g, b, a]
index 3470c9577af561300e128351e5527172d0251329..fdbe02ebd47300afe043cf17b4fcd27bfc41425e 100644 (file)
@@ -156,6 +156,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
             col = layout.column()
             col.prop(game, "use_actor")
             col.prop(game, "use_ghost")
+            col.prop(game, "use_record_animation")
             col.prop(ob, "hide_render", text="Invisible")
 
             layout.separator()
index 2ff697f513fba1d59de48d3adf2da10b9d5245c3..7034162c7ec8ba7a5cad0c761bd2efa0dd3fadc3 100644 (file)
@@ -542,6 +542,8 @@ enum {
        OB_NAVMESH               = 1 << 20,
        OB_HASOBSTACLE           = 1 << 21,
        OB_CHARACTER             = 1 << 22,
+
+       OB_RECORD_ANIMATION      = 1 << 23,
 };
 
 /* ob->gameflag2 */
index 184e067299e8fee036142f926e707616e73e579d..9c1d0c4cc2bcdcc92b516e563cfa16cf9ff8d7f3 100644 (file)
@@ -1646,6 +1646,10 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Physics Type", "Select the type of physical representation");
        RNA_def_property_update(prop, NC_LOGIC, NULL);
 
+       prop = RNA_def_property(srna, "use_record_animation", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "gameflag", OB_RECORD_ANIMATION);
+       RNA_def_property_ui_text(prop, "Record Animation", "Record animation objects without physics");
+
        prop = RNA_def_property(srna, "use_actor", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "gameflag", OB_ACTOR);
        RNA_def_property_ui_text(prop, "Actor", "Object is detected by the Near and Radar sensor");
index 1b27fde4fa43bbb2901c2c0493452550d4455559..eeaffd9005a0ef8e7a775e77b1166078ec3237d0 100644 (file)
@@ -1513,6 +1513,7 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
        objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
        objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
        objprop.m_character = (blenderobject->gameflag & OB_CHARACTER) != 0;
+       objprop.m_record_animation = (blenderobject->gameflag & OB_RECORD_ANIMATION) != 0;
        
        ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
        if (objprop.m_angular_rigidbody || !objprop.m_dyna )
index e682f3356086ed40ac267fa6fe15a28cd7b06fcf..4ed8e3e8a034334eaa92973ef0a13bd0a7b0fed5 100644 (file)
@@ -706,8 +706,7 @@ void        KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
                for (g=0;g<numObjects;g++)
                {
                        KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
-                       if (gameObj->IsDynamic())
-                       {
+                       if (gameObj->IsRecordAnimation()) {
                                
                                Object* blenderObject = gameObj->GetBlenderObject();
                                if (blenderObject)
@@ -769,7 +768,7 @@ void        KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
                        CListValue* parentList = scene->GetRootParentList();
                        for (int ix=0;ix<parentList->GetCount();ix++) {
                                KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
-                               if (!gameobj->IsDynamic()) {
+                               if (!gameobj->IsRecordAnimation()) {
                                        Object* blenderobject = gameobj->GetBlenderObject();
                                        if (!blenderobject)
                                                continue;
@@ -821,8 +820,7 @@ void        KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
                {
                        KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
                        Object* blenderObject = gameObj->GetBlenderObject();
-                       if (blenderObject && blenderObject->parent==NULL && gameObj->IsDynamic())
-                       {
+                       if (blenderObject && blenderObject->parent==NULL && gameObj->IsRecordAnimation()) {
 
                                if (blenderObject->adt==NULL)
                                        BKE_id_add_animdata(&blenderObject->id);
@@ -939,9 +937,7 @@ void        KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
                for (g=0;g<numObjects;g++)
                {
                        KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
-                       if (gameObj->IsDynamic())
-                       {
-                               
+                       if (gameObj->IsRecordAnimation()) {
 #if 0
                                Object* blenderObject = gameObj->GetBlenderObject();
                                if (blenderObject && blenderObject->ipo)
index 903966b79be2ab3e5deeda95b4a79c51b4282f71..1ed3a998b990bb56ee54549c7699d3738a090e2e 100644 (file)
@@ -71,6 +71,7 @@ struct KX_ObjectProperties
        bool    m_ghost;
        class KX_GameObject*    m_dynamic_parent;
        bool    m_isactor;
+       bool    m_record_animation;
        bool    m_sensor;
        bool    m_character;
        bool    m_concave;
index bde50588fd38a942056bf67fdb97f22c79501c3b..16513a97d606b683932ecd13e23fb7249a440bc9 100644 (file)
@@ -435,6 +435,11 @@ void       KX_ConvertBulletObject( class   KX_GameObject* gameobj,
                shapeInfo->Release();
 
        gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
+
+       // record animation for dynamic objects
+       if (isbulletdyna)
+               gameobj->SetRecordAnimation(true);
+
        // don't add automatically sensor object, they are added when a collision sensor is registered
        if (!isbulletsensor && objprop->m_in_active_layer)
        {
@@ -493,6 +498,11 @@ void       KX_ConvertBulletObject( class   KX_GameObject* gameobj,
        gameobj->getClientInfo()->m_type = 
                (isbulletsensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) :
                (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC;
+
+       // should we record animation for this object?
+       if (objprop->m_record_animation)
+               gameobj->SetRecordAnimation(true);
+
        // store materialname in auxinfo, needed for touchsensors
        if (meshobj)
        {
index 96f76ff21b1a0e736df48a467f7a13ceb310f872..d3b5a987138d701b1a8f5307cc0909c22db31f40 100644 (file)
@@ -112,6 +112,7 @@ KX_GameObject::KX_GameObject(
       m_pInstanceObjects(NULL),
       m_pDupliGroupObject(NULL),
       m_actionManager(NULL),
+      m_bRecordAnimation(false),
       m_isDeformable(false)
 
 #ifdef WITH_PYTHON
@@ -1791,6 +1792,7 @@ PyAttributeDef KX_GameObject::Attributes[] = {
        KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin",            KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min),
        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_RW_FUNCTION("record_animation",  KX_GameObject, pyattr_get_record_animation,     pyattr_set_record_animation),
        KX_PYATTRIBUTE_BOOL_RW    ("occlusion", KX_GameObject, m_bOccluder),
        KX_PYATTRIBUTE_RW_FUNCTION("position",  KX_GameObject, pyattr_get_worldPosition,        pyattr_set_localPosition),
        KX_PYATTRIBUTE_RO_FUNCTION("localInertia",      KX_GameObject, pyattr_get_localInertia),
@@ -2258,6 +2260,28 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at
        return PY_SET_ATTR_SUCCESS;
 }
 
+PyObject *KX_GameObject::pyattr_get_record_animation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+       KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+       return PyBool_FromLong(self->IsRecordAnimation());
+}
+
+int KX_GameObject::pyattr_set_record_animation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+       KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+       int param = PyObject_IsTrue(value);
+       if (param == -1) {
+               PyErr_SetString(PyExc_AttributeError, "gameOb.record_animation = bool: KX_GameObject, expected boolean");
+               return PY_SET_ATTR_FAIL;
+       }
+
+       self->SetRecordAnimation(param);
+
+       return PY_SET_ATTR_SUCCESS;
+}
+
+
+
 PyObject *KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 #ifdef USE_MATHUTILS
index 55e2b31c5bfaec90a97e3ce20c7b87660349a340..12aac68365b6c83ef8bc81eee661f6db52d54884 100644 (file)
@@ -126,6 +126,7 @@ protected:
 
        BL_ActionManager* GetActionManager();
        
+       bool                                                            m_bRecordAnimation;
 public:
        bool                                                            m_isDeformable;
 
@@ -599,6 +600,20 @@ public:
                return m_bDyna; 
        }
 
+       /**
+        * Should we record animation for this object?
+        */
+
+       void SetRecordAnimation(bool recordAnimation)
+       {
+               m_bRecordAnimation = recordAnimation;
+       }
+
+       bool IsRecordAnimation() const
+       {
+               return m_bRecordAnimation;
+       }
+
        /**
         * Check if this object has a vertex parent relationship
         */
@@ -981,6 +996,8 @@ public:
        static int                      pyattr_set_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static PyObject*        pyattr_get_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static int                      pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+       static PyObject*        pyattr_get_record_animation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+       static int                      pyattr_set_record_animation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static PyObject*        pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static int                      pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static PyObject*        pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);