orange: animation baking code. also a patch to autokey, to only key the keys made.
authorToni Alatalo <antont@kyperjokki.fi>
Sun, 18 Dec 2005 20:14:22 +0000 (20:14 +0000)
committerToni Alatalo <antont@kyperjokki.fi>
Sun, 18 Dec 2005 20:14:22 +0000 (20:14 +0000)
14 files changed:
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/ipo.c
source/blender/include/BSE_editipo.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/python/SConscript
source/blender/python/api2_2x/NLA.c
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/Types.c
source/blender/python/api2_2x/Types.h
source/blender/src/editaction.c
source/blender/src/editipo.c
source/blender/src/editnla.c
source/blender/src/space.c
source/blender/src/transform_conversions.c

index 0cbccd2a1b44e6653f554665b8ea0a9742d84c4f..cee36e06faea9fb1a41ffbfca4a29e9cebe8b5d5 100644 (file)
@@ -1078,3 +1078,4 @@ void do_all_object_actions(Object *ob)
        }
 }
 
+
index 0f73843b9fa91370fb02281e58fbe34e56b08b4c..8aee2c9e785adef063dfa64fbfebc93f8590f1b6 100644 (file)
@@ -1805,7 +1805,11 @@ void execute_action_ipo(bActionChannel *achan, bPoseChannel *pchan)
                IpoCurve *icu;
                for(icu= achan->ipo->curve.first; icu; icu= icu->next) {
                        void *poin= get_pchan_ipo_poin(pchan, icu->adrcode);
-                       if(poin) write_ipo_poin(poin, IPO_FLOAT, icu->curval);
+                       if(poin) {
+                         write_ipo_poin(poin, IPO_FLOAT, icu->curval);
+                         //printf("execute_action_ipo wrote_ipo_poin: %f\n", icu->curval);
+                         //printf("%s has poin %p value %f\n", achan->name, poin, icu->curval);
+                       }
                }
        }
 }
index 38c54d959569dff912bd7db12c9147c3b07e8125..06611ec6dda741c7a47dd2140d6076eb6a08ac75 100644 (file)
@@ -143,6 +143,8 @@ void duplicate_ipo_keys(struct Ipo *ipo);
 void borderselect_ipo_key(struct Ipo *ipo, float xmin, float xmax, int val);
 void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax, 
                                                  int (*select_function)(struct BezTriple *));
+void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restPos[][4]);
+void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue);
 
 void select_ipo_key(struct Ipo *ipo, float selx, int sel);
 void select_icu_key(struct IpoCurve *icu, float selx, int selectmode);
index aa835780b1a1b5e15459d708969f7809c6354bbe..f1441e7b720207a3a70cfcfd98bf0ec0df69ee7e 100644 (file)
@@ -207,6 +207,7 @@ extern UserDef U; /* from usiblender.c !!!! */
 #define USER_LOCKAROUND        4096
 #define USER_GLOBALUNDO        8192
 #define USER_ORBIT_SELECTION   16384
+#define USER_KEYINSERTAVAI             32768
 #define USER_HIDE_DOT                  65536
 
 /* transopts */
index 51d1101e74a9e330ebaf785f4b9daa8fe3bcf591..c7a597c62c936f82a752e1c4bdd8b4c8f885910a 100644 (file)
@@ -34,6 +34,7 @@ source_files = ['BPY_interface.c',
                 'api2_2x/Noise.c',
                 'api2_2x/NMesh.c',
                 'api2_2x/Object.c',
+                'api2_2x/Pose.c',
                 'api2_2x/point.c',
                 'api2_2x/Registry.c',
                 'api2_2x/Scene.c',
index a07f15b3cab62719c9f685072d121cca1cc685c7..c1ed37bfe43b798db3bac340ee4121f8eeecbe11 100644 (file)
@@ -79,6 +79,7 @@ static PyObject *Action_getName( BPy_Action * self );
 static PyObject *Action_setName( BPy_Action * self, PyObject * args );
 static PyObject *Action_setActive( BPy_Action * self, PyObject * args );
 static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args );
+static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args );
 static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args );
 static PyObject *Action_getAllChannelIpos( BPy_Action * self );
 
@@ -95,6 +96,8 @@ static PyMethodDef BPy_Action_methods[] = {
         "(str) -set this action as the active action for an object"},
        {"getChannelIpo", ( PyCFunction ) Action_getChannelIpo, METH_VARARGS,
         "(str) -get the Ipo from a named action channel in this action"},
