Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/action.c104
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/object.c8
-rw-r--r--source/blender/include/butspace.h1
-rw-r--r--source/blender/makesdna/DNA_action_types.h5
-rw-r--r--source/blender/makesdna/DNA_armature_types.h2
-rw-r--r--source/blender/makesdna/DNA_nla_types.h8
-rw-r--r--source/blender/src/buttons_editing.c55
-rw-r--r--source/blender/src/drawarmature.c116
-rw-r--r--source/blender/src/drawnla.c73
-rw-r--r--source/blender/src/editnla.c40
-rw-r--r--source/blender/src/editobject.c12
-rwxr-xr-xsource/blender/src/transform_conversions.c1
14 files changed, 332 insertions, 97 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index d062b6c5c71..03f5a9903ef 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -416,16 +416,15 @@ void calc_action_range(const bAction *act, float *start, float *end)
const bConstraintChannel *conchan;
const IpoCurve *icu;
float min=999999999.0f, max=-999999999.0;
- int i;
int foundvert=0;
if(act) {
for (chan=act->chanbase.first; chan; chan=chan->next) {
if(chan->ipo) {
for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
- for (i=0; i<icu->totvert; i++) {
- min = MIN2 (min, icu->bezt[i].vec[1][0]);
- max = MAX2 (max, icu->bezt[i].vec[1][0]);
+ if(icu->totvert) {
+ min= MIN2 (min, icu->bezt[0].vec[1][0]);
+ max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]);
foundvert=1;
}
}
@@ -433,9 +432,9 @@ void calc_action_range(const bAction *act, float *start, float *end)
for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
if(conchan->ipo) {
for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
- for (i=0; i<icu->totvert; i++){
- min = MIN2 (min, icu->bezt[i].vec[1][0]);
- max = MAX2 (max, icu->bezt[i].vec[1][0]);
+ if(icu->totvert) {
+ min= MIN2 (min, icu->bezt[0].vec[1][0]);
+ max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]);
foundvert=1;
}
}
@@ -482,7 +481,7 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
/* Copy the data from the action into the pose */
for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
achan= get_action_channel(act, pchan->name);
- pchan->flag= 0;
+ pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
if(achan) {
ipo = achan->ipo;
if (ipo) {
@@ -499,21 +498,21 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
/* for do_all_pose_actions, clears the pose */
static void rest_pose(bPose *pose)
{
- bPoseChannel *chan;
+ bPoseChannel *pchan;
int i;
if (!pose)
return;
- for (chan=pose->chanbase.first; chan; chan=chan->next){
+ for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
for (i=0; i<3; i++){
- chan->loc[i]=0.0;
- chan->quat[i+1]=0.0;
- chan->size[i]=1.0;
+ pchan->loc[i]=0.0;
+ pchan->quat[i+1]=0.0;
+ pchan->size[i]=1.0;
}
- chan->quat[0]=1.0;
+ pchan->quat[0]=1.0;
- chan->flag =0;
+ pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
}
}
@@ -716,6 +715,65 @@ static float nla_time(float cfra, float unit)
return cfra;
}
+static float stridechannel_frame(bAction *act, int stride_axis, char *name, float pdist)
+{
+ bActionChannel *achan= get_action_channel(act, name);
+
+ if(achan && achan->ipo) {
+ IpoCurve *icu= NULL;
+ float minx=0.0f, maxx=0.0f, miny=0.0f, maxy=0.0f;
+ int foundvert= 0;
+
+ if(stride_axis==0) stride_axis= AC_LOC_X;
+ else if(stride_axis==1) stride_axis= AC_LOC_Y;
+ else stride_axis= AC_LOC_Z;
+
+ /* calculate the min/max */
+ for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+ if(icu->adrcode==stride_axis) {
+ if(icu->totvert>1) {
+ foundvert= 1;
+ minx= icu->bezt[0].vec[1][0];
+ maxx= icu->bezt[icu->totvert-1].vec[1][0];
+
+ miny= icu->bezt[0].vec[1][1];
+ maxy= icu->bezt[icu->totvert-1].vec[1][1];
+ }
+ break;
+ }
+ }
+
+ if(foundvert && miny!=maxy) {
+ float stridelen= fabs(maxy-miny), striptime;
+ float actiondist, step= 0.5, error, threshold=0.00001f*stridelen;
+ int max= 20;
+
+ /* amount path moves object */
+ pdist = (float)fmod (pdist, stridelen);
+
+ /* wanted; the (0-1) factor that cancels out this distance, do simple newton-raphson */
+ striptime= step;
+ do {
+ actiondist= eval_icu(icu, minx + striptime*(maxx-minx)) - miny;
+
+ error= pdist - fabs(actiondist);
+
+ step*=0.5f;
+ if(error > 0.0)
+ striptime += step;
+ else
+ striptime -= step;
+
+ max--;
+ }
+ while( fabs(error) > threshold && max>0);
+
+ return striptime;
+ }
+ }
+ return 0.0f;
+}
+
/* ************** do the action ************ */
static void do_nla(Object *ob, int blocktype)
@@ -772,12 +830,16 @@ static void do_nla(Object *ob, int blocktype)
}
pdist = ctime*cu->path->totdist;
- if (strip->stridelen)
- striptime = pdist / strip->stridelen;
- else
- striptime = 0;
-
- striptime = (float)fmod (striptime, 1.0);
+ if(strip->stridechannel[0])
+ striptime= stridechannel_frame(strip->act, strip->stride_axis, strip->stridechannel, pdist);
+ else {
+ if (strip->stridelen) {
+ striptime = pdist / strip->stridelen;
+ striptime = (float)fmod (striptime, 1.0);
+ }
+ else
+ striptime = 0;
+ }
frametime = (striptime * actlength) + strip->actstart;
frametime= bsystem_time(ob, 0, frametime, 0.0);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index f8dbdddc5d1..217f7a33f12 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1278,7 +1278,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
if(data->weight != 0.0)
IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
- if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0))
+ if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0) && (data->flag & CONSTRAINT_IK_AUTO)==0)
IK_SolverAddGoalOrientation(solver, iktarget, goalrot, data->orientweight);
}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 1b04a43ae28..2ab13fe328a 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -265,6 +265,8 @@ static VFontData *vfont_get_data(VFont *vfont)
struct TmpFont *tmpfnt = NULL;
PackedFile *tpf;
+ if(vfont==NULL) return NULL;
+
// Try finding the font from font list
tmpfnt = G.ttfdata.first;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index cc7ca11f81c..fe3ab612525 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -855,11 +855,11 @@ Object *copy_object(Object *ob)
obn->soft= copy_softbody(ob->soft);
/* NT copy fluid sim setting memory */
- if(ob->fluidsimSettings) ob->fluidsimSettings = MEM_dupallocN(ob->fluidsimSettings);
- else ob->fluidsimSettings = NULL;
+ if(obn->fluidsimSettings) obn->fluidsimSettings = MEM_dupallocN(ob->fluidsimSettings);
+ else obn->fluidsimSettings = NULL;
- ob->derivedDeform = NULL;
- ob->derivedFinal = NULL;
+ obn->derivedDeform = NULL;
+ obn->derivedFinal = NULL;
return obn;
}
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index a725ff18138..88a3175ba1b 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -433,6 +433,7 @@ enum {
#define B_ARMBUTS 2400
#define B_ARM_RECALCDATA 2301
+#define B_ARM_STRIDE 2302
/* *********************** */
#define B_CAMBUTS 2500
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index fce02e2e394..2f60045e9ea 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -138,7 +138,8 @@ enum {
POSE_HAS_IK = 0x0100,
POSE_CHAIN = 0x0200,
POSE_DONE = 0x0400,
- POSE_KEY = 0x1000
+ POSE_KEY = 0x1000,
+ POSE_STRIDE = 0x2000
};
/* PoseChannel constflag (constraint detection) */
@@ -147,6 +148,8 @@ enum {
/* only used for drawing Posemode, not stored in channel */
#define PCHAN_HAS_ACTION 4
#define PCHAN_HAS_TARGET 8
+ /* only for drawing Posemode too */
+#define PCHAN_HAS_STRIDE 16
/* PoseChannel->ikflag */
#define BONE_IK_NO_XDOF 1
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 47ecccc1f1e..b31a803718e 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -77,7 +77,7 @@ typedef struct bArmature {
int flag;
int drawtype;
int deformflag;
- int res3;
+ short ghostep, pad;
}bArmature;
/* armature->flag */
diff --git a/source/blender/makesdna/DNA_nla_types.h b/source/blender/makesdna/DNA_nla_types.h
index 4d5483f71d7..bf3d7820dae 100644
--- a/source/blender/makesdna/DNA_nla_types.h
+++ b/source/blender/makesdna/DNA_nla_types.h
@@ -38,9 +38,8 @@ struct Ipo;
typedef struct bActionStrip {
struct bActionStrip *next, *prev;
- short flag;
- short mode;
- int reserved1;
+ short flag, mode;
+ short stride_axis, pad; /* axis 0=x, 1=y, 2=z */
struct Ipo *ipo; /* Blending ipo */
struct bAction *act; /* The action referenced by this strip */
@@ -51,6 +50,8 @@ typedef struct bActionStrip {
float repeat; /* The number of times to repeat the action range */
float blendin, blendout;
+
+ char stridechannel[32]; /* Instead of stridelen, it uses an action channel */
} bActionStrip;
#define ACTSTRIPMODE_BLEND 0
@@ -64,5 +65,6 @@ typedef struct bActionStrip {
#define ACTSTRIP_ACTIVE 0x10
#define ACTSTRIP_LOCK_ACTION 0x20
+
#endif
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index fe93adf5dcb..a6babe376bb 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -62,6 +62,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_radio_types.h"
@@ -2523,14 +2524,52 @@ static void editing_panel_lattice_type(Object *ob, Lattice *lt)
void do_armbuts(unsigned short event)
{
+ Object *ob= OBACT;
+
switch(event) {
case B_ARM_RECALCDATA:
- DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 1);
allqueue(REDRAWBUTSEDIT, 0);
+ break;
+ case B_ARM_STRIDE:
+ if(ob && ob->pose) {
+ bPoseChannel *pchan;
+ bActionStrip *strip;
+
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next)
+ if(pchan->flag & POSE_STRIDE)
+ break;
+
+ /* we put the stride bone name in the strips, for lookup of action channel */
+ for (strip=ob->nlastrips.first; strip; strip=strip->next){
+ if(strip->flag & ACTSTRIP_USESTRIDE) {
+ if(pchan) BLI_strncpy(strip->stridechannel, pchan->name, 32);
+ else strip->stridechannel[0]= 0;
+ }
+ }
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
}
}
+static void validate_stridebutton_cb(void *pchanv, void *poin)
+{
+ Object *ob= OBACT;
+ bPoseChannel *pchan;
+
+ if(ob && ob->pose) {
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next){
+ if(pchan!=pchanv)
+ pchan->flag &= ~POSE_STRIDE;
+ }
+ }
+}
+
static int editbone_to_parnr (EditBone *bone)
{
EditBone *ebone;
@@ -2681,8 +2720,9 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 100,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines");
uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 100,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume");
- uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
- uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 160,80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
+ uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 80,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
+ uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,80,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
+ uiDefButS(block, NUM, REDRAWVIEW3D, "Ghost: ", 210,80,100,20, &arm->ghostep, 0.0f, 30.0f, 0, 0, "Draw Ghosts around current frame, for current Action");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Deform Options", 10,60,150,20, 0, 0, 0, 0, 0, "");
@@ -2801,7 +2841,6 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", bx+107, by, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance");
uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", bx+220, by, 110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
-
/* Segment, ease in/out buttons */
uiBlockBeginAlign(block);
uiDefButS(block, NUM, B_ARM_RECALCDATA, "Segm: ", bx-10,by-19,117,19, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones");
@@ -2864,15 +2903,15 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
by -= (zerodof)? 82: (zerolimit)? 122: 162;
- uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stretch:", bx-10, by, 113, 19, &pchan->ikstretch, 0.0, 1.0, 1.0, 0.0, "Allow scaling of the bone for IK");
- uiBlockEndAlign(block);
by -= 20;
}
else {
- uiDefBut(block, LABEL, 0, "(DoF options only for IK chains)", bx-10,by-60, 300, 20, 0, 0, 0, 0, 0, "");
-
+ but= uiDefButBitS(block, TOG, POSE_STRIDE, B_ARM_STRIDE, "Stride Root", bx-10, by-60, 113, 19, &pchan->flag, 0.0, 0.0, 0, 0, "Set this PoseChannel to define the Stride distance");
+ uiButSetFunc(but, validate_stridebutton_cb, pchan, NULL);
+
+ uiDefBut(block, LABEL, 0, "(DoF only for IK chains)", bx+110,by-60, 190, 19, 0, 0, 0, 0, 0, "");
by -= 82;
}
diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c
index 471eb1e0612..a4dffaea7dd 100644
--- a/source/blender/src/drawarmature.c
+++ b/source/blender/src/drawarmature.c
@@ -43,6 +43,7 @@
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_ID.h"
+#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -829,7 +830,8 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
if(armflag & ARM_POSEMODE) {
/* inner part in background color or constraint */
if(constflag) {
- if(constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
+ if(constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200);
+ else if(constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
else if(constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
else if(constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
else BIF_ThemeColor(TH_BONE_POSE); // PCHAN_HAS_ACTION
@@ -967,10 +969,10 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
else { // wire
if (armflag & ARM_POSEMODE){
if(constflag) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
+ if(constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
+ else if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
else if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
else BIF_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION
@@ -1035,10 +1037,10 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
}
else if (armflag & ARM_POSEMODE){
if(constflag) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
+ if(constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
+ else if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
else if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
else BIF_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION
@@ -1130,7 +1132,6 @@ static void draw_dof_ellipse(float ax, float az)
int i, j, n=16;
float x, z, px, pz;
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glDepthMask(0);
@@ -1310,7 +1311,6 @@ static void draw_pose_channels(Base *base, int dt)
/* and draw blended distances */
if(arm->flag & ARM_POSEMODE) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//glShadeModel(GL_SMOOTH);
@@ -1425,6 +1425,8 @@ static void draw_pose_channels(Base *base, int dt)
constflag= pchan->constflag;
if(pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
constflag |= PCHAN_HAS_ACTION;
+ if(pchan->flag & POSE_STRIDE)
+ constflag |= PCHAN_HAS_STRIDE;
if(arm->drawtype==ARM_ENVELOPE) {
if(dt<OB_SOLID)
@@ -1492,6 +1494,7 @@ static void draw_pose_channels(Base *base, int dt)
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
}
}
+
}
/* in editmode, we don't store the bone matrix... */
@@ -1532,7 +1535,6 @@ static void draw_ebones(Object *ob, int dt)
Mat4Invert(imat, smat);
/* and draw blended distances */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//glShadeModel(GL_SMOOTH);
@@ -1712,6 +1714,93 @@ static void draw_pose_paths(Object *ob)
glPopMatrix();
}
+/* object is supposed to be armature in posemode */
+static void draw_ghost_poses(Base *base)
+{
+ Object *ob= base->object;
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ bActionStrip *strip;
+ float cur, start, end, stepsize, range, colfac, actframe;
+ int cfrao, maptime;
+
+ /* pre conditions, get an action with sufficient frames */
+ if(ob->action==NULL)
+ return;
+
+ calc_action_range(ob->action, &start, &end);
+ if(start==end)
+ return;
+
+ stepsize= 1.0f;
+ range= (float)(arm->ghostep);
+
+ /* we only map time for armature when an active strip exists */
+ for (strip=ob->nlastrips.first; strip; strip=strip->next)
+ if(strip->flag & ACTSTRIP_ACTIVE)
+ break;
+
+ maptime= (strip!=NULL);
+
+ /* store values */
+ ob->flag &= ~OB_POSEMODE;
+ cfrao= CFRA;
+ if(maptime) actframe= get_action_frame(ob, (float)CFRA);
+ else actframe= CFRA;
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+
+ glEnable(GL_BLEND);
+ if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from lowest blend to darkest */
+ for(cur= 0.5f; cur<range; cur+=stepsize) {
+
+ colfac= cur/range;
+ BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
+
+ /* only within action range */
+ if(actframe+cur >= start && actframe+cur <= end) {
+
+ if(maptime) CFRA= (int)get_action_frame_inv(ob, actframe+cur);
+ else CFRA= (int)(actframe+cur);
+
+ if(CFRA!=cfrao) {
+ do_all_pose_actions(ob);
+ where_is_pose(ob);
+ draw_pose_channels(base, OB_WIRE);
+ }
+ }
+ /* only within action range */
+ if(actframe-cur >= start && actframe-cur <= end) {
+
+ if(maptime) CFRA= (int)get_action_frame_inv(ob, actframe-cur);
+ else CFRA= (int)(actframe-cur);
+
+ if(CFRA!=cfrao) {
+ do_all_pose_actions(ob);
+ where_is_pose(ob);
+ draw_pose_channels(base, OB_WIRE);
+ }
+ }
+ }
+ glDisable(GL_BLEND);
+ if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+
+ free_pose_channels(posen);
+ MEM_freeN(posen);
+
+ CFRA= cfrao;
+ ob->pose= poseo;
+ armature_rebuild_pose(ob, ob->data);
+
+ ob->flag |= OB_POSEMODE;
+}
+
/* called from drawobject.c */
void draw_armature(Base *base, int dt)
{
@@ -1744,16 +1833,25 @@ void draw_armature(Base *base, int dt)
if(ob->flag & OB_POSEMODE) arm->flag |= ARM_POSEMODE;
}
else if(ob->flag & OB_POSEMODE) {
+ /* only set once */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ if(arm->ghostep) {
+ draw_ghost_poses(base);
+ }
+
if(ob==OBACT)
arm->flag |= ARM_POSEMODE;
else if(G.f & G_WEIGHTPAINT)
arm->flag |= ARM_POSEMODE;
draw_pose_paths(ob);
- }
+ }
+
draw_pose_channels(base, dt);
arm->flag &= ~ARM_POSEMODE;
+ BIF_ThemeColor(TH_WIRE); /* restore, for extra draw stuff */
}
}
/* restore */
diff --git a/source/blender/src/drawnla.c b/source/blender/src/drawnla.c
index b558750647b..007238224de 100644
--- a/source/blender/src/drawnla.c
+++ b/source/blender/src/drawnla.c
@@ -58,6 +58,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_action.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BSE_drawnla.h"
@@ -148,6 +149,15 @@ static void draw_nla_channels(void)
glRasterPos2f(x+32, y-4);
BMF_DrawString(G.font, ob->action->id.name+2);
+ /* icon for active action (no strip mapping) */
+ for (strip = ob->nlastrips.first; strip; strip=strip->next)
+ if(strip->flag & ACTSTRIP_ACTIVE) break;
+ if(strip==NULL) {
+ glEnable(GL_BLEND);
+ BIF_draw_icon_blended(x, y-8, ICON_DOT, TH_BACK, 0);
+ glDisable(GL_BLEND);
+ }
+
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
}
@@ -417,24 +427,8 @@ void do_nlabuts(unsigned short event)
allqueue(REDRAWNLA, 0);
break;
case B_NLA_PANEL:
- if (strip->end<strip->start)
- strip->end=strip->start;
-
-
- if (strip->blendin>(strip->end-strip->start))
- strip->blendin = strip->end-strip->start;
-
- if (strip->blendout>(strip->end-strip->start))
- strip->blendout = strip->end-strip->start;
-
- if (strip->blendin > (strip->end-strip->start-strip->blendout))
- strip->blendin = (strip->end-strip->start-strip->blendout);
-
- if (strip->blendout > (strip->end-strip->start-strip->blendin))
- strip->blendout = (strip->end-strip->start-strip->blendin);
-
- update_for_newframe_muted();
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
allqueue (REDRAWNLA, 0);
allqueue (REDRAWVIEW3D, 0);
break;
@@ -463,39 +457,46 @@ static void nla_panel_properties(short cntrl) // NLA_HANDLER_PROPERTIES
/* first labels, for simpler align code :) */
uiDefBut(block, LABEL, 0, "Timeline Range:", 10,180,300,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Action Range:", 10,140,300,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Blending:", 10,100,300,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Options:", 10,60,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Blending:", 10,120,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Options:", 10,80,300,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Stride Support:", 10,40,300,19, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_REDR, "Strip Start:", 10,160,150,19, &strip->start, -1000.0, strip->end-1, 100, 0, "First frame in the timeline");
- uiDefButF(block, NUM, B_REDR, "Strip End:", 160,160,150,19, &strip->end, strip->start+1, MAXFRAMEF, 100, 0, "Last frame in the timeline");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Strip Start:", 10,160,150,19, &strip->start, -1000.0, strip->end-1, 100, 0, "First frame in the timeline");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Strip End:", 160,160,150,19, &strip->end, strip->start+1, MAXFRAMEF, 100, 0, "Last frame in the timeline");
- uiBlockBeginAlign(block);
- uiDefIconButBitS(block, ICONTOG, ACTSTRIP_LOCK_ACTION, B_NLA_LOCK, ICON_UNLOCKED, 10,120,20,19, &(strip->flag), 0, 0, 0, 0, "Toggles Action end/start to be automatic mapped to strip duration");
+ uiDefIconButBitS(block, ICONTOG, ACTSTRIP_LOCK_ACTION, B_NLA_LOCK, ICON_UNLOCKED, 10,140,20,19, &(strip->flag), 0, 0, 0, 0, "Toggles Action end/start to be automatic mapped to strip duration");
if(strip->flag & ACTSTRIP_LOCK_ACTION) {
char str[40];
sprintf(str, "Action Start: %.2f", strip->actstart);
- uiDefBut(block, LABEL, B_NOP, str, 30,120,140,19, NULL, 0.0, 0.0, 0, 0, "First frame of the action to map to the playrange");
+ uiDefBut(block, LABEL, B_NOP, str, 30,140,140,19, NULL, 0.0, 0.0, 0, 0, "First frame of the action to map to the playrange");
sprintf(str, "Action End: %.2f", strip->actend);
- uiDefBut(block, LABEL, B_NOP, str, 170,120,140,19, NULL, 0.0, 0.0, 0, 0, "Last frame of the action to map to the playrange");
+ uiDefBut(block, LABEL, B_NOP, str, 170,140,140,19, NULL, 0.0, 0.0, 0, 0, "Last frame of the action to map to the playrange");
}
else {
- uiDefButF(block, NUM, B_REDR, "Action Start:", 30,120,140,19, &strip->actstart, -1000.0, strip->actend-1, 100, 0, "First frame of the action to map to the playrange");
- uiDefButF(block, NUM, B_REDR, "Action End:", 170,120,140,19, &strip->actend, strip->actstart+1, MAXFRAMEF, 100, 0, "Last frame of the action to map to the playrange");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Action Start:", 30,140,140,19, &strip->actstart, -1000.0, strip->actend-1, 100, 0, "First frame of the action to map to the playrange");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Action End:", 170,140,140,19, &strip->actend, strip->actstart+1, MAXFRAMEF, 100, 0, "Last frame of the action to map to the playrange");
}
+
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_REDR, "Blendin:", 10,80,150,19, &strip->blendin, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-in");
- uiDefButF(block, NUM, B_REDR, "Blendout:", 160,80,150,19, &strip->blendout, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-out");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Blendin:", 10,100,150,19, &strip->blendin, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-in");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Blendout:", 160,100,150,19, &strip->blendout, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-out");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_REDR, "Repeat:", 10,40,150,19, &strip->repeat, 0.0001, 1000.0f, 100, 0, "Number of times the action should repeat");
- uiDefButF(block, NUM, B_REDR, "Stride:", 160,40,150,19, &strip->stridelen, 0.0001, 1000.0, 100, 0, "Distance covered by one complete cycle of the action specified in the Action Range");
-
+ uiDefButF(block, NUM, B_NLA_PANEL, "Repeat:", 10,60,150,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat");
+ uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_NLA_PANEL, "Hold", 160,60,75,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip");
+ uiDefButS(block, TOG, B_NLA_PANEL, "Add", 230,60,75,19, &strip->mode, 0, 0, 0, 0, "Toggles additive blending mode");
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, ACTSTRIP_USESTRIDE, B_REDR, "Use Path", 10,0,100,19, &strip->flag, 0, 0, 0, 0, "Plays action based on path position & stride");
- uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_REDR, "Hold", 110,0,100,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip");
- uiDefButS(block, TOG, B_REDR, "Add", 210,0,100,19, &strip->mode, 0, 0, 0, 0, "Toggles additive blending mode");
+ uiDefButBitS(block, TOG, ACTSTRIP_USESTRIDE, B_NLA_PANEL, "Use Path", 10,20,100,19, &strip->flag, 0, 0, 0, 0, "Plays action based on path position & stride");
+ uiDefButF(block, NUM, B_NLA_PANEL, "Stride:", 110,20,200,19, &strip->stridelen, 0.0001, 1000.0, 100, 0, "Distance covered by one complete cycle of the action specified in the Action Range");
+
+ uiDefButS(block, ROW, B_NLA_PANEL, "X", 10, 0, 33, 19, &strip->stride_axis, 1, 0, 0, 0, "Dominant axis for Stride Bone");
+ uiDefButS(block, ROW, B_NLA_PANEL, "Y", 43, 0, 33, 19, &strip->stride_axis, 1, 1, 0, 0, "Dominant axis for Stride Bone");
+ uiDefButS(block, ROW, B_NLA_PANEL, "Z", 76, 0, 34, 19, &strip->stride_axis, 1, 2, 0, 0, "Dominant axis for Stride Bone");
+
+ uiDefBut(block, TEX, B_NLA_PANEL, "Stride Bone:", 110, 0, 200, 19, strip->stridechannel, 1, 31, 0, 0, "Name of Bone used for stride");
+
}
static void nla_blockhandlers(ScrArea *sa)
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 00857d3c841..645ac37c1e1 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -456,6 +456,20 @@ static void set_active_strip(Object *ob, bActionStrip *act)
}
}
+static void find_stridechannel(Object *ob, bActionStrip *strip)
+{
+ if(ob && ob->pose) {
+ bPoseChannel *pchan;
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
+ if(pchan->flag & POSE_STRIDE)
+ break;
+ if(pchan)
+ BLI_strncpy(strip->stridechannel, pchan->name, 32);
+ else
+ strip->stridechannel[0]= 0;
+ }
+}
+
static void convert_nla(short mval[2])
{
bActionStrip *strip, *nstrip;
@@ -522,8 +536,10 @@ static void convert_nla(short mval[2])
nstrip->start = nstrip->actstart;
nstrip->end = nstrip->actend;
nstrip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION;
+
+ find_stridechannel(base->object, nstrip);
set_active_strip(base->object, nstrip);
-
+
nstrip->repeat = 1.0;
BLI_addtail(&base->object->nlastrips, nstrip);
@@ -576,6 +592,8 @@ static void add_nla_block(short event)
strip->end= strip->start+100;
strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION;
+
+ find_stridechannel(nla_base->object, strip);
set_active_strip(nla_base->object, strip);
strip->repeat = 1.0;
@@ -684,7 +702,7 @@ static void mouse_nlachannels(short mval[2])
Base *base;
Object *ob=NULL;
float x,y;
- int click, obclick=0;
+ int click, obclick=0, actclick=0;
int wsize;
wsize = (count_nla_levels ()*(NLACHANNELHEIGHT+NLACHANNELSKIP));
@@ -709,7 +727,10 @@ static void mouse_nlachannels(short mval[2])
/* See if this is an action */
if (ob->action){
- if (click==0) break;
+ if (click==0) {
+ actclick= 1;
+ break;
+ }
click--;
}
@@ -740,17 +761,18 @@ static void mouse_nlachannels(short mval[2])
if(base!=BASACT) set_active_base(base);
- /* set action */
- if(strip)
+ if(actclick) /* de-activate all strips */
+ set_active_strip(ob, NULL);
+ else if(strip) /* set action */
set_active_strip(ob, strip);
/* override option for NLA */
- if(obclick && mval[0]<25) {
+ if(obclick && mval[0]<25)
ob->nlaflag ^= OB_NLA_OVERRIDE;
- ob->ctime= -1234567.0f; // eveil!
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
- }
+ ob->ctime= -1234567.0f; // eveil!
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
+
allqueue(REDRAWIPO, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 8a23fe7059d..5f240aac776 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -3092,18 +3092,20 @@ void make_duplilist_real()
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
*/
- if(ob->mat==0) ob->totcol= 0;
+ if(ob->mat==NULL) ob->totcol= 0;
basen= MEM_dupallocN(base);
basen->flag &= ~OB_FROMDUPLI;
BLI_addhead(&G.scene->base, basen); /* addhead: othwise eternal loop */
- ob->ipo= 0; /* make sure apply works */
- ob->parent= ob->track= 0;
- ob->disp.first= ob->disp.last= 0;
+ ob->ipo= NULL; /* make sure apply works */
+ ob->parent= ob->track= NULL;
+ ob->disp.first= ob->disp.last= NULL;
ob->transflag &= ~OB_DUPLI;
basen->object= copy_object(ob);
+ basen->object->flag &= ~OB_FROMDUPLI;
apply_obmat(basen->object);
+
ob= ob->id.next;
}
@@ -3115,6 +3117,8 @@ void make_duplilist_real()
base= base->next;
}
+ DAG_scene_sort(G.scene);
+
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWOOPS, 0);
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 68d5352e4e5..9cb84b03949 100755
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -472,6 +472,7 @@ static void apply_targetless_ik(Object *ob)
Mat4MulMat4(tmat, offs_bone, parchan->parent->bone->arm_mat);
else
Mat4MulMat4(tmat, offs_bone, parchan->parent->pose_mat);
+
Mat4Invert(imat, tmat);
}
else {