== Keyframing - Cleanup of API ==
* Moved all keyframing functions to their own file (keyframing.c) * Merged all the different keyframing options (needed, visual, fast) into a single API call. The direct benefit of this is that it allows them to be used in conjunction with each other. Also, this means that when using the IKEY, autokeying settings for these are respected too. * Implemented 'keyingsets' system (instead of directly calling insertkey on relevant channels), which is easier to maintain and cleaner. A keyingset basically defines all the channels that can be keyframed together. This paves the way for custom keyingsets sometime down the track (and also for quick-insert keyframes for previously used keyingset). Menus for choosing the keying set to use are generated automatically from the definitions.
This commit is contained in:
99
source/blender/include/BIF_keyframing.h
Normal file
99
source/blender/include/BIF_keyframing.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* $Id: BDR_gpencil.h 14444 2008*04*16 22:40:48Z aligorith $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place * Suite 330, Boston, MA 02111*1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation
|
||||
* This is a new part of Blender (with some old code)
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BIF_KEYFRAMING_H
|
||||
#define BIF_KEYFRAMING_H
|
||||
|
||||
struct ListBase;
|
||||
struct ID;
|
||||
|
||||
struct IpoCurve;
|
||||
struct BezTriple;
|
||||
|
||||
/* ************ Keyframing Management **************** */
|
||||
|
||||
/* Lesser Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it already
|
||||
* exists, and there is a beztriple that can be directly copied into the array.
|
||||
*/
|
||||
int insert_bezt_icu(struct IpoCurve *icu, struct BezTriple *bezt);
|
||||
|
||||
/* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it
|
||||
* already exists. It will insert a keyframe using the current value being keyframed.
|
||||
*/
|
||||
void insert_vert_icu(struct IpoCurve *icu, float x, float y, short flag);
|
||||
|
||||
|
||||
/* flags for use in insert_key(), and insert_vert_icu() */
|
||||
enum {
|
||||
INSERTKEY_NEEDED = (1<<0), /* only insert keyframes where they're needed */
|
||||
INSERTKEY_MATRIX = (1<<1), /* insert 'visual' keyframes where possible/needed */
|
||||
INSERTKEY_FAST = (1<<2), /* don't recalculate handles,etc. after adding key */
|
||||
INSERTKEY_FASTR = (1<<3), /* don't realloc mem (or increase count, as array has already been set out) */
|
||||
INSERTKEY_REPLACE = (1<<4), /* only replace an existing keyframe (this overrides INSERTKEY_NEEDED) */
|
||||
} eInsertKeyFlags;
|
||||
|
||||
/* -------- */
|
||||
|
||||
/* Main Keyframing API calls:
|
||||
* Use this to create any necessary animation data,, and then insert a keyframe
|
||||
* using the current value being keyframed, in the relevant place. Returns success.
|
||||
*/
|
||||
// TODO: adapt this for new data-api -> this blocktype, etc. stuff is evil!
|
||||
short insertkey(struct ID *id, int blocktype, char *actname, char *constname, int adrcode, short flag);
|
||||
|
||||
/* Main Keyframing API call:
|
||||
* Use this to delete keyframe on current frame for relevant channel. Will perform checks just in case.
|
||||
*/
|
||||
short deletekey(struct ID *id, int blocktype, char *actname, char *constname, int adrcode, short flag);
|
||||
|
||||
|
||||
/* Main Keyframe Management calls:
|
||||
* These handle keyframes management from various spaces. They will handle the menus
|
||||
* required for each space.
|
||||
*/
|
||||
void common_insertkey(void);
|
||||
void common_deletekey(void);
|
||||
|
||||
/* ************ Keyframe Checking ******************** */
|
||||
|
||||
/* Checks whether a keyframe exists for the given ID-block one the given frame */
|
||||
short id_cfra_has_keyframe(struct ID *id, short filter);
|
||||
|
||||
/* filter flags fr id_cfra_has_keyframe */
|
||||
enum {
|
||||
/* general */
|
||||
ANIMFILTER_ALL = 0, /* include all available animation data */
|
||||
ANIMFILTER_LOCAL = (1<<0), /* only include locally available anim data */
|
||||
|
||||
/* object specific */
|
||||
ANIMFILTER_MAT = (1<<1), /* include material keyframes too */
|
||||
ANIMFILTER_SKEY = (1<<2), /* shape keys (for geometry) */
|
||||
} eAnimFilterFlags;
|
||||
|
||||
#endif /* BIF_KEYFRAMING_H */
|
||||
@@ -90,9 +90,6 @@ struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int
|
||||
struct Ipo *verify_ipo(struct ID *, short, char *, char *, char *);
|
||||
int texchannel_to_adrcode(int channel);
|
||||
|
||||
int insert_bezt_icu(struct IpoCurve *icu, struct BezTriple *bezt);
|
||||
void insert_vert_icu(struct IpoCurve *icu, float x, float y, short fast);
|
||||
void add_vert_ipo(void);
|
||||
|
||||
void add_duplicate_editipo(void);
|
||||
void remove_doubles_ipo(void);
|
||||
@@ -121,10 +118,8 @@ void paste_editipo(void);
|
||||
void set_exprap_ipo(int mode);
|
||||
|
||||
void set_speed_editipo(float speed);
|
||||
void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, short fast);
|
||||
void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, int adrcode);
|
||||
void insertkey_editipo(void);
|
||||
void common_insertkey(void);
|
||||
void add_vert_ipo(void);
|
||||
void free_ipokey(struct ListBase *lb);
|
||||
void add_to_ipokey(struct ListBase *lb, struct BezTriple *bezt, int nr, int len);
|
||||
void make_ipokey(void);
|
||||
@@ -163,8 +158,6 @@ 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 *));
|
||||
int insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode);
|
||||
void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float floatkey);
|
||||
void select_ipo_key(struct Ipo *ipo, float selx, int sel);
|
||||
void select_icu_key(struct IpoCurve *icu, float selx, int selectmode);
|
||||
void setexprap_ipoloop(struct Ipo *ipo, int code);
|
||||
|
||||
@@ -277,7 +277,9 @@ typedef enum POSE_FLAG {
|
||||
/* clears the POSE_LOCKED flag for the next time the pose is evaluated */
|
||||
POSE_DO_UNLOCK = (1<<2),
|
||||
/* pose has constraints which depend on time (used when depsgraph updates for a new frame) */
|
||||
POSE_CONSTRAINTS_TIMEDEPEND = (1<<3)
|
||||
POSE_CONSTRAINTS_TIMEDEPEND = (1<<3),
|
||||
/* recalculate bone paths */
|
||||
POSE_RECALCPATHS = (1<<4),
|
||||
} POSE_FLAG;
|
||||
|
||||
/* PoseChannel (transform) flags */
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h" /* for M_PI */
|
||||
#include "BSE_editipo.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_space.h"
|
||||
#include "mydevice.h"
|
||||
#include "gen_utils.h"
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "BKE_constraint.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BIF_editconstraint.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "mydevice.h"
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_space.h"
|
||||
#include "mydevice.h"
|
||||
#include "constant.h"
|
||||
|
||||
@@ -81,6 +81,7 @@ struct rctf;
|
||||
#include "BIF_editarmature.h"
|
||||
#include "BIF_editaction.h"
|
||||
#include "BIF_editnla.h"
|
||||
#include "BIF_keyframing.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_space_types.h" //1 - this order
|
||||
#include "BSE_editipo.h" //2
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "Mathutils.h"
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "BKE_texture.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_space.h"
|
||||
#include "mydevice.h"
|
||||
#include "Ipo.h"
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
#include "BIF_editview.h"
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_screen.h"
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
#include "BIF_editseq.h"
|
||||
#include "BIF_editview.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_screen.h"
|
||||
@@ -2021,185 +2022,6 @@ IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constn
|
||||
}
|
||||
|
||||
|
||||
/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
|
||||
#define BEZT_INSERT_THRESH 0.00001
|
||||
|
||||
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
|
||||
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
||||
*/
|
||||
static int binarysearch_bezt_index (BezTriple array[], BezTriple *item, int arraylen, short *replace)
|
||||
{
|
||||
int start=0, end=arraylen;
|
||||
int loopbreaker= 0, maxloop= arraylen * 2;
|
||||
const float frame= (item)? item->vec[1][0] : 0.0f;
|
||||
|
||||
/* initialise replace-flag first */
|
||||
*replace= 0;
|
||||
|
||||
/* sneaky optimisations (don't go through searching process if...):
|
||||
* - keyframe to be added is to be added out of current bounds
|
||||
* - keyframe to be added would replace one of the existing ones on bounds
|
||||
*/
|
||||
if ((arraylen <= 0) || ELEM(NULL, array, item)) {
|
||||
printf("Warning: binarysearch_bezt_index encountered invalid array \n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* check whether to add before/after/on */
|
||||
float framenum;
|
||||
|
||||
/* 'First' Keyframe (when only one keyframe, this case is used) */
|
||||
framenum= array[0].vec[1][0];
|
||||
if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
|
||||
*replace = 1;
|
||||
return 0;
|
||||
}
|
||||
else if (frame < framenum)
|
||||
return 0;
|
||||
|
||||
/* 'Last' Keyframe */
|
||||
framenum= array[(arraylen-1)].vec[1][0];
|
||||
if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
|
||||
*replace= 1;
|
||||
return (arraylen - 1);
|
||||
}
|
||||
else if (frame > framenum)
|
||||
return arraylen;
|
||||
}
|
||||
|
||||
|
||||
/* most of the time, this loop is just to find where to put it
|
||||
* 'loopbreaker' is just here to prevent infinite loops
|
||||
*/
|
||||
for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
|
||||
/* compute and get midpoint */
|
||||
int mid = (start + end) / 2;
|
||||
float midfra= array[mid].vec[1][0];
|
||||
|
||||
/* check if exactly equal to midpoint */
|
||||
if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH)) {
|
||||
*replace = 1;
|
||||
return mid;
|
||||
}
|
||||
|
||||
/* repeat in upper/lower half */
|
||||
if (frame > midfra)
|
||||
start= mid + 1;
|
||||
else if (frame < midfra)
|
||||
end= mid - 1;
|
||||
}
|
||||
|
||||
/* print error if loop-limit exceeded */
|
||||
if (loopbreaker == (maxloop-1)) {
|
||||
printf("Error: binarysearch_bezt_index was taking too long \n");
|
||||
|
||||
// include debug info
|
||||
printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
|
||||
}
|
||||
|
||||
/* not found, so return where to place it */
|
||||
return start;
|
||||
}
|
||||
|
||||
/* This function adds a given BezTriple to an IPO-Curve. It will allocate
|
||||
* memory for the array if needed, and will insert the BezTriple into a
|
||||
* suitable place in chronological order.
|
||||
*
|
||||
* NOTE: any recalculate of the IPO-Curve that needs to be done will need to
|
||||
* be done by the caller.
|
||||
*/
|
||||
int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
|
||||
{
|
||||
BezTriple *newb;
|
||||
int i= 0;
|
||||
|
||||
if (icu->bezt == NULL) {
|
||||
icu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
|
||||
*(icu->bezt)= *bezt;
|
||||
icu->totvert= 1;
|
||||
}
|
||||
else {
|
||||
short replace = -1;
|
||||
i = binarysearch_bezt_index(icu->bezt, bezt, icu->totvert, &replace);
|
||||
|
||||
if (replace) {
|
||||
/* sanity check: 'i' may in rare cases exceed arraylen */
|
||||
if ((i >= 0) && (i < icu->totvert))
|
||||
*(icu->bezt + i) = *bezt;
|
||||
}
|
||||
else {
|
||||
/* add new */
|
||||
newb= MEM_callocN((icu->totvert+1)*sizeof(BezTriple), "beztriple");
|
||||
|
||||
/* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
|
||||
if (i > 0)
|
||||
memcpy(newb, icu->bezt, i*sizeof(BezTriple));
|
||||
|
||||
/* add beztriple to paste at index i */
|
||||
*(newb + i)= *bezt;
|
||||
|
||||
/* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
|
||||
if (i < icu->totvert)
|
||||
memcpy(newb+i+1, icu->bezt+i, (icu->totvert-i)*sizeof(BezTriple));
|
||||
|
||||
/* replace (+ free) old with new */
|
||||
MEM_freeN(icu->bezt);
|
||||
icu->bezt= newb;
|
||||
|
||||
icu->totvert++;
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to return the index, so that some tools which do post-processing can
|
||||
* detect where we added the BezTriple in the array
|
||||
*/
|
||||
return i;
|
||||
}
|
||||
|
||||
/* This function is a wrapper for insert_bezt_icu, and should be used when
|
||||
* adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
|
||||
* else yet.
|
||||
*
|
||||
* 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
|
||||
*/
|
||||
void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
|
||||
{
|
||||
BezTriple beztr;
|
||||
int a, h1, h2;
|
||||
|
||||
/* set all three points, for nicer start position */
|
||||
memset(&beztr, 0, sizeof(BezTriple));
|
||||
beztr.vec[0][0]= x;
|
||||
beztr.vec[0][1]= y;
|
||||
beztr.vec[1][0]= x;
|
||||
beztr.vec[1][1]= y;
|
||||
beztr.vec[2][0]= x;
|
||||
beztr.vec[2][1]= y;
|
||||
beztr.hide= IPO_BEZ;
|
||||
beztr.f1= beztr.f2= beztr.f3= SELECT;
|
||||
beztr.h1= beztr.h2= HD_AUTO;
|
||||
|
||||
/* add temp beztriple to keyframes */
|
||||
a= insert_bezt_icu(icu, &beztr);
|
||||
if (!fast) calchandles_ipocurve(icu);
|
||||
|
||||
/* set handletype */
|
||||
if (icu->totvert > 2) {
|
||||
BezTriple *bezt;
|
||||
|
||||
h1= h2= HD_AUTO;
|
||||
bezt= (icu->bezt + a);
|
||||
|
||||
if (a > 0) h1= (bezt-1)->h2;
|
||||
if (a < icu->totvert-1) h2= (bezt+1)->h1;
|
||||
|
||||
bezt->h1= h1;
|
||||
bezt->h2= h2;
|
||||
|
||||
if (!fast) calchandles_ipocurve(icu);
|
||||
}
|
||||
}
|
||||
|
||||
void add_vert_ipo(void)
|
||||
{
|
||||
EditIpo *ei;
|
||||
@@ -2259,525 +2081,6 @@ void add_vert_ipo(void)
|
||||
BIF_undo_push("Add Ipo vertex");
|
||||
}
|
||||
|
||||
static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, char *constname, IpoCurve *icu, int *vartype)
|
||||
{
|
||||
if (blocktype==ID_PO) {
|
||||
if (GS(id->name)==ID_OB) {
|
||||
Object *ob= (Object *)id;
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
|
||||
if (pchan) {
|
||||
*vartype= IPO_FLOAT;
|
||||
return get_pchan_ipo_poin(pchan, icu->adrcode);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else if (blocktype==ID_CO) {
|
||||
if ((GS(id->name)==ID_OB) && (constname && constname[0])) {
|
||||
Object *ob= (Object *)id;
|
||||
bConstraint *con;
|
||||
|
||||
/* assume that we only want the influence (as only used for Constraint Channels) */
|
||||
if ((ob->ipoflag & OB_ACTION_OB) && !strcmp(actname, "Object")) {
|
||||
for (con= ob->constraints.first; con; con= con->next) {
|
||||
if (strcmp(constname, con->name)==0) {
|
||||
*vartype= IPO_FLOAT;
|
||||
return &con->enforce;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ob->pose) {
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
|
||||
if (pchan) {
|
||||
for (con= pchan->constraints.first; con; con= con->next) {
|
||||
if (strcmp(constname, con->name)==0) {
|
||||
*vartype= IPO_FLOAT;
|
||||
return &con->enforce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return get_ipo_poin(id, icu, vartype);
|
||||
|
||||
}
|
||||
|
||||
#define KEYNEEDED_DONTADD 0
|
||||
#define KEYNEEDED_JUSTADD 1
|
||||
#define KEYNEEDED_DELPREV 2
|
||||
#define KEYNEEDED_DELNEXT 3
|
||||
|
||||
static int new_key_needed(IpoCurve *icu, float cFrame, float nValue)
|
||||
{
|
||||
/* This function determines whether a new keyframe is needed */
|
||||
/* Cases where keyframes should not be added:
|
||||
* 1. Keyframe to be added bewteen two keyframes with similar values
|
||||
* 2. Keyframe to be added on frame where two keyframes are already situated
|
||||
* 3. Keyframe lies at point that intersects the linear line between two keyframes
|
||||
*/
|
||||
|
||||
BezTriple *bezt=NULL, *prev=NULL;
|
||||
int totCount, i;
|
||||
float valA = 0.0f, valB = 0.0f;
|
||||
|
||||
/* safety checking */
|
||||
if (!icu) return KEYNEEDED_JUSTADD;
|
||||
totCount= icu->totvert;
|
||||
if (totCount==0) return KEYNEEDED_JUSTADD;
|
||||
|
||||
/* loop through checking if any are the same */
|
||||
bezt= icu->bezt;
|
||||
for (i=0; i<totCount; i++) {
|
||||
float prevPosi=0.0f, prevVal=0.0f;
|
||||
float beztPosi=0.0f, beztVal=0.0f;
|
||||
|
||||
/* get current time+value */
|
||||
beztPosi= bezt->vec[1][0];
|
||||
beztVal= bezt->vec[1][1];
|
||||
|
||||
if (prev) {
|
||||
/* there is a keyframe before the one currently being examined */
|
||||
|
||||
/* get previous time+value */
|
||||
prevPosi= prev->vec[1][0];
|
||||
prevVal= prev->vec[1][1];
|
||||
|
||||
/* keyframe to be added at point where there are already two similar points? */
|
||||
if (IS_EQ(prevPosi, cFrame) && IS_EQ(beztPosi, cFrame) && IS_EQ(beztPosi, prevPosi)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
|
||||
/* keyframe between prev+current points ? */
|
||||
if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
|
||||
/* is the value of keyframe to be added the same as keyframes on either side ? */
|
||||
if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
else {
|
||||
float realVal;
|
||||
|
||||
/* get real value of curve at that point */
|
||||
realVal= eval_icu(icu, cFrame);
|
||||
|
||||
/* compare whether it's the same as proposed */
|
||||
if (IS_EQ(realVal, nValue))
|
||||
return KEYNEEDED_DONTADD;
|
||||
else
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
}
|
||||
|
||||
/* new keyframe before prev beztriple? */
|
||||
if (cFrame < prevPosi) {
|
||||
/* A new keyframe will be added. However, whether the previous beztriple
|
||||
* stays around or not depends on whether the values of previous/current
|
||||
* beztriples and new keyframe are the same.
|
||||
*/
|
||||
if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal))
|
||||
return KEYNEEDED_DELNEXT;
|
||||
else
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* just add a keyframe if there's only one keyframe
|
||||
* and the new one occurs before the exisiting one does.
|
||||
*/
|
||||
if ((cFrame < beztPosi) && (totCount==1))
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
|
||||
/* continue. frame to do not yet passed (or other conditions not met) */
|
||||
if (i < (totCount-1)) {
|
||||
prev= bezt;
|
||||
bezt++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* Frame in which to add a new-keyframe occurs after all other keys
|
||||
* -> If there are at least two existing keyframes, then if the values of the
|
||||
* last two keyframes and the new-keyframe match, the last existing keyframe
|
||||
* gets deleted as it is no longer required.
|
||||
* -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
|
||||
* keyframe is not equal to last keyframe.
|
||||
*/
|
||||
bezt= (icu->bezt + (icu->totvert - 1));
|
||||
valA= bezt->vec[1][1];
|
||||
|
||||
if (prev)
|
||||
valB= prev->vec[1][1];
|
||||
else
|
||||
valB= bezt->vec[1][1] + 1.0f;
|
||||
|
||||
if (IS_EQ(valA, nValue) && IS_EQ(valA, valB))
|
||||
return KEYNEEDED_DELPREV;
|
||||
else
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
|
||||
/* a duplicate of insertkey that does not check for routing to insertmatrixkey
|
||||
to avoid recursion problems */
|
||||
static void insertkey_nonrecurs(ID *id, int blocktype, char *actname, char *constname, int adrcode)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
Object *ob;
|
||||
void *poin= NULL;
|
||||
float curval, cfra;
|
||||
int vartype;
|
||||
int matset=0;
|
||||
|
||||
if (matset==0) {
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
|
||||
|
||||
if(poin) {
|
||||
curval= read_ipo_poin(poin, vartype);
|
||||
|
||||
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->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
|
||||
/* actually frametofloat calc again! */
|
||||
cfra-= give_timeoffset(ob)*G.scene->r.framelen;
|
||||
}
|
||||
}
|
||||
|
||||
insert_vert_icu(icu, cfra, curval, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode)
|
||||
{
|
||||
int matindex=0;
|
||||
/* branch on adrcode and blocktype, generating the proper matrix-based
|
||||
values to send to insertfloatkey */
|
||||
if (GS(id->name)==ID_OB) {
|
||||
Object *ob= (Object *)id;
|
||||
|
||||
if ( blocktype==ID_OB ){ //working with an object
|
||||
if ((ob)&&!(ob->parent)) {
|
||||
if ((adrcode==OB_ROT_X)||(adrcode==OB_ROT_Y)||(adrcode==OB_ROT_Z)) { //get a rotation
|
||||
float eul[3];
|
||||
switch (adrcode) {
|
||||
case OB_ROT_X:
|
||||
matindex=0;
|
||||
break;
|
||||
case OB_ROT_Y:
|
||||
matindex=1;
|
||||
break;
|
||||
case OB_ROT_Z:
|
||||
matindex=2;
|
||||
break;
|
||||
}
|
||||
Mat4ToEul(ob->obmat, eul);
|
||||
insertfloatkey(id, ID_OB, actname, NULL, adrcode, eul[matindex]*(5.72958));
|
||||
return 1;
|
||||
} else if ((adrcode==OB_LOC_X)||(adrcode==OB_LOC_Y)||(adrcode==OB_LOC_Z)) {//get a translation
|
||||
switch (adrcode) {
|
||||
case OB_LOC_X:
|
||||
matindex=0;
|
||||
break;
|
||||
case OB_LOC_Y:
|
||||
matindex=1;
|
||||
break;
|
||||
case OB_LOC_Z:
|
||||
matindex=2;
|
||||
break;
|
||||
}
|
||||
insertfloatkey(id, ID_OB, actname, NULL, adrcode, ob->obmat[3][matindex]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if ( blocktype==ID_PO) { //working with a pose channel
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
if (pchan) {
|
||||
if ((adrcode==AC_LOC_X)||(adrcode==AC_LOC_Y)||(adrcode==AC_LOC_Z)) {
|
||||
switch (adrcode) {
|
||||
case AC_LOC_X:
|
||||
matindex=0;
|
||||
break;
|
||||
case AC_LOC_Y:
|
||||
matindex=1;
|
||||
break;
|
||||
case AC_LOC_Z:
|
||||
matindex=2;
|
||||
break;
|
||||
}
|
||||
if (!(pchan->bone->parent)||((pchan->bone->parent)&&!(pchan->bone->flag&BONE_CONNECTED))) { /* don't use for non-connected child bones */
|
||||
float delta_mat[4][4];
|
||||
armature_mat_pose_to_delta(delta_mat, pchan->pose_mat, pchan->bone->arm_mat);
|
||||
insertfloatkey(id, ID_PO, pchan->name, NULL, adrcode, delta_mat[3][matindex]);
|
||||
return 1;
|
||||
}
|
||||
} else if ((adrcode==AC_QUAT_W)||(adrcode==AC_QUAT_X)||(adrcode==AC_QUAT_Y)||(adrcode==AC_QUAT_Z)) {
|
||||
float tmat[4][4], trimat[3][3], localQuat[4];
|
||||
|
||||
switch (adrcode) {
|
||||
case AC_QUAT_W:
|
||||
matindex=0;
|
||||
break;
|
||||
case AC_QUAT_X:
|
||||
matindex=1;
|
||||
break;
|
||||
case AC_QUAT_Y:
|
||||
matindex=2;
|
||||
break;
|
||||
case AC_QUAT_Z:
|
||||
matindex=3;
|
||||
break;
|
||||
}
|
||||
|
||||
/* it should be reasonable to assume that we are keyframing on the active object, although it is not
|
||||
* strictly required for this particular space conversion, arg1 must not be null for this to work
|
||||
*/
|
||||
Mat4CpyMat4(tmat, pchan->pose_mat);
|
||||
constraint_mat_convertspace(OBACT, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
|
||||
|
||||
Mat3CpyMat4(trimat, tmat);
|
||||
Mat3ToQuat_is_ok(trimat, localQuat);
|
||||
insertfloatkey(id, ID_PO, pchan->name, NULL, adrcode, localQuat[matindex]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* failed to set a matrix key -- use traditional, but the non-recursing version */
|
||||
insertkey_nonrecurs(id,blocktype,actname,constname,adrcode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match_adr_constraint(ID * id, int blocktype, char *actname, int adrcode)
|
||||
{ /* This function matches constraint blocks with adrcodes to see if the
|
||||
visual keying method should be used. For example, an object looking to key
|
||||
location and having a CopyLoc constraint would return true. */
|
||||
|
||||
Object *ob=NULL;
|
||||
int foundmatch=0;
|
||||
int searchtype=0;
|
||||
bConstraint *conref=NULL, *con=NULL;
|
||||
|
||||
/*Retrieve constraint list*/
|
||||
if( GS(id->name)==ID_OB )
|
||||
ob= (Object *)id;
|
||||
if (ob) {
|
||||
if (blocktype==ID_PO) {
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
conref=pchan->constraints.first;
|
||||
} else if (blocktype==ID_OB) {
|
||||
conref=ob->constraints.first;
|
||||
}
|
||||
|
||||
if (conref) {
|
||||
/*Set search type: 1 is for translation contraints, 2 is for rotation*/
|
||||
if ((adrcode==OB_LOC_X)||(adrcode==OB_LOC_Y)||(adrcode==OB_LOC_Z)||(adrcode==AC_LOC_X)||(adrcode==AC_LOC_Y)||(adrcode==AC_LOC_Z)) {
|
||||
searchtype=1;
|
||||
} else if ((adrcode==OB_ROT_X)||(adrcode==OB_ROT_Y)||(adrcode==OB_ROT_Z)||(adrcode==AC_QUAT_W)||(adrcode==AC_QUAT_X)||(adrcode==AC_QUAT_Y)||(adrcode==AC_QUAT_Z)) {
|
||||
searchtype=2;
|
||||
}
|
||||
|
||||
if (searchtype>0) {
|
||||
for (con=conref; (con)&&(foundmatch==0); con=con->next) {
|
||||
switch (con->type) {
|
||||
/* match constraint types to which kinds of keying they would affect */
|
||||
case CONSTRAINT_TYPE_CHILDOF:
|
||||
foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_TRACKTO:
|
||||
if (searchtype==2) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_FOLLOWPATH:
|
||||
foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_ROTLIMIT:
|
||||
if (searchtype==2) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCLIMIT:
|
||||
if (searchtype==1) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_ROTLIKE:
|
||||
if (searchtype==2) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCLIKE:
|
||||
if (searchtype==1) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCKTRACK:
|
||||
if (searchtype==2) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_DISTLIMIT:
|
||||
if (searchtype==1) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_MINMAX:
|
||||
if (searchtype==1) foundmatch=1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_TRANSFORM:
|
||||
foundmatch=1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundmatch;
|
||||
|
||||
}
|
||||
|
||||
void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, short fast)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
Object *ob;
|
||||
void *poin= NULL;
|
||||
float curval, cfra;
|
||||
int vartype;
|
||||
int matset=0;
|
||||
|
||||
if ((IS_AUTOKEY_FLAG(AUTOMATKEY))&&(match_adr_constraint(id, blocktype, actname, adrcode))) {
|
||||
matset=insertmatrixkey(id, blocktype, actname, constname, adrcode);
|
||||
}
|
||||
if (matset==0) {
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
|
||||
|
||||
if(poin) {
|
||||
curval= read_ipo_poin(poin, vartype);
|
||||
|
||||
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->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
|
||||
/* actually frametofloat calc again! */
|
||||
cfra-= give_timeoffset(ob)*G.scene->r.framelen;
|
||||
}
|
||||
}
|
||||
|
||||
insert_vert_icu(icu, cfra, curval, fast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This function is a 'smarter' version of the insert key code.
|
||||
* It uses an auxilliary function to check whether a keyframe is really needed */
|
||||
void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, int adrcode)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
Object *ob;
|
||||
void *poin= NULL;
|
||||
float curval, cfra;
|
||||
int vartype;
|
||||
int insert_mode;
|
||||
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
|
||||
|
||||
if(poin) {
|
||||
curval= read_ipo_poin(poin, vartype);
|
||||
|
||||
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->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
|
||||
/* actually frametofloat calc again! */
|
||||
cfra-= give_timeoffset(ob)*G.scene->r.framelen;
|
||||
}
|
||||
}
|
||||
|
||||
/* check whether this curve really needs a new keyframe */
|
||||
insert_mode= new_key_needed(icu, cfra, curval);
|
||||
|
||||
/* insert new keyframe at current frame */
|
||||
if (insert_mode)
|
||||
insert_vert_icu(icu, cfra, curval, 0);
|
||||
|
||||
/* delete keyframe immediately before/after newly added */
|
||||
switch (insert_mode) {
|
||||
case KEYNEEDED_DELPREV:
|
||||
delete_icu_key(icu, icu->totvert-2, 1);
|
||||
break;
|
||||
case KEYNEEDED_DELNEXT:
|
||||
delete_icu_key(icu, 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For inserting keys based on an arbitrary float value */
|
||||
void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float floatkey)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
Object *ob;
|
||||
void *poin= NULL;
|
||||
float cfra;
|
||||
int vartype;
|
||||
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
poin= get_context_ipo_poin(id, blocktype, actname, constname, 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->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
|
||||
/* actually frametofloat calc again! */
|
||||
cfra-= give_timeoffset(ob)*G.scene->r.framelen;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert new keyframe at current frame */
|
||||
insert_vert_icu(icu, cfra, floatkey, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void insertkey_editipo(void)
|
||||
{
|
||||
@@ -2909,598 +2212,6 @@ void insertkey_editipo(void)
|
||||
}
|
||||
|
||||
|
||||
void common_insertkey(void)
|
||||
{
|
||||
Base *base;
|
||||
Object *ob;
|
||||
Material *ma;
|
||||
ID *id;
|
||||
IpoCurve *icu;
|
||||
World *wo;
|
||||
Lamp *la;
|
||||
Tex *te;
|
||||
int tlay, map, event;
|
||||
char menustr[256];
|
||||
|
||||
if(curarea->spacetype==SPACE_IPO) {
|
||||
insertkey_editipo();
|
||||
}
|
||||
else if(curarea->spacetype==SPACE_ACTION) {
|
||||
insertkey_action();
|
||||
}
|
||||
else if(curarea->spacetype==SPACE_BUTS) {
|
||||
if(G.buts->mainb==CONTEXT_SHADING) {
|
||||
int tab= G.buts->tab[CONTEXT_SHADING];
|
||||
|
||||
if(tab==TAB_SHADING_MAT) {
|
||||
ma = G.buts->lockpoin;
|
||||
ma = editnode_get_active_material(ma);
|
||||
id = (ID *)ma;
|
||||
|
||||
if(id) {
|
||||
event= pupmenu("Insert Key %t|RGB%x0|Alpha%x1|Halo Size%x2|Mode %x3|All Color%x10|All Mirror%x14|Ofs%x12|Size%x13|All Mapping%x11");
|
||||
if(event== -1) return;
|
||||
|
||||
map= texchannel_to_adrcode(ma->texact);
|
||||
|
||||
if(event==0 || event==10) {
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_COL_R, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_COL_G, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_COL_B, 0);
|
||||
}
|
||||
if(event==1 || event==10) {
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_ALPHA, 0);
|
||||
}
|
||||
if(event==2 || event==10) {
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_HASIZE, 0);
|
||||
}
|
||||
if(event==3 || event==10) {
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_MODE, 0);
|
||||
}
|
||||
if(event==10) {
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_SPEC_R, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_SPEC_G, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_SPEC_B, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_REF, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_EMIT, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_AMB, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_SPEC, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_HARD, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_MODE, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_TRANSLU, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_ADD, 0);
|
||||
}
|
||||
if(event==14) {
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_RAYM, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_FRESMIR, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_FRESMIRI, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_FRESTRA, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, MA_FRESTRAI, 0);
|
||||
}
|
||||
if(event==12 || event==11) {
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_X, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Y, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Z, 0);
|
||||
}
|
||||
if(event==13 || event==11) {
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_X, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Y, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Z, 0);
|
||||
}
|
||||
if(event==11) {
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_R, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_G, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_B, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_DVAR, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_COLF, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_NORF, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_VARF, 0);
|
||||
insertkey(id, ID_MA, NULL, NULL, map+MAP_DISP, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(tab==TAB_SHADING_WORLD) {
|
||||
id= G.buts->lockpoin;
|
||||
wo= G.buts->lockpoin;
|
||||
if(id) {
|
||||
event= pupmenu("Insert Key %t|Zenith RGB%x0|Horizon RGB%x1|Mist%x2|Stars %x3|Offset%x12|Size%x13");
|
||||
if(event== -1) return;
|
||||
|
||||
map= texchannel_to_adrcode(wo->texact);
|
||||
|
||||
if(event==0) {
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_ZEN_R, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_ZEN_G, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_ZEN_B, 0);
|
||||
}
|
||||
if(event==1) {
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_HOR_R, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_HOR_G, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_HOR_B, 0);
|
||||
}
|
||||
if(event==2) {
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_MISI, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_MISTDI, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_MISTSTA, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_MISTHI, 0);
|
||||
}
|
||||
if(event==3) {
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_STAR_R, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_STAR_G, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_STAR_B, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_STARDIST, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, WO_STARSIZE, 0);
|
||||
}
|
||||
if(event==12) {
|
||||
insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_X, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Y, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Z, 0);
|
||||
}
|
||||
if(event==13) {
|
||||
insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_X, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Y, 0);
|
||||
insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(tab==TAB_SHADING_LAMP) {
|
||||
id= G.buts->lockpoin;
|
||||
la= G.buts->lockpoin;
|
||||
if(id) {
|
||||
event= pupmenu("Insert Key %t|RGB%x0|Energy%x1|Spot Size%x2|Offset%x12|Size%x13");
|
||||
if(event== -1) return;
|
||||
|
||||
map= texchannel_to_adrcode(la->texact);
|
||||
|
||||
if(event==0) {
|
||||
insertkey(id, ID_LA, NULL, NULL, LA_COL_R, 0);
|
||||
insertkey(id, ID_LA, NULL, NULL, LA_COL_G, 0);
|
||||
insertkey(id, ID_LA, NULL, NULL, LA_COL_B, 0);
|
||||
}
|
||||
if(event==1) {
|
||||
insertkey(id, ID_LA, NULL, NULL, LA_ENERGY, 0);
|
||||
}
|
||||
if(event==2) {
|
||||
insertkey(id, ID_LA, NULL, NULL, LA_SPOTSI, 0);
|
||||
}
|
||||
if(event==12) {
|
||||
insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_X, 0);
|
||||
insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Y, 0);
|
||||
insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Z, 0);
|
||||
}
|
||||
if(event==13) {
|
||||
insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_X, 0);
|
||||
insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Y, 0);
|
||||
insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Z, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if(tab==TAB_SHADING_TEX) {
|
||||
id= G.buts->lockpoin;
|
||||
te= G.buts->lockpoin;
|
||||
if(id) {
|
||||
event= pupmenu("Insert Key %t|Clouds%x0|Marble%x1|Stucci%x2|Wood%x3|Magic%x4|Blend%x5|Musgrave%x6|Voronoi%x7|DistortedNoise%x8|ColorFilter%x9");
|
||||
if(event== -1) return;
|
||||
|
||||
if(event==0) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
|
||||
}
|
||||
if(event==1) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2, 0);
|
||||
}
|
||||
if(event==2) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
|
||||
}
|
||||
if(event==3) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2, 0);
|
||||
}
|
||||
if(event==4) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
|
||||
}
|
||||
if(event==5) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
|
||||
}
|
||||
if(event==6) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MGH, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_LAC, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN, 0);
|
||||
}
|
||||
if(event==7) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VNW1, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VNW2, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VNW3, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VNW4, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VNMEXP, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VN_DISTM, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_VN_COLT, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_ISCA, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
|
||||
}
|
||||
if(event==8) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_DISTA, 0);
|
||||
}
|
||||
if(event==9) {
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_COL_R, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_COL_G, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_COL_B, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_BRIGHT, 0);
|
||||
insertkey(id, ID_TE, NULL, NULL, TE_CONTRA, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(G.buts->mainb==CONTEXT_OBJECT) {
|
||||
ob= OBACT;
|
||||
if(ob) {
|
||||
id= (ID *) (ob);
|
||||
if(id) {
|
||||
if(ob->type==OB_MESH)
|
||||
event= pupmenu("Insert Key %t|Surface Damping%x0|Random Damping%x1|Permeability%x2|Force Strength%x3|Force Falloff%x4");
|
||||
else
|
||||
event= pupmenu("Insert Key %t|Force Strength%x3|Force Falloff%x4");
|
||||
if(event == -1) return;
|
||||
|
||||
if(event==0) {
|
||||
insertkey(id, ID_OB, NULL, NULL, OB_PD_SDAMP, 0);
|
||||
}
|
||||
if(event==1) {
|
||||
insertkey(id, ID_OB, NULL, NULL, OB_PD_RDAMP, 0);
|
||||
}
|
||||
if(event==2) {
|
||||
insertkey(id, ID_OB, NULL, NULL, OB_PD_PERM, 0);
|
||||
}
|
||||
if(event==3) {
|
||||
insertkey(id, ID_OB, NULL, NULL, OB_PD_FSTR, 0);
|
||||
}
|
||||
if(event==4) {
|
||||
insertkey(id, ID_OB, NULL, NULL, OB_PD_FFALL, 0);
|
||||
}
|
||||
if(event==5) {
|
||||
insertkey(id, ID_OB, NULL, NULL, OB_PD_FMAXD, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(G.buts->mainb==CONTEXT_EDITING) {
|
||||
ob= OBACT;
|
||||
if(ob && ob->type==OB_CAMERA) {
|
||||
id= G.buts->lockpoin;
|
||||
if(id) {
|
||||
/* yafray: insert key extended with aperture and focal distance */
|
||||
/* qdn: FocalDistance now enabled for Blender as wel, for use with defocus node */
|
||||
if (G.scene->r.renderer==R_INTERN)
|
||||
event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1|FocalDistance%x3|Viewplane Shift%x4");
|
||||
else
|
||||
event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1|Aperture%x2|FocalDistance%x3");
|
||||
if(event== -1) return;
|
||||
|
||||
if(event==0) {
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_LENS, 0);
|
||||
}
|
||||
else if(event==1) {
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_STA, 0);
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_END, 0);
|
||||
}
|
||||
else if(event==2) {
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_YF_APERT, 0);
|
||||
}
|
||||
else if(event==3) {
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_YF_FDIST, 0);
|
||||
}
|
||||
else if(event==4) {
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_X, 0);
|
||||
insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_Y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(FALSE /* && G.buts->mainb==BUTS_SOUND */) {
|
||||
if(G.ssound) {
|
||||
id= G.buts->lockpoin;
|
||||
if(id) {
|
||||
event= pupmenu("Insert Key %t|Volume%x0|Pitch%x1|Panning%x2|Attennuation%x3");
|
||||
if(event== -1) return;
|
||||
|
||||
if(event==0) {
|
||||
insertkey(id, ID_SO, NULL, NULL, SND_VOLUME, 0);
|
||||
}
|
||||
if(event==1) {
|
||||
insertkey(id, ID_SO, NULL, NULL, SND_PITCH, 0);
|
||||
}
|
||||
if(event==2) {
|
||||
insertkey(id, ID_SO, NULL, NULL, SND_PANNING, 0);
|
||||
}
|
||||
if(event==3) {
|
||||
insertkey(id, ID_SO, NULL, NULL, SND_ATTEN, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIF_undo_push("Insert Key Buttons");
|
||||
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allspace(REMAKEIPO, 0);
|
||||
|
||||
}
|
||||
else if(curarea->spacetype==SPACE_VIEW3D) {
|
||||
ob= OBACT;
|
||||
|
||||
if (ob && (ob->flag & OB_POSEMODE)) {
|
||||
bPoseChannel *pchan;
|
||||
|
||||
set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
|
||||
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next)
|
||||
if (pchan->flag & POSE_KEY)
|
||||
break;
|
||||
if(pchan==NULL) return;
|
||||
strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Scale%x2|LocRot%x3|LocRotScale%x4|Avail%x9|Needed%x15|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13");
|
||||
}
|
||||
else {
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if (TESTBASELIB(base)) break;
|
||||
base= base->next;
|
||||
}
|
||||
if(base==NULL) return;
|
||||
strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Scale%x2|LocRot%x3|LocRotScale%x4|Layer%x5|Avail%x9|Needed%x15|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13");
|
||||
}
|
||||
|
||||
if(ob) {
|
||||
if(ob->type==OB_MESH) strcat(menustr, "| %x6|Mesh%x7");
|
||||
else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7");
|
||||
else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7");
|
||||
else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7");
|
||||
}
|
||||
|
||||
event= pupmenu(menustr);
|
||||
if(event== -1) return;
|
||||
|
||||
if(event==7) { // ob != NULL
|
||||
insert_shapekey(ob);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ob && (ob->flag & OB_POSEMODE)){
|
||||
bPoseChannel *pchan;
|
||||
short recalc_bonepaths= 0;
|
||||
|
||||
if (ob->action && ob->action->id.lib) {
|
||||
error ("Can't key libactions");
|
||||
return;
|
||||
}
|
||||
|
||||
id= &ob->id;
|
||||
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
|
||||
if (pchan->flag & POSE_KEY) {
|
||||
/* insert relevant keyframes */
|
||||
if(event==0 || event==3 ||event==4) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
|
||||
}
|
||||
if(event==1 || event==3 || event==4) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
|
||||
}
|
||||
if(event==2 || event==4) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
|
||||
}
|
||||
if (event==9 && ob->action) {
|
||||
bActionChannel *achan;
|
||||
|
||||
for (achan = ob->action->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(id, ID_PO, achan->name, NULL, icu->adrcode, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event==11 || event==13) {
|
||||
int matok=0;
|
||||
/* check one to make sure we're not trying to set visual loc keys on
|
||||
bones inside of a chain, which only leads to tears. */
|
||||
matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
|
||||
|
||||
if (matok == 0) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
|
||||
}
|
||||
}
|
||||
if(event==12 || event==13) {
|
||||
int matok=0;
|
||||
/* check one to make sure we're not trying to set visual rot keys on
|
||||
bones inside of a chain, which only leads to tears. */
|
||||
matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
|
||||
|
||||
if (matok == 0) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
|
||||
}
|
||||
}
|
||||
if (event==15 && ob->action) {
|
||||
bActionChannel *achan;
|
||||
|
||||
for (achan = ob->action->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_smarter(id, ID_PO, achan->name, NULL, icu->adrcode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clear unkeyed flag (it doesn't matter if it's set or not) */
|
||||
if (pchan->bone)
|
||||
pchan->bone->flag &= ~BONE_UNKEYED;
|
||||
|
||||
/* check if bone has a path */
|
||||
if (pchan->path)
|
||||
recalc_bonepaths = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* recalculate ipo handles, etc. */
|
||||
if(ob->action)
|
||||
remake_action_ipos(ob->action);
|
||||
|
||||
/* recalculate bone-paths on adding new keyframe? */
|
||||
// TODO: currently, there is no setting to turn this on/off globally
|
||||
if (recalc_bonepaths)
|
||||
pose_recalculate_paths(ob);
|
||||
|
||||
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
}
|
||||
else {
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if (TESTBASELIB(base)) {
|
||||
char *actname= NULL;
|
||||
|
||||
id= (ID *)(base->object);
|
||||
|
||||
if(base->object->ipoflag & OB_ACTION_OB)
|
||||
actname= "Object";
|
||||
|
||||
/* all curves in ipo deselect */
|
||||
if(base->object->ipo || base->object->action) {
|
||||
if (base->object->ipo) {
|
||||
icu= base->object->ipo->curve.first;
|
||||
}
|
||||
else {
|
||||
bActionChannel *achan;
|
||||
achan= get_action_channel(base->object->action, actname);
|
||||
|
||||
if (achan && achan->ipo)
|
||||
icu= achan->ipo->curve.first;
|
||||
else
|
||||
icu= NULL;
|
||||
}
|
||||
|
||||
while(icu) {
|
||||
icu->flag &= ~IPO_SELECT;
|
||||
|
||||
switch (event) {
|
||||
case 9:
|
||||
insertkey(id, ID_OB, actname, NULL, icu->adrcode, 0);
|
||||
break;
|
||||
case 15:
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
|
||||
break;
|
||||
}
|
||||
icu= icu->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(event==0 || event==3 ||event==4) {
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_X, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Y, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Z, 0);
|
||||
}
|
||||
if(event==1 || event==3 ||event==4) {
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_X, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Y, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Z, 0);
|
||||
}
|
||||
if(event==2 || event==4) {
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_X, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z, 0);
|
||||
}
|
||||
if(event==5) {
|
||||
/* remove localview */
|
||||
tlay= base->object->lay;
|
||||
base->object->lay &= 0xFFFFFF;
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LAY, 0);
|
||||
base->object->lay= tlay;
|
||||
}
|
||||
if(event==11 || event==13) {
|
||||
insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_X);
|
||||
insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Y);
|
||||
insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Z);
|
||||
}
|
||||
if(event==12 || event==13) {
|
||||
insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_X);
|
||||
insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y);
|
||||
insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z);
|
||||
}
|
||||
base->object->recalc |= OB_RECALC_OB;
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(event==0) BIF_undo_push("Insert Loc Key");
|
||||
else if(event==1) BIF_undo_push("Insert Rot Key");
|
||||
else if(event==2) BIF_undo_push("Insert Scale Key");
|
||||
else if(event==3) BIF_undo_push("Insert LocRot Key");
|
||||
else if(event==4) BIF_undo_push("Insert LocRotScale Key");
|
||||
else if(event==5) BIF_undo_push("Insert Layer Key");
|
||||
else if(event==7) BIF_undo_push("Insert Vertex Key");
|
||||
else if(event==9) BIF_undo_push("Insert Avail Key");
|
||||
else if(event==11) BIF_undo_push("Insert VisualLoc Key");
|
||||
else if(event==12) BIF_undo_push("Insert VisualRot Key");
|
||||
else if(event==13) BIF_undo_push("Insert VisualLocRot Key");
|
||||
else if(event==15) BIF_undo_push("Insert Needed Key");
|
||||
|
||||
DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
|
||||
|
||||
allspace(REMAKEIPO, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ****************************************************************************** */
|
||||
|
||||
void add_duplicate_editipo(void)
|
||||
|
||||
@@ -869,6 +869,152 @@ int confirm_objectExists( Mesh **me, float mat[][3] )
|
||||
return newob;
|
||||
}
|
||||
|
||||
// HACK: these can also be found in cmoview.tga.c, but are here so that they can be found by linker
|
||||
// this hack is only used so that scons+mingw + split-sources hack works
|
||||
// ------------------------------- start copied code
|
||||
/* these are not the monkeys you are looking for */
|
||||
int monkeyo= 4;
|
||||
int monkeynv= 271;
|
||||
int monkeynf= 250;
|
||||
signed char monkeyv[271][3]= {
|
||||
{-71,21,98},{-63,12,88},{-57,7,74},{-82,-3,79},{-82,4,92},
|
||||
{-82,17,100},{-92,21,102},{-101,12,95},{-107,7,83},
|
||||
{-117,31,84},{-109,31,95},{-96,31,102},{-92,42,102},
|
||||
{-101,50,95},{-107,56,83},{-82,66,79},{-82,58,92},
|
||||
{-82,46,100},{-71,42,98},{-63,50,88},{-57,56,74},
|
||||
{-47,31,72},{-55,31,86},{-67,31,97},{-66,31,99},
|
||||
{-70,43,100},{-82,48,103},{-93,43,105},{-98,31,105},
|
||||
{-93,20,105},{-82,31,106},{-82,15,103},{-70,20,100},
|
||||
{-127,55,95},{-127,45,105},{-127,-87,94},{-127,-41,100},
|
||||
{-127,-24,102},{-127,-99,92},{-127,52,77},{-127,73,73},
|
||||
{-127,115,-70},{-127,72,-109},{-127,9,-106},{-127,-49,-45},
|
||||
{-101,-24,72},{-87,-56,73},{-82,-89,73},{-80,-114,68},
|
||||
{-85,-121,67},{-104,-124,71},{-127,-126,74},{-71,-18,68},
|
||||
{-46,-5,69},{-21,19,57},{-17,55,76},{-36,62,80},
|
||||
{-64,77,88},{-86,97,94},{-107,92,97},{-119,63,96},
|
||||
{-106,53,99},{-111,39,98},{-101,12,95},{-79,2,90},
|
||||
{-64,8,86},{-47,24,83},{-45,38,83},{-50,48,85},
|
||||
{-72,56,92},{-95,60,97},{-127,-98,94},{-113,-92,94},
|
||||
{-112,-107,91},{-119,-113,89},{-127,-114,88},{-127,-25,96},
|
||||
{-127,-18,95},{-114,-19,95},{-111,-29,96},{-116,-37,95},
|
||||
{-76,-6,86},{-48,7,80},{-34,26,77},{-32,48,84},
|
||||
{-39,53,93},{-71,70,102},{-87,82,107},{-101,79,109},
|
||||
{-114,55,108},{-111,-13,104},{-100,-57,91},{-95,-90,88},
|
||||
{-93,-105,85},{-97,-117,81},{-106,-119,81},{-127,-121,82},
|
||||
{-127,6,93},{-127,27,98},{-85,61,95},{-106,18,96},
|
||||
{-110,27,97},{-112,-88,94},{-117,-57,96},{-127,-57,96},
|
||||
{-127,-42,95},{-115,-35,100},{-110,-29,102},{-113,-17,100},
|
||||
{-122,-16,100},{-127,-26,106},{-121,-19,104},{-115,-20,104},
|
||||
{-113,-29,106},{-117,-32,103},{-127,-37,103},{-94,-40,71},
|
||||
{-106,-31,91},{-104,-40,91},{-97,-32,71},{-127,-112,88},
|
||||
{-121,-111,88},{-115,-105,91},{-115,-95,93},{-127,-100,84},
|
||||
{-115,-96,85},{-115,-104,82},{-121,-109,81},{-127,-110,81},
|
||||
{-105,28,100},{-103,20,99},{-84,55,97},{-92,54,99},
|
||||
{-73,51,99},{-55,45,89},{-52,37,88},{-53,25,87},
|
||||
{-66,13,92},{-79,8,95},{-98,14,100},{-104,38,100},
|
||||
{-100,48,100},{-97,46,97},{-102,38,97},{-96,16,97},
|
||||
{-79,11,93},{-68,15,90},{-57,27,86},{-56,36,86},
|
||||
{-59,43,87},{-74,50,96},{-91,51,98},{-84,52,96},
|
||||
{-101,22,96},{-102,29,96},{-113,59,78},{-102,85,79},
|
||||
{-84,88,76},{-65,71,71},{-40,58,63},{-25,52,59},
|
||||
{-28,21,48},{-50,0,53},{-71,-12,60},{-127,115,37},
|
||||
{-127,126,-10},{-127,-25,-86},{-127,-59,24},{-127,-125,59},
|
||||
{-127,-103,44},{-127,-73,41},{-127,-62,36},{-18,30,7},
|
||||
{-17,41,-6},{-28,34,-56},{-68,56,-90},{-33,-6,9},
|
||||
{-51,-16,-21},{-45,-1,-55},{-84,7,-85},{-97,-45,52},
|
||||
{-104,-53,33},{-90,-91,49},{-95,-64,50},{-85,-117,51},
|
||||
{-109,-97,47},{-111,-69,46},{-106,-121,56},{-99,-36,55},
|
||||
{-100,-29,60},{-101,-22,64},{-100,-50,21},{-89,-40,-34},
|
||||
{-83,-19,-69},{-69,111,-49},{-69,119,-9},{-69,109,30},
|
||||
{-68,67,55},{-34,52,43},{-46,58,36},{-45,90,7},
|
||||
{-25,72,16},{-25,79,-15},{-45,96,-25},{-45,87,-57},
|
||||
{-25,69,-46},{-48,42,-75},{-65,3,-70},{-22,42,-26},
|
||||
{-75,-22,19},{-72,-25,-27},{-13,52,-30},{-28,-18,-16},
|
||||
{6,-13,-42},{37,7,-55},{46,41,-54},{31,65,-54},
|
||||
{4,61,-40},{3,53,-37},{25,56,-50},{35,37,-52},
|
||||
{28,10,-52},{5,-5,-39},{-21,-9,-17},{-9,46,-28},
|
||||
{-6,39,-37},{-14,-3,-27},{6,0,-47},{25,12,-57},
|
||||
{31,32,-57},{23,46,-56},{4,44,-46},{-19,37,-27},
|
||||
{-20,22,-35},{-30,12,-35},{-22,11,-35},{-19,2,-35},
|
||||
{-23,-2,-35},{-34,0,-9},{-35,-3,-22},{-35,5,-24},
|
||||
{-25,26,-27},{-13,31,-34},{-13,30,-41},{-23,-2,-41},
|
||||
{-18,2,-41},{-21,10,-41},{-29,12,-41},{-19,22,-41},
|
||||
{6,42,-53},{25,44,-62},{34,31,-63},{28,11,-62},
|
||||
{7,0,-54},{-14,-2,-34},{-5,37,-44},{-13,14,-42},
|
||||
{-7,8,-43},{1,16,-47},{-4,22,-45},{3,30,-48},
|
||||
{8,24,-49},{15,27,-50},{12,35,-50},{4,56,-62},
|
||||
{33,60,-70},{48,38,-64},{41,7,-68},{6,-11,-63},
|
||||
{-26,-16,-42},{-17,49,-49},
|
||||
};
|
||||
|
||||
signed char monkeyf[250][4]= {
|
||||
{27,4,5,26}, {25,4,5,24}, {3,6,5,4}, {1,6,5,2}, {5,6,7,4},
|
||||
{3,6,7,2}, {5,8,7,6}, {3,8,7,4}, {7,8,9,6},
|
||||
{5,8,9,4}, {7,10,9,8}, {5,10,9,6}, {9,10,11,8},
|
||||
{7,10,11,6}, {9,12,11,10}, {7,12,11,8}, {11,6,13,12},
|
||||
{5,4,13,12}, {3,-2,13,12}, {-3,-4,13,12}, {-5,-10,13,12},
|
||||
{-11,-12,14,12}, {-13,-18,14,13}, {-19,4,5,13}, {10,12,4,4},
|
||||
{10,11,9,9}, {8,7,9,9}, {7,5,6,6}, {6,3,4,4},
|
||||
{5,1,2,2}, {4,-1,0,0}, {3,-3,-2,-2}, {22,67,68,23},
|
||||
{20,65,66,21}, {18,63,64,19}, {16,61,62,17}, {14,59,60,15},
|
||||
{12,19,48,57}, {18,19,48,47}, {18,19,48,47}, {18,19,48,47},
|
||||
{18,19,48,47}, {18,19,48,47}, {18,19,48,47}, {18,19,48,47},
|
||||
{18,19,48,47}, {18,-9,-8,47}, {18,27,45,46}, {26,55,43,44},
|
||||
{24,41,42,54}, {22,39,40,23}, {20,37,38,21}, {18,35,36,19},
|
||||
{16,33,34,17}, {14,31,32,15}, {12,39,30,13}, {11,48,45,38},
|
||||
{8,36,-19,9}, {8,-20,44,47}, {42,45,46,43}, {18,19,40,39},
|
||||
{16,17,38,37}, {14,15,36,35}, {32,44,43,33}, {12,33,32,42},
|
||||
{19,44,43,42}, {40,41,42,-27}, {8,9,39,-28}, {15,43,42,16},
|
||||
{13,43,42,14}, {11,43,42,12}, {9,-30,42,10}, {37,12,38,-32},
|
||||
{-33,37,45,46}, {-33,40,41,39}, {38,40,41,37}, {36,40,41,35},
|
||||
{34,40,41,33}, {36,39,38,37}, {35,40,39,38}, {1,2,14,21},
|
||||
{1,2,40,13}, {1,2,40,39}, {1,24,12,39}, {-34,36,38,11},
|
||||
{35,38,36,37}, {-37,8,35,37}, {-11,-12,-45,40}, {-11,-12,39,38},
|
||||
{-11,-12,37,36}, {-11,-12,35,34}, {33,34,40,41}, {33,34,38,39},
|
||||
{33,34,36,37}, {33,-52,34,35}, {33,37,36,34}, {33,35,34,34},
|
||||
{8,7,37,36}, {-32,7,35,46}, {-34,-33,45,46}, {4,-33,43,34},
|
||||
{-34,-33,41,42}, {-34,-33,39,40}, {-34,-33,37,38}, {-34,-33,35,36},
|
||||
{-34,-33,33,34}, {-34,-33,31,32}, {-34,-4,28,30}, {-5,-34,28,27},
|
||||
{-35,-44,36,27}, {26,35,36,45}, {24,25,44,45}, {25,23,44,42},
|
||||
{25,24,41,40}, {25,24,39,38}, {25,24,37,36}, {25,24,35,34},
|
||||
{25,24,33,32}, {25,24,31,30}, {15,24,29,38}, {25,24,27,26},
|
||||
{23,12,37,26}, {11,12,35,36}, {-86,-59,36,-80}, {-60,-61,36,35},
|
||||
{-62,-63,36,35}, {-64,-65,36,35}, {-66,-67,36,35}, {-68,-69,36,35},
|
||||
{-70,-71,36,35}, {-72,-73,36,35}, {-74,-75,36,35}, {42,43,53,58},
|
||||
{40,41,57,56}, {38,39,55,57}, {-81,-80,37,56}, {-83,-82,55,52},
|
||||
{-85,-84,51,49}, {-87,-86,48,49}, {47,50,51,48}, {46,48,51,49},
|
||||
{43,46,49,44}, {-92,-91,45,42}, {-23,49,50,-20}, {-94,40,48,-24},
|
||||
{-96,-22,48,49}, {-97,48,21,-90}, {-100,36,50,23}, {22,49,48,-100},
|
||||
{-101,47,46,22}, {21,45,35,25}, {33,34,44,41}, {13,14,28,24},
|
||||
{-107,26,30,-106}, {14,46,45,15}, {14,44,43,-110}, {-111,42,23,-110},
|
||||
{6,7,45,46}, {45,44,47,46}, {45,46,47,48}, {47,46,49,48},
|
||||
{17,49,47,48}, {17,36,46,48}, {35,36,44,45}, {35,36,40,43},
|
||||
{35,36,38,39}, {-4,-3,37,35}, {-123,34,33,1}, {-9,-8,-7,-6},
|
||||
{-10,-7,32,-125}, {-127,-11,-126,-126}, {-7,-6,5,31}, {4,5,33,30},
|
||||
{4,39,33,32}, {4,35,32,38}, {20,21,39,38}, {4,37,38,5},
|
||||
{-11,-10,36,3}, {-11,15,14,35}, {13,16,34,34}, {-13,14,13,13},
|
||||
{-3,1,30,29}, {-3,28,29,1}, {-2,31,28,-1}, {12,13,27,30},
|
||||
{-2,26,12,12}, {35,29,42,36}, {34,35,36,33}, {32,35,36,31},
|
||||
{30,35,36,29}, {28,35,36,27}, {26,35,36,25}, {34,39,38,35},
|
||||
{32,39,38,33}, {30,39,38,31}, {28,39,38,29}, {26,39,38,27},
|
||||
{25,31,32,38}, {-18,-17,45,44}, {-18,17,28,44}, {-24,-20,42,-23},
|
||||
{11,35,27,14}, {25,28,39,41}, {37,41,40,38}, {34,40,36,35},
|
||||
{32,40,39,33}, {30,39,31,40}, {21,29,39,22}, {-31,37,28,4},
|
||||
{-32,33,35,36}, {32,33,34,34}, {18,35,36,48}, {34,25,40,35},
|
||||
{24,25,38,39}, {24,25,36,37}, {24,25,34,35}, {24,25,32,33},
|
||||
{24,13,41,31}, {17,11,41,35}, {15,16,34,35}, {13,14,34,35},
|
||||
{11,12,34,35}, {9,10,34,35}, {7,8,34,35}, {26,25,37,36},
|
||||
{35,36,37,38}, {37,36,39,38}, {37,38,39,40}, {25,31,36,39},
|
||||
{18,34,35,30}, {17,22,30,33}, {19,29,21,20}, {16,26,29,17},
|
||||
{24,29,28,25}, {22,31,28,23}, {20,31,30,21}, {18,31,30,19},
|
||||
{16,30,17,17}, {-21,-22,35,34}, {-21,-22,33,32}, {-21,-22,31,30},
|
||||
{-21,-22,29,28}, {-21,-22,27,26}, {-28,-22,25,31}, {24,28,29,30},
|
||||
{23,24,26,27}, {23,24,25,25}, {-69,-35,-32,27}, {-70,26,25,-66},
|
||||
{-68,-67,24,-33},
|
||||
};
|
||||
// ------------------------------- end copied code
|
||||
|
||||
|
||||
void make_prim(int type, float imat[3][3], int tot, int seg,
|
||||
int subdiv, float dia, float d, int ext, int fill,
|
||||
float cent[3])
|
||||
@@ -1022,9 +1168,9 @@ void make_prim(int type, float imat[3][3], int tot, int seg,
|
||||
break;
|
||||
case 13: /* Monkey */
|
||||
{
|
||||
extern int monkeyo, monkeynv, monkeynf;
|
||||
extern signed char monkeyf[][4];
|
||||
extern signed char monkeyv[][3];
|
||||
//extern int monkeyo, monkeynv, monkeynf;
|
||||
//extern signed char monkeyf[][4];
|
||||
//extern signed char monkeyv[][3];
|
||||
EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
|
||||
EditFace *efa;
|
||||
int i;
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_previewrender.h" /* use only so fly mode can preview when its done */
|
||||
#include "BIF_space.h"
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
#include "BIF_editview.h"
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_mainqueue.h"
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_poselib.h"
|
||||
|
||||
1767
source/blender/src/keyframing.c
Normal file
1767
source/blender/src/keyframing.c
Normal file
@@ -0,0 +1,1767 @@
|
||||
/**
|
||||
* $Id: keyframing.c 14881 2008-05-18 10:41:42Z aligorith $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation
|
||||
* This is a new part of Blender (with some old code)
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_butspace.h"
|
||||
#include "BIF_editaction.h"
|
||||
#include "BIF_editkey.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
#include "BIF_toets.h"
|
||||
|
||||
#include "BSE_editipo.h"
|
||||
#include "BSE_node.h"
|
||||
#include "BSE_time.h"
|
||||
#include "BSE_view.h"
|
||||
|
||||
#include "blendef.h"
|
||||
|
||||
#include "PIL_time.h" /* sleep */
|
||||
#include "mydevice.h"
|
||||
|
||||
/* ************************************************** */
|
||||
/* LOCAL TYPES AND DEFINES */
|
||||
|
||||
/* -------------- Keying Sets ------------------- */
|
||||
|
||||
/* keying set - a set of channels that will be keyframed together */
|
||||
// TODO: move this to a header to allow custom sets someday?
|
||||
typedef struct bKeyingSet {
|
||||
/* callback func to consider if keyingset should be included
|
||||
* (by default, if this is undefined, item will be shown)
|
||||
*/
|
||||
short (*include_cb)(struct bKeyingSet *, const char *);
|
||||
|
||||
char name[48]; /* name of keyingset */
|
||||
int blocktype; /* blocktype that all channels belong to */ // in future, this may be eliminated
|
||||
short flag; /* flags to use when setting keyframes */
|
||||
|
||||
short chan_num; /* number of channels to insert keyframe in */
|
||||
short adrcodes[32]; /* adrcodes for channels to insert keys for (ideally would be variable-len, but limit of 32 will suffice) */
|
||||
} bKeyingSet;
|
||||
|
||||
/* keying set context - an array of keying sets and the number of them */
|
||||
typedef struct bKeyingContext {
|
||||
bKeyingSet *keyingsets; /* array containing the keyingsets of interest */
|
||||
bKeyingSet *lastused; /* item that was chosen last time*/
|
||||
int tot; /* number of keyingsets in */
|
||||
} bKeyingContext;
|
||||
|
||||
|
||||
/* ----------- Common KeyData Sources ------------ */
|
||||
|
||||
/* temporary struct to gather data combos to keyframe */
|
||||
typedef struct bCommonKeySrc {
|
||||
struct bCommonKeySrc *next, *prev;
|
||||
|
||||
/* general data/destination-source settings */
|
||||
ID *id; /* id-block this comes from */
|
||||
char *actname; /* name of action channel */
|
||||
char *constname; /* name of constraint channel */
|
||||
|
||||
/* general destination source settings */
|
||||
Ipo *ipo; /* ipo-block that id-block has (optional) */
|
||||
bAction *act; /* action-block that id-block has (optional) */
|
||||
|
||||
/* pose-level settings */
|
||||
bPoseChannel *pchan; /* pose channel */
|
||||
|
||||
/* buttons-window settings */
|
||||
int map; /* offset to apply to certain adrcodes */
|
||||
} bCommonKeySrc;
|
||||
|
||||
/* ************************************************** */
|
||||
/* KEYFRAME INSERTION */
|
||||
|
||||
/* -------------- BezTriple Insertion -------------------- */
|
||||
|
||||
/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
|
||||
#define BEZT_INSERT_THRESH 0.00001
|
||||
|
||||
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
|
||||
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
||||
*/
|
||||
static int binarysearch_bezt_index (BezTriple array[], BezTriple *item, int arraylen, short *replace)
|
||||
{
|
||||
int start=0, end=arraylen;
|
||||
int loopbreaker= 0, maxloop= arraylen * 2;
|
||||
const float frame= (item)? item->vec[1][0] : 0.0f;
|
||||
|
||||
/* initialise replace-flag first */
|
||||
*replace= 0;
|
||||
|
||||
/* sneaky optimisations (don't go through searching process if...):
|
||||
* - keyframe to be added is to be added out of current bounds
|
||||
* - keyframe to be added would replace one of the existing ones on bounds
|
||||
*/
|
||||
if ((arraylen <= 0) || ELEM(NULL, array, item)) {
|
||||
printf("Warning: binarysearch_bezt_index encountered invalid array \n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* check whether to add before/after/on */
|
||||
float framenum;
|
||||
|
||||
/* 'First' Keyframe (when only one keyframe, this case is used) */
|
||||
framenum= array[0].vec[1][0];
|
||||
if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
|
||||
*replace = 1;
|
||||
return 0;
|
||||
}
|
||||
else if (frame < framenum)
|
||||
return 0;
|
||||
|
||||
/* 'Last' Keyframe */
|
||||
framenum= array[(arraylen-1)].vec[1][0];
|
||||
if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
|
||||
*replace= 1;
|
||||
return (arraylen - 1);
|
||||
}
|
||||
else if (frame > framenum)
|
||||
return arraylen;
|
||||
}
|
||||
|
||||
|
||||
/* most of the time, this loop is just to find where to put it
|
||||
* 'loopbreaker' is just here to prevent infinite loops
|
||||
*/
|
||||
for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
|
||||
/* compute and get midpoint */
|
||||
int mid = (start + end) / 2;
|
||||
float midfra= array[mid].vec[1][0];
|
||||
|
||||
/* check if exactly equal to midpoint */
|
||||
if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH)) {
|
||||
*replace = 1;
|
||||
return mid;
|
||||
}
|
||||
|
||||
/* repeat in upper/lower half */
|
||||
if (frame > midfra)
|
||||
start= mid + 1;
|
||||
else if (frame < midfra)
|
||||
end= mid - 1;
|
||||
}
|
||||
|
||||
/* print error if loop-limit exceeded */
|
||||
if (loopbreaker == (maxloop-1)) {
|
||||
printf("Error: binarysearch_bezt_index was taking too long \n");
|
||||
|
||||
// include debug info
|
||||
printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
|
||||
}
|
||||
|
||||
/* not found, so return where to place it */
|
||||
return start;
|
||||
}
|
||||
|
||||
/* This function adds a given BezTriple to an IPO-Curve. It will allocate
|
||||
* memory for the array if needed, and will insert the BezTriple into a
|
||||
* suitable place in chronological order.
|
||||
*
|
||||
* NOTE: any recalculate of the IPO-Curve that needs to be done will need to
|
||||
* be done by the caller.
|
||||
*/
|
||||
int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
|
||||
{
|
||||
BezTriple *newb;
|
||||
int i= 0;
|
||||
|
||||
if (icu->bezt == NULL) {
|
||||
icu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
|
||||
*(icu->bezt)= *bezt;
|
||||
icu->totvert= 1;
|
||||
}
|
||||
else {
|
||||
short replace = -1;
|
||||
i = binarysearch_bezt_index(icu->bezt, bezt, icu->totvert, &replace);
|
||||
|
||||
if (replace) {
|
||||
/* sanity check: 'i' may in rare cases exceed arraylen */
|
||||
if ((i >= 0) && (i < icu->totvert))
|
||||
*(icu->bezt + i) = *bezt;
|
||||
}
|
||||
else {
|
||||
/* add new */
|
||||
newb= MEM_callocN((icu->totvert+1)*sizeof(BezTriple), "beztriple");
|
||||
|
||||
/* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
|
||||
if (i > 0)
|
||||
memcpy(newb, icu->bezt, i*sizeof(BezTriple));
|
||||
|
||||
/* add beztriple to paste at index i */
|
||||
*(newb + i)= *bezt;
|
||||
|
||||
/* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
|
||||
if (i < icu->totvert)
|
||||
memcpy(newb+i+1, icu->bezt+i, (icu->totvert-i)*sizeof(BezTriple));
|
||||
|
||||
/* replace (+ free) old with new */
|
||||
MEM_freeN(icu->bezt);
|
||||
icu->bezt= newb;
|
||||
|
||||
icu->totvert++;
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to return the index, so that some tools which do post-processing can
|
||||
* detect where we added the BezTriple in the array
|
||||
*/
|
||||
return i;
|
||||
}
|
||||
|
||||
/* This function is a wrapper for insert_bezt_icu, and should be used when
|
||||
* adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
|
||||
* else yet.
|
||||
*
|
||||
* 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
|
||||
*/
|
||||
void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
|
||||
{
|
||||
BezTriple beztr;
|
||||
int a, h1, h2;
|
||||
|
||||
/* set all three points, for nicer start position */
|
||||
memset(&beztr, 0, sizeof(BezTriple));
|
||||
beztr.vec[0][0]= x;
|
||||
beztr.vec[0][1]= y;
|
||||
beztr.vec[1][0]= x;
|
||||
beztr.vec[1][1]= y;
|
||||
beztr.vec[2][0]= x;
|
||||
beztr.vec[2][1]= y;
|
||||
beztr.hide= IPO_BEZ;
|
||||
beztr.f1= beztr.f2= beztr.f3= SELECT;
|
||||
beztr.h1= beztr.h2= HD_AUTO;
|
||||
|
||||
/* add temp beztriple to keyframes */
|
||||
a= insert_bezt_icu(icu, &beztr);
|
||||
if (!fast) calchandles_ipocurve(icu);
|
||||
|
||||
/* set handletype */
|
||||
if (icu->totvert > 2) {
|
||||
BezTriple *bezt;
|
||||
|
||||
h1= h2= HD_AUTO;
|
||||
bezt= (icu->bezt + a);
|
||||
|
||||
if (a > 0) h1= (bezt-1)->h2;
|
||||
if (a < icu->totvert-1) h2= (bezt+1)->h1;
|
||||
|
||||
bezt->h1= h1;
|
||||
bezt->h2= h2;
|
||||
|
||||
if (!fast) calchandles_ipocurve(icu);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------- Get Data ------------------------ */
|
||||
|
||||
/* Get pointer to use to get values from */
|
||||
// FIXME: this should not be possible with Data-API
|
||||
static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, char *constname, IpoCurve *icu, int *vartype)
|
||||
{
|
||||
switch (blocktype) {
|
||||
case ID_PO: /* posechannel */
|
||||
if (GS(id->name)==ID_OB) {
|
||||
Object *ob= (Object *)id;
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
|
||||
if (pchan) {
|
||||
*vartype= IPO_FLOAT;
|
||||
return get_pchan_ipo_poin(pchan, icu->adrcode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_CO: /* constraint */
|
||||
if ((GS(id->name)==ID_OB) && (constname && constname[0])) {
|
||||
Object *ob= (Object *)id;
|
||||
bConstraint *con;
|
||||
|
||||
/* assume that we only want the influence (as only used for Constraint Channels) */
|
||||
if ((ob->ipoflag & OB_ACTION_OB) && !strcmp(actname, "Object")) {
|
||||
for (con= ob->constraints.first; con; con= con->next) {
|
||||
if (strcmp(constname, con->name)==0) {
|
||||
*vartype= IPO_FLOAT;
|
||||
return &con->enforce;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ob->pose) {
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
|
||||
if (pchan) {
|
||||
for (con= pchan->constraints.first; con; con= con->next) {
|
||||
if (strcmp(constname, con->name)==0) {
|
||||
*vartype= IPO_FLOAT;
|
||||
return &con->enforce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_OB: /* object */
|
||||
/* hack: layer channels for object need to be keyed WITHOUT localview flag...
|
||||
* tsk... tsk... why must we just dump bitflags upon users :/
|
||||
*/
|
||||
if ((GS(id->name)==ID_OB) && (icu->adrcode==OB_LAY)) {
|
||||
Object *ob= (Object *)id;
|
||||
static int layer = 0;
|
||||
|
||||
/* init layer to be the object's layer var, then remove local view from it */
|
||||
layer = ob->lay;
|
||||
layer &= 0xFFFFFF;
|
||||
|
||||
/* return pointer to this static var
|
||||
* - assumes that this pointer won't be stored for use later, so may not be threadsafe
|
||||
* if multiple keyframe calls are made, but that is unlikely to happen in the near future
|
||||
*/
|
||||
return (void *)(&layer);
|
||||
}
|
||||
/* no break here for other ob channel-types - as they can be done normally */
|
||||
|
||||
default: /* normal data-source */
|
||||
return get_ipo_poin(id, icu, vartype);
|
||||
}
|
||||
|
||||
/* not valid... */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* -------------- 'Smarter' Keyframing Functions -------------------- */
|
||||
/* return codes for new_key_needed */
|
||||
enum {
|
||||
KEYNEEDED_DONTADD = 0,
|
||||
KEYNEEDED_JUSTADD,
|
||||
KEYNEEDED_DELPREV,
|
||||
KEYNEEDED_DELNEXT
|
||||
} eKeyNeededStatus;
|
||||
|
||||
/* This helper function determines whether a new keyframe is needed */
|
||||
/* Cases where keyframes should not be added:
|
||||
* 1. Keyframe to be added bewteen two keyframes with similar values
|
||||
* 2. Keyframe to be added on frame where two keyframes are already situated
|
||||
* 3. Keyframe lies at point that intersects the linear line between two keyframes
|
||||
*/
|
||||
static short new_key_needed (IpoCurve *icu, float cFrame, float nValue)
|
||||
{
|
||||
BezTriple *bezt=NULL, *prev=NULL;
|
||||
int totCount, i;
|
||||
float valA = 0.0f, valB = 0.0f;
|
||||
|
||||
/* safety checking */
|
||||
if (icu == NULL) return KEYNEEDED_JUSTADD;
|
||||
totCount= icu->totvert;
|
||||
if (totCount == 0) return KEYNEEDED_JUSTADD;
|
||||
|
||||
/* loop through checking if any are the same */
|
||||
bezt= icu->bezt;
|
||||
for (i=0; i<totCount; i++) {
|
||||
float prevPosi=0.0f, prevVal=0.0f;
|
||||
float beztPosi=0.0f, beztVal=0.0f;
|
||||
|
||||
/* get current time+value */
|
||||
beztPosi= bezt->vec[1][0];
|
||||
beztVal= bezt->vec[1][1];
|
||||
|
||||
if (prev) {
|
||||
/* there is a keyframe before the one currently being examined */
|
||||
|
||||
/* get previous time+value */
|
||||
prevPosi= prev->vec[1][0];
|
||||
prevVal= prev->vec[1][1];
|
||||
|
||||
/* keyframe to be added at point where there are already two similar points? */
|
||||
if (IS_EQ(prevPosi, cFrame) && IS_EQ(beztPosi, cFrame) && IS_EQ(beztPosi, prevPosi)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
|
||||
/* keyframe between prev+current points ? */
|
||||
if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
|
||||
/* is the value of keyframe to be added the same as keyframes on either side ? */
|
||||
if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
else {
|
||||
float realVal;
|
||||
|
||||
/* get real value of curve at that point */
|
||||
realVal= eval_icu(icu, cFrame);
|
||||
|
||||
/* compare whether it's the same as proposed */
|
||||
if (IS_EQ(realVal, nValue))
|
||||
return KEYNEEDED_DONTADD;
|
||||
else
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
}
|
||||
|
||||
/* new keyframe before prev beztriple? */
|
||||
if (cFrame < prevPosi) {
|
||||
/* A new keyframe will be added. However, whether the previous beztriple
|
||||
* stays around or not depends on whether the values of previous/current
|
||||
* beztriples and new keyframe are the same.
|
||||
*/
|
||||
if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal))
|
||||
return KEYNEEDED_DELNEXT;
|
||||
else
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* just add a keyframe if there's only one keyframe
|
||||
* and the new one occurs before the exisiting one does.
|
||||
*/
|
||||
if ((cFrame < beztPosi) && (totCount==1))
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
|
||||
/* continue. frame to do not yet passed (or other conditions not met) */
|
||||
if (i < (totCount-1)) {
|
||||
prev= bezt;
|
||||
bezt++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* Frame in which to add a new-keyframe occurs after all other keys
|
||||
* -> If there are at least two existing keyframes, then if the values of the
|
||||
* last two keyframes and the new-keyframe match, the last existing keyframe
|
||||
* gets deleted as it is no longer required.
|
||||
* -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
|
||||
* keyframe is not equal to last keyframe.
|
||||
*/
|
||||
bezt= (icu->bezt + (icu->totvert - 1));
|
||||
valA= bezt->vec[1][1];
|
||||
|
||||
if (prev)
|
||||
valB= prev->vec[1][1];
|
||||
else
|
||||
valB= bezt->vec[1][1] + 1.0f;
|
||||
|
||||
if (IS_EQ(valA, nValue) && IS_EQ(valA, valB))
|
||||
return KEYNEEDED_DELPREV;
|
||||
else
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
|
||||
/* ------------------ 'Visual' Keyframing Functions ------------------ */
|
||||
|
||||
/* internal status codes for visualkey_can_use */
|
||||
enum {
|
||||
VISUALKEY_NONE = 0,
|
||||
VISUALKEY_LOC,
|
||||
VISUALKEY_ROT
|
||||
};
|
||||
|
||||
/* This helper function determines if visual-keyframing should be used when
|
||||
* inserting keyframes for the given channel. As visual-keyframing only works
|
||||
* on Object and Pose-Channel blocks, this should only get called for those
|
||||
* blocktypes, when using "standard" keying but 'Visual Keying' option in Auto-Keying
|
||||
* settings is on.
|
||||
*/
|
||||
static short visualkey_can_use (ID *id, int blocktype, char *actname, char *constname, int adrcode)
|
||||
{
|
||||
Object *ob= NULL;
|
||||
bConstraint *con= NULL;
|
||||
short searchtype= VISUALKEY_NONE;
|
||||
|
||||
/* validate data */
|
||||
if ((id == NULL) || (GS(id->name)!=ID_OB) || !(ELEM(blocktype, ID_OB, ID_PO)))
|
||||
return 0;
|
||||
|
||||
/* get first constraint and determine type of keyframe constraints to check for*/
|
||||
ob= (Object *)id;
|
||||
|
||||
if (blocktype == ID_OB) {
|
||||
con= ob->constraints.first;
|
||||
|
||||
if (ELEM3(adrcode, OB_LOC_X, OB_LOC_Y, OB_LOC_Z))
|
||||
searchtype= VISUALKEY_LOC;
|
||||
else if (ELEM3(adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z))
|
||||
searchtype= VISUALKEY_ROT;
|
||||
}
|
||||
else if (blocktype == ID_PO) {
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
|
||||
con= pchan->constraints.first;
|
||||
|
||||
if (ELEM3(adrcode, AC_LOC_X, AC_LOC_Y, AC_LOC_Z))
|
||||
searchtype= VISUALKEY_LOC;
|
||||
else if (ELEM4(adrcode, AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z))
|
||||
searchtype= VISUALKEY_ROT;
|
||||
}
|
||||
|
||||
/* only search if a searchtype and initial constraint are available */
|
||||
if (searchtype && con) {
|
||||
for (; con; con= con->next) {
|
||||
/* only consider constraint if it is not disabled, and has influence */
|
||||
if (con->flag & CONSTRAINT_DISABLE) continue;
|
||||
if (con->enforce == 0.0f) continue;
|
||||
|
||||
/* some constraints may alter these transforms */
|
||||
switch (con->type) {
|
||||
/* multi-transform constraints */
|
||||
case CONSTRAINT_TYPE_CHILDOF:
|
||||
return 1;
|
||||
case CONSTRAINT_TYPE_TRANSFORM:
|
||||
return 1;
|
||||
case CONSTRAINT_TYPE_FOLLOWPATH:
|
||||
return 1;
|
||||
|
||||
/* single-transform constraits */
|
||||
case CONSTRAINT_TYPE_TRACKTO:
|
||||
if (searchtype==VISUALKEY_ROT) return 1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_ROTLIMIT:
|
||||
if (searchtype==VISUALKEY_ROT) return 1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCLIMIT:
|
||||
if (searchtype==VISUALKEY_LOC) return 1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_ROTLIKE:
|
||||
if (searchtype==VISUALKEY_ROT) return 1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCLIKE:
|
||||
if (searchtype==VISUALKEY_LOC) return 1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCKTRACK:
|
||||
if (searchtype==VISUALKEY_ROT) return 1;
|
||||
break;
|
||||
case CONSTRAINT_TYPE_MINMAX:
|
||||
if (searchtype==VISUALKEY_LOC) return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* when some condition is met, this function returns, so here it can be 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This helper function extracts the value to use for visual-keyframing
|
||||
* In the event that it is not possible to perform visual keying, try to fall-back
|
||||
* to using the poin method. Assumes that all data it has been passed is valid.
|
||||
*/
|
||||
static float visualkey_get_value (ID *id, int blocktype, char *actname, char *constname, int adrcode, IpoCurve *icu)
|
||||
{
|
||||
Object *ob;
|
||||
void *poin = NULL;
|
||||
int index, vartype;
|
||||
|
||||
/* validate situtation */
|
||||
if ((id==NULL) || (GS(id->name)!=ID_OB) || (ELEM(blocktype, ID_OB, ID_PO)==0))
|
||||
return 0.0f;
|
||||
|
||||
/* get object */
|
||||
ob= (Object *)id;
|
||||
|
||||
/* only valid for objects or posechannels */
|
||||
if (blocktype == ID_OB) {
|
||||
/* parented objects are not supported, as the effects of the parent
|
||||
* are included in the matrix, which kindof beats the point
|
||||
*/
|
||||
if ((ob) && (ob->parent==NULL)) {
|
||||
/* only Location or Rotation keyframes are supported now */
|
||||
if (ELEM3(adrcode, OB_LOC_X, OB_LOC_Y, OB_LOC_Z)) {
|
||||
/* assumes that OB_LOC_Z > OB_LOC_Y > OB_LOC_X */
|
||||
index= adrcode - OB_LOC_X;
|
||||
|
||||
return ob->obmat[3][index];
|
||||
}
|
||||
else if (ELEM3(adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) {
|
||||
float eul[3];
|
||||
|
||||
/* assumes that OB_ROT_Z > OB_ROT_Y > OB_ROT_X */
|
||||
index= adrcode - OB_ROT_X;
|
||||
|
||||
Mat4ToEul(ob->obmat, eul);
|
||||
return eul[index]*(5.72958);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (blocktype == ID_PO) {
|
||||
bPoseChannel *pchan;
|
||||
float tmat[4][4];
|
||||
|
||||
/* get data to use */
|
||||
pchan= get_pose_channel(ob->pose, actname);
|
||||
|
||||
/* Although it is not strictly required for this particular space conversion,
|
||||
* arg1 must not be null, as there is a null check for the other conversions to
|
||||
* be safe. Therefore, the active object is passed here, and in many cases, this
|
||||
* will be what owns the pose-channel that is getting this anyway.
|
||||
*/
|
||||
Mat4CpyMat4(tmat, pchan->pose_mat);
|
||||
constraint_mat_convertspace(ob, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
|
||||
|
||||
/* Loc, Rot/Quat keyframes are supported... */
|
||||
if (ELEM3(adrcode, AC_LOC_X, AC_LOC_Y, AC_LOC_Z)) {
|
||||
/* assumes that AC_LOC_Z > AC_LOC_Y > AC_LOC_X */
|
||||
index= adrcode - AC_LOC_X;
|
||||
|
||||
/* only use for non-connected bones */
|
||||
if ((pchan->bone->parent) && !(pchan->bone->flag & BONE_CONNECTED))
|
||||
return tmat[3][index];
|
||||
else if (pchan->bone->parent == NULL)
|
||||
return tmat[3][index];
|
||||
}
|
||||
else if (ELEM4(adrcode, AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z)) {
|
||||
float tmat[4][4], trimat[3][3], quat[4];
|
||||
|
||||
/* assumes that AC_QUAT_Z > AC_QUAT_Y > AC_QUAT_X > AC_QUAT_W */
|
||||
index= adrcode - AC_QUAT_W;
|
||||
|
||||
Mat3CpyMat4(trimat, tmat);
|
||||
Mat3ToQuat_is_ok(trimat, quat);
|
||||
|
||||
return quat[index];
|
||||
}
|
||||
}
|
||||
|
||||
/* as the function hasn't returned yet, try reading from poin */
|
||||
get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
|
||||
if (poin)
|
||||
return read_ipo_poin(poin, vartype);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------- Insert Key API ------------------------- */
|
||||
|
||||
/* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it
|
||||
* already exists. It will insert a keyframe using the current value being keyframed.
|
||||
*
|
||||
* The flag argument is used for special settings that alter the behaviour of
|
||||
* the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
|
||||
* and extra keyframe filtering.
|
||||
*/
|
||||
short insertkey (ID *id, int blocktype, char *actname, char *constname, int adrcode, short flag)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
|
||||
/* get ipo-curve */
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
/* only continue if we have an ipo-curve to add keyframe to */
|
||||
if (icu) {
|
||||
float cfra = frame_to_float(CFRA);
|
||||
float curval= 0.0f;
|
||||
void *poin = NULL;
|
||||
int vartype;
|
||||
|
||||
/* apply special time tweaking */
|
||||
if (GS(id->name) == ID_OB) {
|
||||
Object *ob= (Object *)id;
|
||||
|
||||
/* apply NLA-scaling (if applicable) */
|
||||
if (actname && actname[0])
|
||||
cfra= get_action_frame(ob, cfra);
|
||||
|
||||
/* ancient time-offset cruft */
|
||||
if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
|
||||
/* actually frametofloat calc again! */
|
||||
cfra-= give_timeoffset(ob)*G.scene->r.framelen;
|
||||
}
|
||||
}
|
||||
|
||||
/* get pointer to data to read from */
|
||||
poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
|
||||
if (poin == NULL) return 0;
|
||||
|
||||
/* obtain value to give keyframe */
|
||||
if ( (flag & INSERTKEY_MATRIX) &&
|
||||
(visualkey_can_use(id, blocktype, actname, constname, adrcode)) )
|
||||
{
|
||||
/* visual-keying is only available for object and pchan datablocks, as
|
||||
* it works by keyframing using a value extracted from the final matrix
|
||||
* instead of using the kt system to extract a value.
|
||||
*/
|
||||
curval= visualkey_get_value(id, blocktype, actname, constname, adrcode, icu);
|
||||
}
|
||||
else {
|
||||
/* use kt's read_poin function to extract value (kt->read_poin should
|
||||
* exist in all cases, but it never hurts to check)
|
||||
*/
|
||||
curval= read_ipo_poin(poin, vartype);
|
||||
}
|
||||
|
||||
/* only insert keyframes where they are needed */
|
||||
if (flag & INSERTKEY_NEEDED) {
|
||||
short insert_mode;
|
||||
|
||||
/* check whether this curve really needs a new keyframe */
|
||||
insert_mode= new_key_needed(icu, cfra, curval);
|
||||
|
||||
/* insert new keyframe at current frame */
|
||||
if (insert_mode)
|
||||
insert_vert_icu(icu, cfra, curval, (flag & INSERTKEY_FAST));
|
||||
|
||||
/* delete keyframe immediately before/after newly added */
|
||||
switch (insert_mode) {
|
||||
case KEYNEEDED_DELPREV:
|
||||
delete_icu_key(icu, icu->totvert-2, 1);
|
||||
break;
|
||||
case KEYNEEDED_DELNEXT:
|
||||
delete_icu_key(icu, 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* just insert keyframe */
|
||||
insert_vert_icu(icu, cfra, curval, (flag & INSERTKEY_FAST));
|
||||
}
|
||||
|
||||
/* return success */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* return failure */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************** */
|
||||
/* KEYFRAME DELETION */
|
||||
|
||||
/* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it
|
||||
* already exists. It will delete a keyframe at the current frame.
|
||||
*
|
||||
* The flag argument is used for special settings that alter the behaviour of
|
||||
* the keyframe deletion. These include the quick refresh options.
|
||||
*/
|
||||
short deletekey (ID *id, int blocktype, char *actname, char *constname, int adrcode, short flag)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
|
||||
// locate ipo-curve
|
||||
icu= NULL; // fixme..
|
||||
|
||||
// TODO: implement me!
|
||||
|
||||
/* return failure */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
/* COMMON KEYFRAME MANAGEMENT (common_insertkey/deletekey) */
|
||||
|
||||
|
||||
/* ------------- KeyingSet Defines ------------ */
|
||||
/* Note: these must all be named with the defks_* prefix, otherwise the template macro will not work! */
|
||||
|
||||
/* macro for defining keyingset contexts */
|
||||
#define KSC_TEMPLATE(ctx_name) {&defks_##ctx_name[0], NULL, sizeof(defks_##ctx_name)/sizeof(bKeyingSet)}
|
||||
|
||||
/* --- */
|
||||
|
||||
/* Object KeyingSets ------ */
|
||||
|
||||
/* check if include shapekey entry */
|
||||
static short incl_v3d_ob_shapekey (bKeyingSet *ks, const char mode[])
|
||||
{
|
||||
Object *ob= (G.obedit)? (G.obedit) : (OBACT);
|
||||
char *newname= NULL;
|
||||
|
||||
/* not available for delete mode */
|
||||
if (strcmp(mode, "Delete")==0)
|
||||
return 0;
|
||||
|
||||
/* check if is geom object that can get shapekeys */
|
||||
switch (ob->type) {
|
||||
/* geometry? */
|
||||
case OB_MESH: newname= "Mesh"; break;
|
||||
case OB_CURVE: newname= "Curve"; break;
|
||||
case OB_SURF: newname= "Surface"; break;
|
||||
case OB_LATTICE: newname= "Lattice"; break;
|
||||
|
||||
/* not geometry! */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if ks is shapekey entry (this could be callled for separator before too!) */
|
||||
if (ks->flag == -3)
|
||||
sprintf(ks->name, newname);
|
||||
|
||||
/* if it gets here, it's ok */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* array for object keyingset defines */
|
||||
bKeyingSet defks_v3d_object[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "Loc", ID_OB, 0, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
|
||||
{NULL, "Rot", ID_OB, 0, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
|
||||
{NULL, "Scale", ID_OB, 0, 3, {OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "LocRot", ID_OB, 0, 6,
|
||||
{OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
|
||||
OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
|
||||
|
||||
{NULL, "LocScale", ID_OB, 0, 6,
|
||||
{OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
|
||||
OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
|
||||
|
||||
{NULL, "LocRotScale", ID_OB, 0, 9,
|
||||
{OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
|
||||
OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
|
||||
OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
|
||||
|
||||
{NULL, "RotScale", ID_OB, 0, 6,
|
||||
{OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
|
||||
OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "VisualLoc", ID_OB, INSERTKEY_MATRIX, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
|
||||
{NULL, "VisualRot", ID_OB, INSERTKEY_MATRIX, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
|
||||
|
||||
{NULL, "VisualLocRot", ID_OB, INSERTKEY_MATRIX, 6,
|
||||
{OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
|
||||
OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Layer", ID_OB, 0, 1, {OB_LAY}}, // icky option...
|
||||
{NULL, "Available", ID_OB, -2, 0, {}},
|
||||
|
||||
{incl_v3d_ob_shapekey, "%l%l", 0, -1, 0, {}}, // separator (linked to shapekey entry)
|
||||
{incl_v3d_ob_shapekey, "<ShapeKey>", ID_OB, -3, 0, {}}
|
||||
};
|
||||
|
||||
/* PoseChannel KeyingSets ------ */
|
||||
|
||||
/* array for posechannel keyingset defines */
|
||||
bKeyingSet defks_v3d_pchan[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "Loc", ID_PO, 0, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
|
||||
{NULL, "Rot", ID_PO, 0, 4, {AC_QUAT_W,AC_QUAT_X,AC_QUAT_Y,AC_QUAT_Z}},
|
||||
{NULL, "Scale", ID_PO, 0, 3, {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "LocRot", ID_PO, 0, 7,
|
||||
{AC_LOC_X,AC_LOC_Y,AC_LOC_Z,AC_QUAT_W,
|
||||
AC_QUAT_X,AC_QUAT_Y,AC_QUAT_Z}},
|
||||
|
||||
{NULL, "LocScale", ID_PO, 0, 6,
|
||||
{AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
|
||||
AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
|
||||
|
||||
{NULL, "LocRotScale", ID_PO, 0, 10,
|
||||
{AC_LOC_X,AC_LOC_Y,AC_LOC_Z,AC_QUAT_W,AC_QUAT_X,
|
||||
AC_QUAT_Y,AC_QUAT_Z,AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
|
||||
|
||||
{NULL, "RotScale", ID_PO, 0, 7,
|
||||
{AC_QUAT_W,AC_QUAT_X,AC_QUAT_Y,AC_QUAT_Z,
|
||||
AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "VisualLoc", ID_PO, INSERTKEY_MATRIX, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
|
||||
{NULL, "VisualRot", ID_PO, INSERTKEY_MATRIX, 3, {AC_QUAT_W,AC_QUAT_X,AC_QUAT_Y,AC_QUAT_Z}},
|
||||
|
||||
{NULL, "VisualLocRot", ID_PO, INSERTKEY_MATRIX, 7,
|
||||
{AC_LOC_X,AC_LOC_Y,AC_LOC_Z,AC_QUAT_W,
|
||||
AC_QUAT_X,AC_QUAT_Y,AC_QUAT_Z}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_PO, -2, 0, {}}
|
||||
};
|
||||
|
||||
/* Material KeyingSets ------ */
|
||||
|
||||
/* array for material keyingset defines */
|
||||
bKeyingSet defks_buts_shading_mat[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "RGB", ID_MA, 0, 3, {MA_COL_R,MA_COL_G,MA_COL_B}},
|
||||
{NULL, "Alpha", ID_MA, 0, 1, {MA_ALPHA}},
|
||||
{NULL, "Halo Size", ID_MA, 0, 1, {MA_HASIZE}},
|
||||
{NULL, "Mode", ID_MA, 0, 1, {MA_MODE}}, // evil bitflags
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "All Color", ID_MA, 0, 18,
|
||||
{MA_COL_R,MA_COL_G,MA_COL_B,
|
||||
MA_ALPHA,MA_HASIZE, MA_MODE,
|
||||
MA_SPEC_R,MA_SPEC_G,MA_SPEC_B,
|
||||
MA_REF,MA_EMIT,MA_AMB,MA_SPEC,MA_HARD,
|
||||
MA_MODE,MA_TRANSLU,MA_ADD}},
|
||||
|
||||
{NULL, "All Mirror", ID_MA, 0, 5,
|
||||
{MA_RAYM,MA_FRESMIR,MA_FRESMIRI,
|
||||
MA_FRESTRA,MA_FRESTRAI}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Ofs", ID_MA, 0, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
|
||||
{NULL, "Size", ID_MA, 0, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
|
||||
|
||||
{NULL, "All Mapping", ID_MA, 0, 14,
|
||||
{MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
|
||||
MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
|
||||
MAP_R,MAP_G,MAP_B,MAP_DVAR,
|
||||
MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_MA, -2, 0, {}}
|
||||
};
|
||||
|
||||
/* World KeyingSets ------ */
|
||||
|
||||
/* array for world keyingset defines */
|
||||
bKeyingSet defks_buts_shading_wo[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "Zenith RGB", ID_WO, 0, 3, {WO_ZEN_R,WO_ZEN_G,WO_ZEN_B}},
|
||||
{NULL, "Horizon RGB", ID_WO, 0, 3, {WO_HOR_R,WO_HOR_G,WO_HOR_B}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Mist", ID_WO, 0, 4, {WO_MISI,WO_MISTDI,WO_MISTSTA,WO_MISTHI}},
|
||||
{NULL, "Stars", ID_WO, 0, 5, {WO_STAR_R,WO_STAR_G,WO_STAR_B,WO_STARDIST,WO_STARSIZE}},
|
||||
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Ofs", ID_WO, 0, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
|
||||
{NULL, "Size", ID_WO, 0, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
|
||||
|
||||
{NULL, "All Mapping", ID_WO, 0, 14,
|
||||
{MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
|
||||
MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
|
||||
MAP_R,MAP_G,MAP_B,MAP_DVAR,
|
||||
MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_WO, -2, 0, {}}
|
||||
};
|
||||
|
||||
/* Lamp KeyingSets ------ */
|
||||
|
||||
/* array for lamp keyingset defines */
|
||||
bKeyingSet defks_buts_shading_la[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "RGB", ID_LA, 0, 3, {LA_COL_R,LA_COL_G,LA_COL_B}},
|
||||
{NULL, "Energy", ID_LA, 0, 1, {LA_ENERGY}},
|
||||
{NULL, "Spot Size", ID_LA, 0, 1, {LA_SPOTSI}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Ofs", ID_LA, 0, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
|
||||
{NULL, "Size", ID_LA, 0, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
|
||||
|
||||
{NULL, "All Mapping", ID_LA, 0, 14,
|
||||
{MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
|
||||
MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
|
||||
MAP_R,MAP_G,MAP_B,MAP_DVAR,
|
||||
MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_LA, -2, 0, {}}
|
||||
};
|
||||
|
||||
/* Texture KeyingSets ------ */
|
||||
|
||||
/* array for texture keyingset defines */
|
||||
bKeyingSet defks_buts_shading_tex[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "Clouds", ID_TE, 0, 5,
|
||||
{TE_NSIZE,TE_NDEPTH,TE_NTYPE,
|
||||
TE_MG_TYP,TE_N_BAS1}},
|
||||
|
||||
{NULL, "Marble", ID_TE, 0, 7,
|
||||
{TE_NSIZE,TE_NDEPTH,TE_NTYPE,
|
||||
TE_TURB,TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
|
||||
|
||||
{NULL, "Stucci", ID_TE, 0, 5,
|
||||
{TE_NSIZE,TE_NTYPE,TE_TURB,
|
||||
TE_MG_TYP,TE_N_BAS1}},
|
||||
|
||||
{NULL, "Wood", ID_TE, 0, 6,
|
||||
{TE_NSIZE,TE_NTYPE,TE_TURB,
|
||||
TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
|
||||
|
||||
{NULL, "Magic", ID_TE, 0, 2, {TE_NDEPTH,TE_TURB}},
|
||||
|
||||
{NULL, "Blend", ID_TE, 0, 1, {TE_MG_TYP}},
|
||||
|
||||
{NULL, "Musgrave", ID_TE, 0, 6,
|
||||
{TE_MG_TYP,TE_MGH,TE_MG_LAC,
|
||||
TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN}},
|
||||
|
||||
{NULL, "Voronoi", ID_TE, 0, 9,
|
||||
{TE_VNW1,TE_VNW2,TE_VNW3,TE_VNW4,
|
||||
TE_VNMEXP,TE_VN_DISTM,TE_VN_COLT,
|
||||
TE_ISCA,TE_NSIZE}},
|
||||
|
||||
{NULL, "Distorted Noise", ID_TE, 0, 4,
|
||||
{TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN,TE_DISTA}},
|
||||
|
||||
{NULL, "Color Filter", ID_TE, 0, 5,
|
||||
{TE_COL_R,TE_COL_G,TE_COL_B,TE_BRIGHT,TE_CONTRA}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_TE, -2, 0, {}}
|
||||
};
|
||||
|
||||
/* Object Buttons KeyingSets ------ */
|
||||
|
||||
/* check if include particles entry */
|
||||
static short incl_buts_ob (bKeyingSet *ks, const char mode[])
|
||||
{
|
||||
Object *ob= OBACT;
|
||||
/* only if object is mesh type */
|
||||
return (ob->type == OB_MESH);
|
||||
}
|
||||
|
||||
/* array for texture keyingset defines */
|
||||
bKeyingSet defks_buts_object[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{incl_buts_ob, "Surface Damping", ID_OB, 0, 1, {OB_PD_SDAMP}},
|
||||
{incl_buts_ob, "Random Damping", ID_OB, 0, 1, {OB_PD_RDAMP}},
|
||||
{incl_buts_ob, "Permeability", ID_OB, 0, 1, {OB_PD_PERM}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Force Strength", ID_OB, 0, 1, {OB_PD_FSTR}},
|
||||
{NULL, "Force Falloff", ID_OB, 0, 1, {OB_PD_FFALL}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_OB, -2, 0, {}} // this will include ob-transforms too!
|
||||
};
|
||||
|
||||
/* Camera Buttons KeyingSets ------ */
|
||||
|
||||
/* check if include internal-renderer entry */
|
||||
static short incl_buts_cam1 (bKeyingSet *ks, const char mode[])
|
||||
{
|
||||
/* only if renderer is internal renderer */
|
||||
return (G.scene->r.renderer==R_INTERN);
|
||||
}
|
||||
|
||||
/* check if include external-renderer entry */
|
||||
static short incl_buts_cam2 (bKeyingSet *ks, const char mode[])
|
||||
{
|
||||
/* only if renderer is internal renderer */
|
||||
return (G.scene->r.renderer!=R_INTERN);
|
||||
}
|
||||
|
||||
/* array for camera keyingset defines */
|
||||
bKeyingSet defks_buts_cam[] =
|
||||
{
|
||||
/* include_cb, name, blocktype, flag, chan_num, adrcodes */
|
||||
{NULL, "Lens", ID_CA, 0, 1, {CAM_LENS}},
|
||||
{NULL, "Clipping", ID_CA, 0, 2, {CAM_STA,CAM_END}},
|
||||
{NULL, "Focal Distance", ID_CA, 0, 1, {CAM_YF_FDIST}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
|
||||
{incl_buts_cam2, "Aperture", ID_CA, 0, 1, {CAM_YF_APERT}},
|
||||
{incl_buts_cam1, "Viewplane Shift", ID_CA, 0, 2, {CAM_SHIFT_X,CAM_SHIFT_Y}},
|
||||
|
||||
{NULL, "%l", 0, -1, 0, {}}, // separator
|
||||
|
||||
{NULL, "Available", ID_CA, -2, 0, {}}
|
||||
};
|
||||
|
||||
/* --- */
|
||||
|
||||
/* Keying Context Defines - Must keep in sync with enumeration (eKS_Contexts) */
|
||||
bKeyingContext ks_contexts[] =
|
||||
{
|
||||
KSC_TEMPLATE(v3d_object),
|
||||
KSC_TEMPLATE(v3d_pchan),
|
||||
|
||||
KSC_TEMPLATE(buts_shading_mat),
|
||||
KSC_TEMPLATE(buts_shading_wo),
|
||||
KSC_TEMPLATE(buts_shading_la),
|
||||
KSC_TEMPLATE(buts_shading_tex),
|
||||
|
||||
KSC_TEMPLATE(buts_object),
|
||||
KSC_TEMPLATE(buts_cam)
|
||||
};
|
||||
|
||||
/* Keying Context Enumeration - Must keep in sync with definitions*/
|
||||
typedef enum eKS_Contexts {
|
||||
KSC_V3D_OBJECT = 0,
|
||||
KSC_V3D_PCHAN,
|
||||
|
||||
KSC_BUTS_MAT,
|
||||
KSC_BUTS_WO,
|
||||
KSC_BUTS_LA,
|
||||
KSC_BUTS_TEX,
|
||||
|
||||
KSC_BUTS_OB,
|
||||
KSC_BUTS_CAM,
|
||||
|
||||
/* make sure this last one remains untouched! */
|
||||
KSC_TOT_TYPES
|
||||
} eKS_Contexts;
|
||||
|
||||
|
||||
/* ---------------- KeyingSet Tools ------------------- */
|
||||
|
||||
/* helper for commonkey_context_get() - get keyingsets for 3d-view */
|
||||
static void commonkey_context_getv3d (ListBase *sources, bKeyingContext **ksc)
|
||||
{
|
||||
Object *ob;
|
||||
IpoCurve *icu;
|
||||
|
||||
if ((OBACT) && (OBACT->flag & OB_POSEMODE)) {
|
||||
bPoseChannel *pchan;
|
||||
|
||||
/* pose-level */
|
||||
ob= OBACT;
|
||||
*ksc= &ks_contexts[KSC_V3D_PCHAN];
|
||||
set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
|
||||
|
||||
/* loop through posechannels */
|
||||
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
|
||||
if (pchan->flag & POSE_KEY) {
|
||||
bCommonKeySrc *cks;
|
||||
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set id-block to key to, and action */
|
||||
cks->id= (ID *)ob;
|
||||
cks->act= ob->action;
|
||||
|
||||
/* set pchan */
|
||||
cks->pchan= pchan;
|
||||
cks->actname= pchan->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Base *base;
|
||||
|
||||
/* object-level */
|
||||
*ksc= &ks_contexts[KSC_V3D_OBJECT];
|
||||
|
||||
/* loop through bases */
|
||||
for (base= FIRSTBASE; base; base= base->next) {
|
||||
if (TESTBASELIB(base)) {
|
||||
bCommonKeySrc *cks;
|
||||
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set id-block to key to */
|
||||
ob= base->object;
|
||||
cks->id= (ID *)ob;
|
||||
|
||||
/* when ob's keyframes are in an action, default to using 'Object' as achan name */
|
||||
if (ob->ipoflag & OB_ACTION_OB)
|
||||
cks->actname= "Object";
|
||||
|
||||
/* set ipo-flags */
|
||||
// TODO: add checks for lib-linked data
|
||||
if ((ob->ipo) || (ob->action)) {
|
||||
if (ob->ipo) {
|
||||
cks->ipo= ob->ipo;
|
||||
}
|
||||
else {
|
||||
bActionChannel *achan;
|
||||
|
||||
cks->act= ob->action;
|
||||
achan= get_action_channel(ob->action, cks->actname);
|
||||
|
||||
if (achan && achan->ipo)
|
||||
cks->ipo= achan->ipo;
|
||||
}
|
||||
|
||||
/* deselect all ipo-curves */
|
||||
for (icu= cks->ipo->curve.first; icu; icu= icu->next) {
|
||||
icu->flag &= ~IPO_SELECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* helper for commonkey_context_get() - get keyingsets for buttons window */
|
||||
// nb - for mtex entries... need to set map (= texchan_to_adrcode(id->texact)
|
||||
static void commonkey_context_getsbuts (ListBase *sources, bKeyingContext **ksc)
|
||||
{
|
||||
bCommonKeySrc *cks;
|
||||
|
||||
/* check on tab-type */
|
||||
switch (G.buts->mainb) {
|
||||
case CONTEXT_SHADING: /* ------------- Shading buttons ---------------- */
|
||||
/* subtabs include "Material", "Texture", "Lamp", "World"*/
|
||||
switch (G.buts->tab[CONTEXT_SHADING]) {
|
||||
case TAB_SHADING_MAT: /* >------------- Material Tab -------------< */
|
||||
{
|
||||
Material *ma= editnode_get_active_material(G.buts->lockpoin);
|
||||
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set data */
|
||||
cks->id= (ID *)ma;
|
||||
cks->map= texchannel_to_adrcode(ma->texact);
|
||||
|
||||
/* set keyingsets */
|
||||
*ksc= &ks_contexts[KSC_BUTS_MAT];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TAB_SHADING_WORLD: /* >------------- World Tab -------------< */
|
||||
{
|
||||
World *wo= G.buts->lockpoin;
|
||||
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set data */
|
||||
cks->id= (ID *)wo;
|
||||
cks->map= texchannel_to_adrcode(wo->texact);
|
||||
|
||||
/* set keyingsets */
|
||||
*ksc= &ks_contexts[KSC_BUTS_WO];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TAB_SHADING_LAMP: /* >------------- Lamp Tab -------------< */
|
||||
{
|
||||
Lamp *la= G.buts->lockpoin;
|
||||
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set data */
|
||||
cks->id= (ID *)la;
|
||||
cks->map= texchannel_to_adrcode(la->texact);
|
||||
|
||||
/* set keyingsets */
|
||||
*ksc= &ks_contexts[KSC_BUTS_LA];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TAB_SHADING_TEX: /* >------------- Texture Tab -------------< */
|
||||
{
|
||||
Tex *te= G.buts->lockpoin;
|
||||
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set data */
|
||||
cks->id= (ID *)te;
|
||||
|
||||
/* set keyingsets */
|
||||
*ksc= &ks_contexts[KSC_BUTS_TEX];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTEXT_OBJECT: /* ------------- Object buttons ---------------- */
|
||||
{
|
||||
Object *ob= OBACT;
|
||||
|
||||
if (ob) {
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set id-block to key to */
|
||||
cks->id= (ID *)ob;
|
||||
|
||||
/* set keyingsets */
|
||||
*ksc= &ks_contexts[KSC_BUTS_OB];
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTEXT_EDITING: /* ------------- Editing buttons ---------------- */
|
||||
{
|
||||
Object *ob= OBACT;
|
||||
|
||||
if ((ob) && (ob->type==OB_CAMERA)) { /* >---------------- camera buttons ---------------< */
|
||||
/* add new keyframing destination */
|
||||
cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
|
||||
BLI_addtail(sources, cks);
|
||||
|
||||
/* set id-block to key to */
|
||||
cks->id= (ID *)ob;
|
||||
|
||||
/* set keyingsets */
|
||||
*ksc= &ks_contexts[KSC_BUTS_CAM];
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* if nothing happened... */
|
||||
*ksc= NULL;
|
||||
}
|
||||
|
||||
|
||||
/* get keyingsets for appropriate context */
|
||||
static void commonkey_context_get (ListBase *sources, bKeyingContext **ksc)
|
||||
{
|
||||
/* check view type */
|
||||
switch (curarea->spacetype) {
|
||||
/* 3d view - first one tested as most often used */
|
||||
case SPACE_VIEW3D:
|
||||
commonkey_context_getv3d(sources, ksc);
|
||||
break;
|
||||
|
||||
/* buttons view */
|
||||
case SPACE_BUTS:
|
||||
commonkey_context_getsbuts(sources, ksc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush updates after all operations */
|
||||
static void commonkey_context_finish (ListBase *sources)
|
||||
{
|
||||
/* check view type */
|
||||
switch (curarea->spacetype) {
|
||||
/* 3d view - first one tested as most often used */
|
||||
case SPACE_VIEW3D:
|
||||
{
|
||||
/* either pose or object level */
|
||||
if (OBACT && (OBACT->pose)) {
|
||||
Object *ob= OBACT;
|
||||
|
||||
/* recalculate ipo handles, etc. */
|
||||
if (ob->action)
|
||||
remake_action_ipos(ob->action);
|
||||
|
||||
/* recalculate bone-paths on adding new keyframe? */
|
||||
// TODO: currently, there is no setting to turn this on/off globally
|
||||
if (ob->pose->flag & POSE_RECALCPATHS)
|
||||
pose_recalculate_paths(ob);
|
||||
}
|
||||
else {
|
||||
bCommonKeySrc *cks;
|
||||
|
||||
/* loop over bases (as seen in sources) */
|
||||
for (cks= sources->first; cks; cks= cks->next) {
|
||||
Object *ob= (Object *)cks->id;
|
||||
|
||||
/* simply set recalc flag */
|
||||
ob->recalc |= OB_RECALC_OB;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush refreshes after undo */
|
||||
static void commonkey_context_refresh (void)
|
||||
{
|
||||
/* check view type */
|
||||
switch (curarea->spacetype) {
|
||||
/* 3d view - first one tested as most often used */
|
||||
case SPACE_VIEW3D:
|
||||
{
|
||||
/* do refreshes */
|
||||
DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
|
||||
|
||||
allspace(REMAKEIPO, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWMARKER, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- */
|
||||
|
||||
/* Build menu-string of available keying-sets (allocates memory for string)
|
||||
* NOTE: mode must not be longer than 64 chars
|
||||
*/
|
||||
static char *build_keyingsets_menu (bKeyingContext *ksc, const char mode[48])
|
||||
{
|
||||
DynStr *pupds= BLI_dynstr_new();
|
||||
bKeyingSet *ks;
|
||||
char buf[64];
|
||||
char *str;
|
||||
int i, n;
|
||||
|
||||
/* add title first */
|
||||
BLI_snprintf(buf, 64, "%s Key %%t|", mode);
|
||||
BLI_dynstr_append(pupds, buf);
|
||||
|
||||
/* loop through keyingsets, adding them */
|
||||
for (ks=ksc->keyingsets, i=0, n=1; i < ksc->tot; ks++, i++, n++) {
|
||||
/* check if keyingset can be used */
|
||||
if (ks->flag == -1) {
|
||||
/* optional separator? */
|
||||
if (ks->include_cb) {
|
||||
if (ks->include_cb(ks, mode)) {
|
||||
BLI_snprintf( buf, 64, "%s%s", ks->name, ((n < ksc->tot)?"|":"") );
|
||||
BLI_dynstr_append(pupds, buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_snprintf( buf, 64, "%%l%s", ((n < ksc->tot)?"|":"") );
|
||||
BLI_dynstr_append(pupds, buf);
|
||||
}
|
||||
}
|
||||
else if ( (ks->include_cb==NULL) || (ks->include_cb(ks, mode)) ) {
|
||||
/* entry can be included */
|
||||
BLI_dynstr_append(pupds, ks->name);
|
||||
|
||||
/* check if special "shapekey" entry */
|
||||
if (ks->flag == -3)
|
||||
BLI_snprintf( buf, 64, "%%x0%s", ((n < ksc->tot)?"|":"") );
|
||||
else
|
||||
BLI_snprintf( buf, 64, "%%x%d%s", n, ((n < ksc->tot)?"|":"") );
|
||||
BLI_dynstr_append(pupds, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to normal MEM_malloc'd string */
|
||||
str= BLI_dynstr_get_cstring(pupds);
|
||||
BLI_dynstr_free(pupds);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Get the keying set that was chosen by the user from the menu */
|
||||
static bKeyingSet *get_keyingset_fromcontext (bKeyingContext *ksc, short index)
|
||||
{
|
||||
/* check if index is valid */
|
||||
if (ELEM(NULL, ksc, ksc->keyingsets))
|
||||
return NULL;
|
||||
if ((index < 1) || (index > ksc->tot))
|
||||
return NULL;
|
||||
|
||||
/* index starts from 1, and should directly correspond to keyingset in array */
|
||||
return (bKeyingSet *)(ksc->keyingsets + (index - 1));
|
||||
}
|
||||
|
||||
/* ---------------- Keyframe Management API -------------------- */
|
||||
|
||||
/* mode for common_modifykey */
|
||||
enum {
|
||||
COMMONKEY_MODE_INSERT = 0,
|
||||
COMMONKEY_MODE_DELETE,
|
||||
} eCommonModifyKey_Modes;
|
||||
|
||||
/* Display a menu for handling the insertion of keyframes based on the active view */
|
||||
// TODO: add back an option for repeating last keytype
|
||||
void common_modifykey (short mode)
|
||||
{
|
||||
ListBase dsources = {NULL, NULL};
|
||||
bKeyingContext *ksc= NULL;
|
||||
bCommonKeySrc *cks;
|
||||
bKeyingSet *ks = NULL;
|
||||
char *menustr, buf[64];
|
||||
short menu_nr;
|
||||
|
||||
/* check if mode is valid */
|
||||
if (ELEM(mode, COMMONKEY_MODE_INSERT, COMMONKEY_MODE_DELETE)==0)
|
||||
return;
|
||||
|
||||
/* delegate to other functions or get keyingsets to use */
|
||||
switch (curarea->spacetype) {
|
||||
/* spaces with their own methods */
|
||||
case SPACE_IPO:
|
||||
if (mode == COMMONKEY_MODE_INSERT)
|
||||
insertkey_editipo();
|
||||
return;
|
||||
case SPACE_ACTION:
|
||||
if (mode == COMMONKEY_MODE_INSERT)
|
||||
insertkey_action();
|
||||
return;
|
||||
|
||||
/* TODO: based on UI elements? will that even be handled here??? */
|
||||
|
||||
/* default - check per view */
|
||||
default:
|
||||
/* get the keyingsets and the data to add keyframes to */
|
||||
commonkey_context_get(&dsources, &ksc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* check that there is data to operate on */
|
||||
if (ELEM(NULL, dsources.first, ksc)) {
|
||||
BLI_freelistN(&dsources);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get menu and process it */
|
||||
if (mode == COMMONKEY_MODE_DELETE)
|
||||
menustr= build_keyingsets_menu(ksc, "Delete");
|
||||
else
|
||||
menustr= build_keyingsets_menu(ksc, "Insert");
|
||||
menu_nr= pupmenu(menustr);
|
||||
if (menustr) MEM_freeN(menustr);
|
||||
|
||||
/* no item selected or shapekey entry? */
|
||||
if (menu_nr < 1) {
|
||||
/* free temp sources */
|
||||
BLI_freelistN(&dsources);
|
||||
|
||||
/* check if insert new shapekey */
|
||||
if ((menu_nr == 0) && (mode == COMMONKEY_MODE_INSERT))
|
||||
insert_shapekey(OBACT);
|
||||
else
|
||||
ksc->lastused= NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
/* try to get keyingset */
|
||||
ks= get_keyingset_fromcontext(ksc, menu_nr);
|
||||
|
||||
if (ks == NULL) {
|
||||
BLI_freelistN(&dsources);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* loop over each destination, applying the keying set */
|
||||
for (cks= dsources.first; cks; cks= cks->next) {
|
||||
short success= 0;
|
||||
|
||||
/* special hacks for 'available' option */
|
||||
if (ks->flag == -2) {
|
||||
IpoCurve *icu= NULL;
|
||||
|
||||
/* get first IPO-curve */
|
||||
if (cks->act && cks->actname) {
|
||||
bActionChannel *achan= get_action_channel(cks->act, cks->actname);
|
||||
|
||||
// FIXME: what about constraint channels?
|
||||
if (achan && achan->ipo)
|
||||
icu= achan->ipo->curve.first;
|
||||
}
|
||||
else
|
||||
icu= cks->ipo->curve.first;
|
||||
|
||||
/* we get adrcodes directly from IPO curves (see method below...) */
|
||||
for (; icu; icu= icu->next) {
|
||||
short flag;
|
||||
|
||||
/* insert mode or delete mode */
|
||||
if (mode == COMMONKEY_MODE_DELETE) {
|
||||
/* local flags only add on to global flags */
|
||||
flag = 0;
|
||||
|
||||
/* delete keyframe */
|
||||
success += deletekey(cks->id, ks->blocktype, cks->actname, cks->constname, icu->adrcode, flag);
|
||||
}
|
||||
else {
|
||||
/* local flags only add on to global flags */
|
||||
flag = ks->flag;
|
||||
if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
|
||||
// if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
|
||||
|
||||
/* insert keyframe */
|
||||
success += insertkey(cks->id, ks->blocktype, cks->actname, cks->constname, icu->adrcode, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
/* loop over channels available in keyingset */
|
||||
for (i=0; i < ks->chan_num; i++) {
|
||||
short flag, adrcode;
|
||||
|
||||
/* get adrcode
|
||||
* - certain adrcodes (for MTEX channels need special offsets) // BAD CRUFT!!!
|
||||
*/
|
||||
adrcode= ks->adrcodes[i];
|
||||
if (ELEM3(ks->blocktype, ID_MA, ID_LA, ID_WO)) {
|
||||
switch (adrcode) {
|
||||
case MAP_OFS_X: case MAP_OFS_Y: case MAP_OFS_Z:
|
||||
case MAP_SIZE_X: case MAP_SIZE_Y: case MAP_SIZE_Z:
|
||||
case MAP_R: case MAP_G: case MAP_B: case MAP_DVAR:
|
||||
case MAP_COLF: case MAP_NORF: case MAP_VARF: case MAP_DISP:
|
||||
adrcode += cks->map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert mode or delete mode */
|
||||
if (mode == COMMONKEY_MODE_DELETE) {
|
||||
/* local flags only add on to global flags */
|
||||
flag = 0;
|
||||
|
||||
/* delete keyframe */
|
||||
success += deletekey(cks->id, ks->blocktype, cks->actname, cks->constname, adrcode, flag);
|
||||
}
|
||||
else {
|
||||
/* local flags only add on to global flags */
|
||||
flag = ks->flag;
|
||||
if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
|
||||
// if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
|
||||
|
||||
/* insert keyframe */
|
||||
success += insertkey(cks->id, ks->blocktype, cks->actname, cks->constname, adrcode, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* special handling for some key-sources */
|
||||
if (success) {
|
||||
/* set pose recalc-paths flag */
|
||||
if (cks->pchan) {
|
||||
Object *ob= (Object *)cks->id;
|
||||
bPoseChannel *pchan= cks->pchan;
|
||||
|
||||
/* set flag to trigger path recalc */
|
||||
if (pchan->path)
|
||||
ob->pose->flag |= POSE_RECALCPATHS;
|
||||
|
||||
/* clear unkeyed flag (it doesn't matter if it's set or not) */
|
||||
if (pchan->bone)
|
||||
pchan->bone->flag &= ~BONE_UNKEYED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* apply post-keying flushes for this data sources */
|
||||
commonkey_context_finish(&dsources);
|
||||
ksc->lastused= ks;
|
||||
|
||||
/* free temp data */
|
||||
BLI_freelistN(&dsources);
|
||||
|
||||
/* undo pushes */
|
||||
if (mode == COMMONKEY_MODE_DELETE)
|
||||
BLI_snprintf(buf, 64, "Delete %s Key", ks->name);
|
||||
else
|
||||
BLI_snprintf(buf, 64, "Insert %s Key", ks->name);
|
||||
BIF_undo_push(buf);
|
||||
|
||||
/* queue updates for contexts */
|
||||
commonkey_context_refresh();
|
||||
}
|
||||
|
||||
/* ---- */
|
||||
|
||||
/* used to insert keyframes from any view */
|
||||
void common_insertkey (void)
|
||||
{
|
||||
common_modifykey(COMMONKEY_MODE_INSERT);
|
||||
}
|
||||
|
||||
/* used to insert keyframes from any view */
|
||||
void common_deletekey (void)
|
||||
{
|
||||
common_modifykey(COMMONKEY_MODE_DELETE);
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
@@ -61,7 +61,7 @@
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
//#include "BIF_keyframing.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BSE_editipo.h"
|
||||
|
||||
#include "BDR_drawaction.h"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_graphics.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
@@ -406,6 +407,7 @@ void pose_recalculate_paths(Object *ob)
|
||||
waitcursor(0);
|
||||
|
||||
CFRA= cfra;
|
||||
ob->pose->flag &= ~POSE_RECALCPATHS;
|
||||
allqueue(REDRAWVIEW3D, 0); /* recalc tags are still there */
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
#include "BIF_imasel.h"
|
||||
#include "BIF_editparticle.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_previewrender.h"
|
||||
#include "BIF_renderwin.h"
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
#include "BIF_graphics.h"
|
||||
#include "BIF_imasel.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_mainqueue.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_renderwin.h"
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
#include "BIF_editsima.h"
|
||||
#include "BIF_editparticle.h"
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_mywindow.h"
|
||||
@@ -3562,22 +3563,25 @@ short autokeyframe_cfra_can_key(Object *ob)
|
||||
*/
|
||||
void autokeyframe_ob_cb_func(Object *ob, int tmode)
|
||||
{
|
||||
ID *id= (ID *)(ob);
|
||||
IpoCurve *icu;
|
||||
|
||||
if (autokeyframe_cfra_can_key(ob)) {
|
||||
char *actname = NULL;
|
||||
short flag = 0;
|
||||
|
||||
if (ob->ipoflag & OB_ACTION_OB)
|
||||
actname= "Object";
|
||||
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
|
||||
flag |= INSERTKEY_NEEDED;
|
||||
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
|
||||
flag |= INSERTKEY_MATRIX;
|
||||
|
||||
if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
|
||||
/* only key on available channels */
|
||||
if ((ob->ipo) || (ob->action)) {
|
||||
ID *id= (ID *)(ob);
|
||||
|
||||
if (ob->ipo) {
|
||||
icu= ob->ipo->curve.first;
|
||||
}
|
||||
else {
|
||||
if (ob->action && actname) {
|
||||
bActionChannel *achan;
|
||||
achan= get_action_channel(ob->action, actname);
|
||||
|
||||
@@ -3586,19 +3590,16 @@ void autokeyframe_ob_cb_func(Object *ob, int tmode)
|
||||
else
|
||||
icu= NULL;
|
||||
}
|
||||
else
|
||||
icu= ob->ipo->curve.first;
|
||||
|
||||
while (icu) {
|
||||
for (; icu; icu= icu->next) {
|
||||
icu->flag &= ~IPO_SELECT;
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
|
||||
else
|
||||
insertkey(id, ID_OB, actname, NULL, icu->adrcode, 0);
|
||||
icu= icu->next;
|
||||
insertkey(id, ID_OB, actname, NULL, icu->adrcode, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
|
||||
ID *id= (ID *)(ob);
|
||||
short doLoc=0, doRot=0, doScale=0;
|
||||
|
||||
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
|
||||
@@ -3629,35 +3630,33 @@ void autokeyframe_ob_cb_func(Object *ob, int tmode)
|
||||
}
|
||||
|
||||
if (doLoc) {
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_LOC_X);
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_LOC_Y);
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_LOC_Z);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_X, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Y, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Z, flag);
|
||||
}
|
||||
if (doRot) {
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_ROT_X);
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_ROT_Y);
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_ROT_Z);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_X, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Y, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Z, flag);
|
||||
}
|
||||
if (doScale) {
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_SIZE_X);
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_SIZE_Y);
|
||||
insertkey_smarter(id, ID_OB, actname, NULL, OB_SIZE_Z);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_X, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z, flag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ID *id= (ID *)(ob);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_X, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Y, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Z, flag);
|
||||
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_X, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Y, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_LOC_Z, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_X, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Y, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Z, flag);
|
||||
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_X, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Y, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_ROT_Z, 0);
|
||||
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_X, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z, 0);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_X, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y, flag);
|
||||
insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z, flag);
|
||||
}
|
||||
|
||||
remake_object_ipos(ob);
|
||||
@@ -3683,8 +3682,15 @@ void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
|
||||
act= ob->action;
|
||||
|
||||
if (autokeyframe_cfra_can_key(ob)) {
|
||||
short flag= 0;
|
||||
|
||||
if (act == NULL)
|
||||
act= ob->action= add_empty_action("Action");
|
||||
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
|
||||
flag |= INSERTKEY_NEEDED;
|
||||
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
|
||||
flag |= INSERTKEY_MATRIX;
|
||||
|
||||
for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
|
||||
if (pchan->bone->flag & BONE_TRANSFORM) {
|
||||
@@ -3695,17 +3701,10 @@ void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
|
||||
if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
|
||||
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) {
|
||||
/* only insert keyframe if needed? */
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
|
||||
insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
|
||||
else
|
||||
insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
achan= get_action_channel(act, pchan->name);
|
||||
if (achan && achan->ipo) {
|
||||
for (icu= achan->ipo->curve.first; icu; icu= icu->next)
|
||||
insertkey(id, ID_PO, pchan->name, NULL, icu->adrcode, flag);
|
||||
}
|
||||
}
|
||||
/* only insert keyframe if needed? */
|
||||
@@ -3735,65 +3734,36 @@ void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
|
||||
}
|
||||
|
||||
if (doLoc) {
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_LOC_X);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, flag);
|
||||
}
|
||||
if (doRot) {
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, flag);
|
||||
}
|
||||
if (doScale) {
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_SIZE_X);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
|
||||
insertkey_smarter(id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
|
||||
}
|
||||
}
|
||||
else if (IS_AUTOKEY_FLAG(AUTOMATKEY)) {
|
||||
int matok=0;
|
||||
|
||||
/* check one to make sure we're not trying to set visual loc keys on
|
||||
bones inside of a chain, which only leads to tears. */
|
||||
matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
|
||||
|
||||
if (matok == 0) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
|
||||
}
|
||||
|
||||
/* check one to make sure we're not trying to set visual rot keys on
|
||||
bones inside of a chain, which only leads to tears. */
|
||||
matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
|
||||
insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
|
||||
|
||||
if (matok == 0) {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, flag);
|
||||
}
|
||||
}
|
||||
/* insert keyframe in any channel that's appropriate */
|
||||
else {
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, flag);
|
||||
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, flag);
|
||||
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, flag);
|
||||
insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user