+       {"verifyChannel", ( PyCFunction ) Action_verifyChannel, METH_VARARGS,
+        "(str) -verify the channel in this action"},
        {"removeChannel", ( PyCFunction ) Action_removeChannel, METH_VARARGS,
         "(str) -remove the channel from the action"},
        {"getAllChannelIpos", ( PyCFunction ) Action_getAllChannelIpos,
@@ -317,6 +320,27 @@ static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args )
        return Ipo_CreatePyObject( chan->ipo );
 }
 
+//----------------------------------------------------------------------
+static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args )
+{
+       char *chanName;
+       bActionChannel *chan;
+
+       if( !self->action )
+               ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                        "couldn't create channel for a NULL action" ) );
+
+       if( !PyArg_ParseTuple( args, "s", &chanName ) )
+               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
+                                               "expected string argument" ) );
+
+       chan = verify_action_channel(self->action, chanName);
+
+       Py_INCREF( Py_None );
+       return Py_None;
+}
+
+
 static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args )
 {
        char *chanName;
index b8430b3e348ff7dd35fd41ede35935a8a95d7ddf..00d948eb7fc796f9eadb2f110e26ea0cbb16df65 100644 (file)
@@ -77,6 +77,7 @@ struct rctf;
 #include "Curve.h"
 #include "Ipo.h"
 #include "Armature.h"
+#include "Pose.h"
 #include "Camera.h"
 #include "Lamp.h"
 #include "Lattice.h"
@@ -181,6 +182,7 @@ static PyObject *Object_getTracked( BPy_Object * self );
 static PyObject *Object_getType( BPy_Object * self );
 static PyObject *Object_getBoundBox( BPy_Object * self );
 static PyObject *Object_getAction( BPy_Object * self );
+static PyObject *Object_getPose( BPy_Object * self );
 static PyObject *Object_isSelected( BPy_Object * self );
 static PyObject *Object_makeDisplayList( BPy_Object * self );
 static PyObject *Object_link( BPy_Object * self, PyObject * args );
@@ -198,6 +200,9 @@ static PyObject *Object_setMatrix( BPy_Object * self, PyObject * args );
 static PyObject *Object_setIpo( BPy_Object * self, PyObject * args );
 static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args );
 static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args );
+static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args );
+static PyObject *Object_insertMatrixKey( BPy_Object * self, PyObject * args );
+static PyObject *Object_bake_to_action( BPy_Object * self, PyObject * args );
 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args );
 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args );
 static PyObject *Object_setName( BPy_Object * self, PyObject * args );
@@ -295,6 +300,8 @@ If 'name_only' is nonzero or True, only the name of the datablock is returned"},
         "Returns the object draw type"},
        {"getAction", ( PyCFunction ) Object_getAction, METH_NOARGS,
         "Returns the active action for this object"},
+       {"getPose", ( PyCFunction ) Object_getPose, METH_NOARGS,
+        "Returns the pose for this object"},
        {"isSelected", ( PyCFunction ) Object_isSelected, METH_NOARGS,
         "Return a 1 or 0 depending on whether the object is selected"},
        {"getEuler", ( PyCFunction ) Object_getEuler, METH_NOARGS,
@@ -520,6 +527,12 @@ works only if self and the object specified are of the same type."},
         "( Object IPO type ) - Inserts a key into IPO"},
         {"insertPoseKey", ( PyCFunction ) Object_insertPoseKey, METH_VARARGS,
         "( Object Pose type ) - Inserts a key into Action"},
+        {"insertCurrentPoseKey", ( PyCFunction ) Object_insertCurrentPoseKey, METH_VARARGS,
+        "( Object Pose type ) - Inserts a key into Action based on current pose"},
+        {"insertMatrixKey", ( PyCFunction ) Object_insertMatrixKey, METH_VARARGS,
+        "(  ) - Inserts a key into Action based on current/giventime object matrix"},
+        {"bake_to_action", ( PyCFunction ) Object_bake_to_action, METH_VARARGS,
+        "(  ) - creates a new action with the information from object animations"},
        {"getAllProperties", ( PyCFunction ) Object_getAllProperties,
         METH_NOARGS,
         "() - Get all the properties from this object"},
@@ -1096,6 +1109,15 @@ static PyObject *Object_getAction( BPy_Object * self )
        }
 }
 
+static PyObject *Object_getPose( BPy_Object * self )
+{
+       /*BPy_Action *py_action = NULL; */
+
+       if( !self->object->pose )
+               Py_RETURN_NONE;
+       else 
+               return Pose_CreatePyObject( self->object->pose );
+}
 
 static PyObject *Object_isSelected( BPy_Object * self )
 {
@@ -2060,29 +2082,48 @@ static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args )
 
 /*
  * Object_insertPoseKey()
- *  inserts Action Pose key (for LOC, ROT, SIZE, LOCROT, or LOCROTSIZE)
+ *  inserts a Action Pose key from a given pose (sourceaction, frame) to the active action to a given framenum
  */
 
 static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args )
 {
        Object *ob= self->object;
+       BPy_Action *sourceact;
        char *chanName;
+       int actframe;
+
+       //for debug prints
+       bActionChannel *achan;
+       bPoseChannel *pchan;
 
        /* for doing the time trick, similar to editaction bake_action_with_client() */
        int oldframe;
        int curframe;
 
-       if( !PyArg_ParseTuple( args, "si", &chanName, &curframe ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,                                                                           "expected a string and an int argument" ) );
+       if( !PyArg_ParseTuple( args, "O!sii", &Action_Type, &sourceact, &chanName, &actframe, &curframe ) )
+               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,                                                                           "expects an action to copy poses from, a string for chan/bone name, an int argument for frame-to-extract from the action and finally another int for the frame where to put the new key in the active object.action" ) );
+
+       printf("%s %s %d %d, ", sourceact->action->id.name, chanName, actframe, curframe);
+       printf("%s\n", ob->action->id.name);
+       
+       /*  */
+       extract_pose_from_action(ob->pose, sourceact->action, actframe);
 
        oldframe = G.scene->r.cfra;
        G.scene->r.cfra = curframe;
-
-       /* Apply the object ipo */
-       /* uses the current action of the object */
-       extract_pose_from_action(ob->pose, ob->action, curframe);
-       where_is_pose(ob);
-
+       
+       //debug
+       pchan = get_pose_channel(ob->pose, chanName);
+       printquat(pchan->name, pchan->quat);
+
+       achan = get_action_channel(sourceact->action, chanName);
+       if(achan->ipo) {
+         IpoCurve* icu;
+         for (icu = achan->ipo->curve.first; icu; icu=icu->next){
+           printvecf("bezt", icu->bezt->vec[1]);
+           }
+       }
+       
        insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X);
        insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y);
        insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z);
@@ -2094,6 +2135,123 @@ static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args )
        insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y);
        insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z);
        
+       /*
+       for (achan = ob->action->chanbase.first; achan; achan=achan->next) {
+         if(achan->ipo) {
+           IpoCurve* icu;
+           for (icu = achan->ipo->curve.first; icu; icu=icu->next){
+             printf("result: %f %f %f %f", icu->bp->vec[0], icu->bp->vec[1], icu->bp->vec[2], icu->bp->vec[3]);
+           }
+         }
+       }
+       */
+
+       G.scene->r.cfra = oldframe;
+
+       allspace(REMAKEIPO, 0);
+       EXPP_allqueue(REDRAWIPO, 0);
+       EXPP_allqueue(REDRAWVIEW3D, 0);
+       EXPP_allqueue(REDRAWACTION, 0);
+       EXPP_allqueue(REDRAWNLA, 0);
+
+       /* restore, but now with the new action in place */
+       //extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra);
+       //where_is_pose(ob);
+       
+       allqueue(REDRAWACTION, 1);
+
+       return EXPP_incr_ret( Py_None );
+}
+
+static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args )
+{
+  Object *ob= self->object;
+  //bPoseChannel *pchan; //for iterating over all channels in object->pose
+  char *chanName;
+
+  /* for doing the time trick, similar to editaction bake_action_with_client() */
+  int oldframe;
+  int curframe;
+
+  if( !PyArg_ParseTuple( args, "si", &chanName, &curframe ) )
+    return ( EXPP_ReturnPyObjError( PyExc_AttributeError,                                                                              "expected chan/bone name, and a time (int) argument" ) );
+
+  oldframe = G.scene->r.cfra;
+  G.scene->r.cfra = curframe;
+  
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y);
+  insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z);
+
+  G.scene->r.cfra = oldframe;
+
+  allspace(REMAKEIPO, 0);
+  EXPP_allqueue(REDRAWIPO, 0);
+  EXPP_allqueue(REDRAWVIEW3D, 0);
+  EXPP_allqueue(REDRAWACTION, 0);
+  EXPP_allqueue(REDRAWNLA, 0);
+
+  /* restore */
+  extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra);
+  where_is_pose(ob);
+       
+  allqueue(REDRAWACTION, 1);
+
+  return EXPP_incr_ret( Py_None );
+}  
+
+static PyObject *Object_insertMatrixKey( BPy_Object * self, PyObject * args )
+{
+       Object *ob= self->object;
+       char *chanName;
+
+       /* for doing the time trick, similar to editaction bake_action_with_client() */
+       int oldframe;
+       int curframe;
+
+       /* for copying the current object/bone matrices to the new action */
+       bPoseChannel *pchan;
+       float localQuat[4];
+       float tmat[4][4], startpos[4][4];
+
+       //to get the matrix
+       bArmature *arm;
+       Bone      *bone;
+               
+       if( !PyArg_ParseTuple( args, "si", &chanName,  &curframe ) )
+         return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expects a string for chan/bone name and an int for the frame where to put the new key" ) );
+       
+       oldframe = G.scene->r.cfra;
+       G.scene->r.cfra = curframe;
+
+       //just to get the armaturespace mat
+       arm = get_armature(ob);
+       for (bone = arm->bonebase.first; bone; bone=bone->next)
+         if (bone->name == chanName) break;
+         //XXX does not check for if-not-found
+
+       where_is_object(ob);
+       world2bonespace(tmat, ob->obmat, bone->arm_mat, startpos);
+       Mat4ToQuat(tmat, localQuat);
+
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X, tmat[3][0]);
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y, tmat[3][1]);
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z, tmat[3][2]);
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W, localQuat[0]);
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X, localQuat[1]);
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y, localQuat[2]);
+       insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z, localQuat[3]);
+       //insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X, );
+       //insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y);
+       //insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z);
+       
        allspace(REMAKEIPO, 0);
        EXPP_allqueue(REDRAWIPO, 0);
        EXPP_allqueue(REDRAWVIEW3D, 0);
@@ -2102,7 +2260,7 @@ static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args )
 
        G.scene->r.cfra = oldframe;
 
-       /* restore */
+       /* restore, but now with the new action in place */
        extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra);
        where_is_pose(ob);
        
@@ -2111,7 +2269,26 @@ static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args )
        return EXPP_incr_ret( Py_None );
 }
 
+static PyObject *Object_bake_to_action( BPy_Object * self, PyObject * args )
+{
+       Object *ob= self->object;
+
+       /* for doing the time trick, similar to editaction bake_action_with_client() */
+       //int oldframe;
+       //int curframe;
+
+       //if( !PyArg_ParseTuple( args, "i", &curframe ) )
+       //  return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expects an int for the frame where to put the new key" ) );
+       
+       //oldframe = G.scene->r.cfra;
+       //G.scene->r.cfra = curframe;
+
+       bake_all_to_action(); //ob);
 
+       //G.scene->r.cfra = oldframe;
+
+       return EXPP_incr_ret( Py_None );
+}
 
 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args )
 {
index 6f5bbac6a3a5d19f8a5ca60db2992a2442df4356..8eb2ed3c2cbe8f00224f9b887fba0b5b5db39a7a 100644 (file)
@@ -48,6 +48,7 @@ struct PyMethodDef Null_methods[] = { {NULL, NULL, 0, NULL} };
 void types_InitAll( void )
 {
        Action_Type.ob_type = &PyType_Type;
+       Pose_Type.ob_type = &PyType_Type;
        Armature_Type.ob_type = &PyType_Type;
        BezTriple_Type.ob_type = &PyType_Type;
        Bone_Type.ob_type = &PyType_Type;
@@ -183,6 +184,8 @@ PyObject *Types_Init( void )
                              ( PyObject * ) &BezTriple_Type );
        PyDict_SetItemString( dict, "ActionType",
                              ( PyObject * ) &Action_Type );
+       PyDict_SetItemString( dict, "PoseType",
+                             ( PyObject * ) &Pose_Type );
        PyDict_SetItemString( dict, "propertyType",
                              ( PyObject * ) &property_Type );
        PyDict_SetItemString( dict, "pointType",
index ea8a80a1a9899b3b0fef44216e15ea6f352e5714..349c4af545b3fb887064149cc60ab880872e1bf1 100644 (file)
@@ -36,6 +36,7 @@
 #include <Python.h>
 
 extern PyTypeObject Action_Type, Armature_Type;
+extern PyTypeObject Pose_Type;
 extern PyTypeObject BezTriple_Type, Bone_Type, Button_Type;
 extern PyTypeObject Camera_Type;
 extern PyTypeObject CurNurb_Type;
index 118bdee813f96afd2eadda0ea373e10f36ae2035..42c4020572771b7aaa9c7b601f0bbd49b5847e4c 100644 (file)
@@ -2148,46 +2148,6 @@ static void numbuts_action(void)
     }
 }
 
-static void insert_test(void)
-{
-       Object *ob= OBACT;
-       bActionChannel *achan;
-       int oldframe;
-       
-       if(ob==NULL || ob->pose==NULL || ob->action==NULL) return;
-       printf("In the call\n");
-       
-       /* uses the current action of the object */
-       extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra);
-       
-       oldframe = G.scene->r.cfra;
-       G.scene->r.cfra = G.rt;
-       
-       for (achan = ob->action->chanbase.first; achan; achan=achan->next) {
-               if(achan->ipo) {
-                       printf("inserted %s\n", achan->name);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_LOC_X);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_LOC_Y);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_LOC_Z);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_QUAT_X);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_QUAT_Y);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_QUAT_Z);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_QUAT_W);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_SIZE_X);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_SIZE_Y);
-                       insertkey(&ob->id, ID_PO, achan->name, NULL, AC_SIZE_Z);
-               }
-       }
-       
-       G.scene->r.cfra = oldframe;
-       
-       allspace(REMAKEIPO, 0);
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue(REDRAWACTION, 0);
-       allqueue(REDRAWNLA, 0);
-       allqueue(REDRAWACTION, 1);
-}
-
 void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
 {
        extern void do_actionbuts(unsigned short event); // drawaction.c
@@ -2775,3 +2735,169 @@ void bottom_sel_action()
        allqueue(REDRAWIPO, 0);
        allqueue(REDRAWNLA, 0);
 }
+
+void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4])
+{
+       float imatarm[4][4], imatbone[4][4], tmat[4][4], t2mat[4][4];
+       
+       Mat4Invert(imatarm, armPos);
+       Mat4Invert(imatbone, restPos);
+       Mat4MulMat4(tmat, imatarm, worldSpace);
+       Mat4MulMat4(t2mat, tmat, imatbone);
+       Mat4MulMat4(boneSpaceMat, restPos, t2mat);
+}
+
+
+bAction* bake_obIPO_to_action (Object *ob)
+{
+       bArmature               *arm;
+       bAction                 *result=NULL;
+       bActionChannel  *achan;
+       bAction                 *temp;
+       bPoseChannel    *pchan;
+       Bone                    *bone;
+       ID                              *id;
+       ListBase                elems;
+       float                   actstart, actend;
+       int                     oldframe,testframe;
+       int                     curframe;
+       char                    newname[64];
+       float                   quat[4],tmat[4][4],startpos[4][4],imat[4][4],mat3[3][3];
+       CfraElem                *firstcfra, *lastcfra;
+       
+       arm = get_armature(ob);
+       
+       if (arm) {      
+       
+               oldframe = CFRA;
+               result = add_empty_action(ID_PO);
+               id = (ID *)ob;
+               
+               sprintf (newname, "TESTOBBAKE");
+               rename_id(&result->id, newname);
+               
+               if(ob!=G.obedit) { // make sure object is not in edit mode
+                       if(ob->ipo) {
+                               /* convert the ipo to a list of 'current frame elements' */
+                               
+                               temp = ob->action;
+                               ob->action = result;
+                               
+                               elems.first= elems.last= NULL;
+                               make_cfra_list(ob->ipo, &elems);
+                               /* set the beginning armature location */
+                               firstcfra=elems.first;
+                               lastcfra=elems.last;
+                               CFRA=firstcfra->cfra;
+                               
+                               where_is_object(ob);
+                               Mat4CpyMat4(startpos,ob->obmat);
+                               
+                               /* loop from first key to last, sampling every 10 */
+                               for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) { 
+                                       CFRA=testframe;
+                                       where_is_object(ob);
+
+                                       for (bone = arm->bonebase.first; bone; bone=bone->next) {
+                                               if (!bone->parent) { /* this is a root bone, so give it a key! */
+                                                       world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
+                                                       Mat4ToQuat(tmat,quat);
+                                                       printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
+                                                       //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
+                                                       //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
+                                                       //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);
+                                               }
+                                       }
+                               }
+                               BLI_freelistN(&elems);  
+                       }
+               }
+               CFRA = oldframe;
+       }
+       return result;  
+}
+
+bAction* bake_everything_to_action (Object *ob)
+{
+       bArmature               *arm;
+       bAction                 *result=NULL;
+       bActionChannel  *achan;
+       bAction                 *temp;
+       bPoseChannel    *pchan;
+       Bone                    *bone;
+       ID                              *id;
+       ListBase                elems;
+       float                   actstart, actend;
+       int                     oldframe,testframe;
+       int                     curframe;
+       char                    newname[64];
+       float                   quat[4],tmat[4][4],startpos[4][4],imat[4][4],mat3[3][3];
+       CfraElem                *firstcfra, *lastcfra;
+       
+       arm = get_armature(ob);
+       
+       if (arm) {      
+       
+               oldframe = CFRA;
+               result = add_empty_action(ID_PO);
+               id = (ID *)ob;
+               
+               sprintf (newname, "TESTOBBAKE");
+               rename_id(&result->id, newname);
+               
+               if(ob!=G.obedit) { // make sure object is not in edit mode
+                       if(ob->ipo) {
+                               /* convert the ipo to a list of 'current frame elements' */
+                               
+                               temp = ob->action;
+                               ob->action = result;
+                               
+                               elems.first= elems.last= NULL;
+                               make_cfra_list(ob->ipo, &elems);
+                               /* set the beginning armature location */
+                               firstcfra=elems.first;
+                               lastcfra=elems.last;
+                               CFRA=firstcfra->cfra;
+                               
+                               where_is_object(ob);
+                               Mat4CpyMat4(startpos,ob->obmat);
+                               
+                               /* loop from first key to last, sampling every 10 */
+                               for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) { 
+                                       CFRA=testframe;
+                                       
+                                       do_all_pose_actions(ob);
+                                       where_is_object(ob);
+                                       for (bone = arm->bonebase.first; bone; bone=bone->next) {
+                                               if (!bone->parent) { /* this is a root bone, so give it a key! */
+                                                       world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
+                                                       
+                                                       Mat4ToQuat(tmat,quat);
+                                                       printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
+                                                       insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
+                                                       //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
+                                                       //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
+                                                       //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);
+                                               }
+                                       }
+                               }
+                               BLI_freelistN(&elems);  
+                       }
+               }
+               CFRA = oldframe;
+       }
+       return result;  
+}
index 9834bdc704c7a66077c24ebae91cd8fa7637e5ce..3fb48fb417f3db37521955adcd2b463cd5f47d0a 100644 (file)
@@ -1963,6 +1963,42 @@ void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcod
        }
 }
 
+/* For inserting keys based on the object matrix - not on the current IPO value
+   Generically - it inserts the passed float value into the appropriate IPO */
+void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue)
+{
+       IpoCurve *icu;
+       Object *ob;
+       void *poin= NULL;
+       float cfra;
+       int vartype;
+       
+       icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
+       
+       if(icu) {
+               
+               poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+               
+               if(poin) {
+                       
+                       cfra= frame_to_float(CFRA);
+                       
+                       /* if action is mapped in NLA, it returns a correction */
+                       if(actname && actname[0] && GS(id->name)==ID_OB)
+                               cfra= get_action_frame((Object *)id, cfra);
+                       
+                       if( GS(id->name)==ID_OB ) {
+                               ob= (Object *)id;
+                               if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
+                                       /* actually frametofloat calc again! */
+                                       cfra-= ob->sf*G.scene->r.framelen;
+                               }
+                       }
+                       insert_vert_ipo(icu, cfra, matrixvalue);
+               }
+       }
+}
+
 void insertkey_editipo(void)
 {
        EditIpo *ei;
@@ -2340,7 +2376,7 @@ void common_insertkey(void)
                ob= OBACT;
 
                if (ob && (ob->flag & OB_POSEMODE)) {
-                       strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9");
+                       strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13");
                }
                else {
                        base= FIRSTBASE;
@@ -2350,7 +2386,7 @@ void common_insertkey(void)
                        }
                        if(base==NULL) return;
                
-                       strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9");
+                       strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13");
                }
                
                if(ob) {
@@ -2408,6 +2444,25 @@ void common_insertkey(void)
                                                        }
                                                }
                                        }
+                                       if(event==11 || event==13) {
+                                               float obSpaceBoneMat[4][4]; 
+                                               
+                                               bone2objectspace(obSpaceBoneMat, pchan->pose_mat, pchan->bone->arm_mat);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, obSpaceBoneMat[3][0]);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, obSpaceBoneMat[3][1]);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, obSpaceBoneMat[3][2]);
+                                       }
+                                       if(event==12 || event==13) {
+                                               float obSpaceBoneMat[4][4];
+                                               float localQuat[4];
+                                               
+                                               bone2objectspace(obSpaceBoneMat, pchan->pose_mat, pchan->bone->arm_mat);
+                                               Mat4ToQuat(obSpaceBoneMat, localQuat);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, localQuat[0]);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, localQuat[1]);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, localQuat[2]);
+                                               insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, localQuat[2]);
+                                       }
                                }
                        }
                        if(ob->action)
@@ -2460,6 +2515,21 @@ void common_insertkey(void)
                                                insertkey(id, ID_OB, actname, NULL, OB_LAY);
                                                base->object->lay= tlay;
                                        }
+                                       if(event==11 || event==13) {
+                                               insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_X, ob->obmat[3][0]);
+                                               insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Y, ob->obmat[3][1]);
+                                               insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Z, ob->obmat[3][2]);
+                                       }
+                                       if(event==12 || event==13) {
+                                               float eul[3];
+                                               float rotMat[3][3];
+                                               
+                                               Mat3CpyMat4(rotMat, ob->obmat);
+                                               Mat3ToEul(rotMat, eul);
+                                               insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_X, eul[0]*(5.72958));
+                                               insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y, eul[1]*(5.72958));
+                                               insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z, eul[2]*(5.72958));
+                                       }
                                }
                                base= base->next;
                        }
@@ -4454,4 +4524,10 @@ void move_to_frame(void)
        BIF_undo_push("Set frame to selected Ipo vertex");
 }
 
-
+void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restPos[][4])
+{
+       float imat[4][4];
+       Mat4Invert(imat, restPos);
+       Mat4MulMat4(obSpaceBoneMat, obSpace, imat);
+}
index 7708b699b52356da6ab2c546534c317e3800fec3..1679d274d2c7b36df81220eacaad940930992189 100644 (file)
@@ -1577,6 +1577,23 @@ void deselect_nlachannels(int test)
        }       
 }
 
+static Object *get_object_from_active_strip(void) {
+
+       Base *base;
+       bActionStrip *strip;
+       
+       for (base=G.scene->base.first; base; base=base->next) {
+               for (strip = base->object->nlastrips.first; 
+                        strip; strip=strip->next){
+                       if (strip->flag & ACTSTRIP_SELECT) {
+                               return base->object;
+                       }
+               }
+       }
+       return NULL;
+}
+
+
 void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
 {
        unsigned short event= evt->event;
@@ -1587,6 +1604,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
        float dx,dy;
        int     cfra;
        short mousebut = L_MOUSE;
+       Object          *ob; //in shift-B / bake
        
        if (curarea->win==0) return;
        if (!snla) return;
@@ -1646,8 +1664,17 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                break;
                                
                        case BKEY:
-                               borderselect_nla();
-                               break;
+                         if (G.qual & LR_SHIFTKEY){
+                           bake_all_to_action();
+                           allqueue (REDRAWNLA, 0);
+                           allqueue (REDRAWVIEW3D, 0);
+                           BIF_undo_push("Bake All To Action");
+                           ob = get_object_from_active_strip();
+                           //build_match_caches(ob);
+                         }
+                         else
+                           borderselect_nla();
+                         break;
                                
                        case CKEY:
                                convert_nla(mval);
@@ -1763,3 +1790,91 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
        if(doredraw) scrarea_queue_winredraw(curarea);
 }
 
+static void add_nla_block_by_name(char name[32], Object *ob, short hold, short add, float repeat)
+{
+       bAction *act=NULL;
+       bActionStrip *strip;
+       int             cur;
+
+       if (name){
+               for (cur = 1, act=G.main->action.first; act; act=act->id.next, cur++){
+                       if (strcmp(name,act->id.name)==0) {
+                               break;
+                       }
+               }
+       }
+       
+       /* Bail out if no action was chosen */
+       if (!act){
+               return;
+       }
+       
+       /* Initialize the new action block */
+       strip = MEM_callocN(sizeof(bActionStrip), "bActionStrip");
+       
+       deselect_nlachannel_keys(0);
+       
+       /* Link the action to the strip */
+       strip->act = act;
+       calc_action_range(strip->act, &strip->actstart, &strip->actend);
+       strip->start = G.scene->r.cfra;         /* could be mval[0] another time... */
+       strip->end = strip->start + (strip->actend-strip->actstart);
+               /* simple prevention of zero strips */
+       if(strip->start>strip->end-2) 
+               strip->end= strip->start+100;
+       
+       strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION; //|ACTSTRIP_USEMATCH;
+       
+       if (hold==1)
+               strip->flag = strip->flag|ACTSTRIP_HOLDLASTFRAME;
+               
+       if (add==1)
+               strip->mode = ACTSTRIPMODE_ADD;
+       
+       find_stridechannel(ob, strip);
+       
+       set_active_strip(ob, strip);
+       
+       strip->repeat = repeat;
+       
+       act->id.us++;
+       
+       BLI_addtail(&ob->nlastrips, strip);
+
+       BIF_undo_push("Add NLA strip");
+}
+
+void bake_all_to_action(void)
+{
+       Object          *ob;
+       bAction         *newAction=NULL;
+       Ipo             *ipo=NULL;
+       ID              *id;
+       short           hold, add;
+       float           repeat;
+
+       /* burn object-level motion into a new action */
+       ob = get_object_from_active_strip();
+       if (ob) {
+               if (ob->flag&OB_ARMATURE) {
+                       newAction = bake_obIPO_to_action(ob);
+                       if (newAction) {
+                               /* unlink the object's IPO */
+                               ipo=ob->ipo;
+                               if (ipo) {
+                                       id = &ipo->id;
+                                       if (id->us > 0)
+                                               id->us--;
+                                       ob->ipo = NULL;
+                               }
+                               
+                               /* add the new Action to NLA as a strip */
+                               hold=1;
+                               add=1;
+                               repeat=1.0;
+                               printf("about to add nla block...\n");
+                               add_nla_block_by_name(newAction->id.name, ob, hold, add, repeat);
+                       }
+               }
+       }
+}
index 67517b163deff8cf7cb8be6ac75e3593dbab76a8..899acdb41361abed595355d8ddce066866a8eb70 100644 (file)
@@ -2678,10 +2678,15 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                uiDefBut(block, LABEL,0,"Auto keyframe",
                        (xpos+(2*edgsp)+(2*mpref)+midsp),y3label,mpref,buth,
                        0, 0, 0, 0, 0, "");
+
                uiDefButBitI(block, TOG, G_RECORDKEYS, REDRAWTIME, "Action and Object", 
                                        (xpos+edgsp+(2*mpref)+(2*midsp)),y2,mpref, buth,
                                         &(G.flags), 0, 0, 0, 0, "Automatic keyframe insertion in Object and Action Ipo curves");
 
+               uiDefButBitI(block, TOG, USER_KEYINSERTAVAI, REDRAWTIME, "Available", 
+                       (xpos+edgsp+(2*mpref)+(2*midsp)),y1,mpref, buth,
+                       &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in available curves");
+
 //             uiDefButBitS(block, TOG, USER_KEYINSERTACT, 0, "Action",
 //                     (xpos+edgsp+(2*mpref)+(2*midsp)),y2,(spref+edgsp),buth,
 //                     &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in Action Ipo curve");
index bb454270d2facbb78db202c459d1310a6655ab07..82b5c63d4cbf91561db0107cfa390cacdcfffa8e 100755 (executable)
@@ -2027,6 +2027,7 @@ void special_aftertrans_update(TransInfo *t)
 {
        Object *ob;
        Base *base;
+       IpoCurve *icu;
        int redrawipo=0;
        int cancelled= (t->state == TRANS_CANCEL);
                
@@ -2073,19 +2074,36 @@ void special_aftertrans_update(TransInfo *t)
                        
                        for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
                                if (pchan->bone->flag & BONE_TRANSFORM){
-                                       
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
-                                       
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
-                                       
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
-                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+
+                                       if(U.uiflag & USER_KEYINSERTAVAI) {
+                                               bActionChannel *achan; 
+
+                                               for (achan = act->chanbase.first; achan; achan=achan->next){
+
+                                                       if (achan->ipo && !strcmp (achan->name, pchan->name)){
+                                                               for (icu = achan->ipo->curve.first; icu; icu=icu->next){
+                                                                       insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
+                                                               }
+
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       else{
+
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
+
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
+
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
+                                               insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+                                       }
                                }
                        }
                        
@@ -2122,22 +2140,36 @@ void special_aftertrans_update(TransInfo *t)
                        /* Set autokey if necessary */
                        if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){
                                char *actname="";
-                               
+
                                if(ob->ipoflag & OB_ACTION_OB)
                                        actname= "Object";
-                               
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
-                       
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
-                       
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
-                               insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
-                               
+
+                               if(U.uiflag & USER_KEYINSERTAVAI) {
+                                       if(base->object->ipo) {
+                                               ID* id= (ID *)(base->object);
+                                               icu= base->object->ipo->curve.first;
+                                               while(icu) {
+                                                       icu->flag &= ~IPO_SELECT;
+                                                       insertkey(id, ID_OB, actname, NULL, icu->adrcode);
+                                                       icu= icu->next;
+                                               }
+                                       }
+                               }
+                               else {
+
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
+
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
+
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
+                                       insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
+                               }
+
                                remake_object_ipos (ob);
                                allqueue(REDRAWIPO, 0);
                                allspace(REMAKEIPO, 0);