More armature goodies;
The B-Bones! (where the B can be read as 'block' or 'bezier' or 'b-spline') - set option on/off in edit buttons, armature panel - scaling of B-bones only works in editmode, use ALT+S to make bones fatter or thinner. Also works for constrainted transform - In pose mode, you now have a buttons panel with per-bone settings too Here you can find the "segments" button, which allows bones to interpolate between previous/next bones, including roll. - Buttons to control interpolation ("In" and "Out" are disabled, doesn't work satisfying yet NOTE: this doesn't give deform yet! Main purpose for now is to test if this drawing method serves to animate/pose armatures well. Still need to review proper interpolation methods... maybe bezier is too limited.
This commit is contained in:
@@ -87,6 +87,7 @@ void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone);
|
||||
void armature_rebuild_pose(struct Object *ob, struct bArmature *arm);
|
||||
void where_is_pose (struct Object *ob);
|
||||
|
||||
/* get_objectspace_bone_matrix has to be removed still */
|
||||
void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed);
|
||||
void vec_roll_to_mat3(float *vec, float roll, float mat[][3]);
|
||||
|
||||
@@ -103,7 +104,13 @@ void GB_calc_armature_deform (float *co, struct MDeformVert *dvert);
|
||||
void GB_build_mats (float parmat[][4], float obmat[][4], float premat[][4], float postmat[][4]);
|
||||
void GB_validate_defgroups (struct Mesh *mesh, struct ListBase *defbase);
|
||||
|
||||
/*void make_boneParentMatrix (struct Bone* bone, float mat[][4]);*/
|
||||
/* B-Bone support */
|
||||
typedef struct Mat4 {
|
||||
float mat[4][4];
|
||||
} Mat4;
|
||||
|
||||
Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ void basisNurb(float t, short order, short pnts, float *knots, float *basis, int
|
||||
void makeNurbfaces( struct Nurb *nu, float *data);
|
||||
void makeNurbcurve_forw(struct Nurb *nu, float *data);
|
||||
void makeNurbcurve( struct Nurb *nu, float *data, int dim);
|
||||
void maakbez(float q0, float q1, float q2, float q3, float *p, int it);
|
||||
void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
|
||||
void make_orco_surf( struct Curve *cu);
|
||||
void makebevelcurve( struct Object *ob, struct ListBase *disp);
|
||||
short bevelinside(struct BevList *bl1,struct BevList *bl2);
|
||||
|
@@ -45,6 +45,7 @@
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -242,6 +243,107 @@ Bone *get_named_bone (bArmature *arm, const char *name)
|
||||
return bone;
|
||||
}
|
||||
|
||||
/* ************* B-Bone support ******************* */
|
||||
|
||||
#define MAX_BBONE_SUBDIV 32
|
||||
|
||||
/* returns pointer to static array, filled with desired amount of bone->segments elements */
|
||||
/* this calculation is done within pchan pose_mat space */
|
||||
Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
|
||||
{
|
||||
static Mat4 bbone_array[MAX_BBONE_SUBDIV];
|
||||
bPoseChannel *next, *prev;
|
||||
Bone *bone= pchan->bone;
|
||||
float h1[3], h2[3], length, hlength, roll;
|
||||
float mat3[3][3], imat[4][4];
|
||||
float data[MAX_BBONE_SUBDIV+1][4], *fp;
|
||||
int a;
|
||||
|
||||
length= bone->length;
|
||||
hlength= length*0.390464f; // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles
|
||||
|
||||
/* evaluate next and prev bones */
|
||||
if(bone->flag & BONE_IK_TOPARENT)
|
||||
prev= pchan->parent;
|
||||
else
|
||||
prev= NULL;
|
||||
|
||||
next= pchan->child;
|
||||
|
||||
/* find the handle points, since this is inside bone space, the
|
||||
first point = (0,0,0)
|
||||
last point = (0, length, 0) */
|
||||
|
||||
Mat4Invert(imat, pchan->pose_mat);
|
||||
|
||||
if(prev) {
|
||||
/* transform previous point inside this bone space */
|
||||
VECCOPY(h1, prev->pose_head);
|
||||
Mat4MulVecfl(imat, h1);
|
||||
/* if previous bone is B-bone too, use average handle direction */
|
||||
if(prev->bone->segments>1) h1[1]-= length;
|
||||
Normalise(h1);
|
||||
VecMulf(h1, -hlength);
|
||||
}
|
||||
else {
|
||||
h1[0]= 0.0f; h1[1]= hlength; h1[2]= 0.0f;
|
||||
}
|
||||
if(next) {
|
||||
float difmat[4][4], result[3][3], imat3[3][3];
|
||||
|
||||
/* transform next point inside this bone space */
|
||||
VECCOPY(h2, next->pose_tail);
|
||||
Mat4MulVecfl(imat, h2);
|
||||
/* if next bone is B-bone too, use average handle direction */
|
||||
if(next->bone->segments>1);
|
||||
else h2[1]-= length;
|
||||
|
||||
/* find the next roll to interpolate as well */
|
||||
Mat4MulMat4(difmat, next->pose_mat, imat);
|
||||
Mat3CpyMat4(result, difmat); // the desired rotation at beginning of next bone
|
||||
|
||||
vec_roll_to_mat3(h2, 0.0f, mat3); // the result of vec_roll without roll
|
||||
|
||||
Mat3Inv(imat3, mat3);
|
||||
Mat3MulMat3(mat3, imat3, result); // the matrix transforming vec_roll to desired roll
|
||||
|
||||
roll= atan2(mat3[2][0], mat3[2][2]);
|
||||
|
||||
/* and only now negate handle */
|
||||
Normalise(h2);
|
||||
VecMulf(h2, -hlength);
|
||||
|
||||
}
|
||||
else {
|
||||
h2[0]= 0.0f; h2[1]= -hlength; h2[2]= 0.0f;
|
||||
roll= 0.0;
|
||||
}
|
||||
|
||||
// VecMulf(h1, pchan->bone->ease1);
|
||||
// VecMulf(h2, pchan->bone->ease2);
|
||||
|
||||
/* make curve */
|
||||
if(bone->segments > MAX_BBONE_SUBDIV)
|
||||
bone->segments= MAX_BBONE_SUBDIV;
|
||||
|
||||
forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], bone->segments, 4);
|
||||
forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, bone->segments, 4);
|
||||
forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, bone->segments, 4);
|
||||
|
||||
forward_diff_bezier(0.0, 0.390464f*roll, (1.0f-0.390464f)*roll, roll, data[0]+3, bone->segments, 4);
|
||||
|
||||
/* make transformation matrices for the segments for drawing */
|
||||
|
||||
for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) {
|
||||
VecSubf(h1, fp+4, fp);
|
||||
vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll
|
||||
Mat4CpyMat3(bbone_array[a].mat, mat3);
|
||||
VECCOPY(bbone_array[a].mat[3], fp);
|
||||
}
|
||||
|
||||
return bbone_array;
|
||||
}
|
||||
|
||||
/* ************ Armature Deform ******************* */
|
||||
|
||||
void init_armature_deform(Object *parent, Object *ob)
|
||||
@@ -521,6 +623,13 @@ void where_is_armature_bone(Bone *bone, Bone *prevbone)
|
||||
|
||||
bone->length= VecLenf(bone->head, bone->tail);
|
||||
|
||||
/* this is called on old file reading too... */
|
||||
if(bone->xwidth==0.0) {
|
||||
bone->xwidth= 0.1f;
|
||||
bone->zwidth= 0.1f;
|
||||
bone->segments= 1;
|
||||
}
|
||||
|
||||
if(prevbone) {
|
||||
float offs_bone[4][4]; // yoffs(b-1) + root(b) + bonemat(b)
|
||||
|
||||
@@ -567,17 +676,20 @@ void where_is_armature (bArmature *arm)
|
||||
}
|
||||
}
|
||||
|
||||
static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int depth, int counter)
|
||||
static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int counter)
|
||||
{
|
||||
bPoseChannel *pchan = verify_pose_channel (pose, bone->name); // verify checks and/or adds
|
||||
|
||||
pchan->bone= bone;
|
||||
pchan->parent= parchan;
|
||||
pchan->depth= depth;
|
||||
|
||||
counter++;
|
||||
|
||||
for(bone= bone->childbase.first; bone; bone= bone->next) {
|
||||
counter= rebuild_pose_bone(pose, bone, pchan, depth+1, counter);
|
||||
counter= rebuild_pose_bone(pose, bone, pchan, counter);
|
||||
/* for quick detecting of next bone in chain */
|
||||
if(bone->flag & BONE_IK_TOPARENT)
|
||||
pchan->child= get_pose_channel(pose, bone->name);
|
||||
}
|
||||
|
||||
return counter;
|
||||
@@ -596,9 +708,9 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
|
||||
if(ob->pose==NULL) ob->pose= MEM_callocN(sizeof(bPose), "new pose");
|
||||
pose= ob->pose;
|
||||
|
||||
/* first step, check if all channels are there, also sets depth */
|
||||
/* first step, check if all channels are there */
|
||||
for(bone= arm->bonebase.first; bone; bone= bone->next) {
|
||||
counter= rebuild_pose_bone(pose, bone, NULL, 0, counter);
|
||||
counter= rebuild_pose_bone(pose, bone, NULL, counter);
|
||||
}
|
||||
/* sort channels on dependency order, so we can walk the channel list */
|
||||
|
||||
|
@@ -1055,7 +1055,8 @@ void makeNurbcurve(Nurb *nu, float *data, int dim)
|
||||
MEM_freeN(basisu);
|
||||
}
|
||||
|
||||
void maakbez(float q0, float q1, float q2, float q3, float *p, int it)
|
||||
/* forward differencing method for bezier curve */
|
||||
void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
|
||||
{
|
||||
float rt0,rt1,rt2,rt3,f;
|
||||
int a;
|
||||
@@ -1075,7 +1076,7 @@ void maakbez(float q0, float q1, float q2, float q3, float *p, int it)
|
||||
|
||||
for(a=0; a<=it; a++) {
|
||||
*p= q0;
|
||||
p+= 3;
|
||||
p+= stride;
|
||||
q0+= q1;
|
||||
q1+= q2;
|
||||
q2+= q3;
|
||||
@@ -1612,9 +1613,9 @@ void makeBevelList(Object *ob)
|
||||
v2= bezt->vec[0];
|
||||
|
||||
/* always do all three, to prevent data hanging around */
|
||||
maakbez(v1[0], v1[3], v2[0], v2[3], data, nu->resolu);
|
||||
maakbez(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu);
|
||||
maakbez(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu);
|
||||
forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, nu->resolu, 3);
|
||||
forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu, 3);
|
||||
forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu, 3);
|
||||
|
||||
if((nu->type & CU_2D)==0) {
|
||||
if(cu->flag & CU_3D) {
|
||||
|
@@ -1251,7 +1251,7 @@ static void curve_to_displist(ListBase *nubase, ListBase *dispbase)
|
||||
}
|
||||
|
||||
dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
|
||||
/* len+1 because of 'maakbez' function */
|
||||
/* len+1 because of 'forward_diff_bezier' function */
|
||||
dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
|
||||
BLI_addtail(dispbase, dl);
|
||||
dl->parts= 1;
|
||||
@@ -1283,10 +1283,10 @@ static void curve_to_displist(ListBase *nubase, ListBase *dispbase)
|
||||
else {
|
||||
v1= prevbezt->vec[1];
|
||||
v2= bezt->vec[0];
|
||||
maakbez(v1[0], v1[3], v2[0], v2[3], data, nu->resolu);
|
||||
maakbez(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu);
|
||||
forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, nu->resolu, 3);
|
||||
forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu, 3);
|
||||
if((nu->type & 8)==0)
|
||||
maakbez(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu);
|
||||
forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu, 3);
|
||||
data+= 3*nu->resolu;
|
||||
}
|
||||
|
||||
|
@@ -2265,6 +2265,7 @@ static void direct_link_pose(FileData *fd, bPose *pose) {
|
||||
for (chan = pose->chanbase.first; chan; chan=chan->next) {
|
||||
chan->bone= NULL;
|
||||
chan->parent= newdataadr(fd, chan->parent);
|
||||
chan->child= newdataadr(fd, chan->child);
|
||||
direct_link_constraints(fd, &chan->constraints);
|
||||
}
|
||||
|
||||
|
@@ -64,8 +64,10 @@ typedef struct EditBone
|
||||
for pose element, rather than trying to use the existing transObject
|
||||
system?
|
||||
*/
|
||||
float dist, weight, length;
|
||||
short boneclass;
|
||||
float dist, weight;
|
||||
float xwidth, length, zwidth; /* put them in order! transform uses this as scale */
|
||||
float ease1, ease2;
|
||||
short boneclass, segments;
|
||||
|
||||
|
||||
} EditBone;
|
||||
|
@@ -50,6 +50,7 @@
|
||||
#define TFM_PUSHPULL 12
|
||||
#define TFM_CREASE 13
|
||||
#define TFM_MIRROR 14
|
||||
#define TFM_BONESIZE 15
|
||||
|
||||
/* TRANSFORM CONTEXTS */
|
||||
#define CTX_NONE 0
|
||||
|
@@ -246,6 +246,9 @@ int PushPull(TransInfo *t, short mval[2]);
|
||||
void initCrease(TransInfo *t);
|
||||
int Crease(TransInfo *t, short mval[2]);
|
||||
|
||||
void initBoneSize(TransInfo *t);
|
||||
int BoneSize(TransInfo *t, short mval[2]);
|
||||
|
||||
/*********************** transform_conversions.c ********** */
|
||||
struct ListBase;
|
||||
void count_bone_select(TransInfo *t, struct ListBase *lb, int do_it);
|
||||
|
@@ -51,12 +51,14 @@ typedef struct bPoseChannel {
|
||||
struct bPoseChannel *next, *prev;
|
||||
ListBase constraints;
|
||||
char name[32]; /* Channels need longer names than normal blender objects */
|
||||
|
||||
short flag; /* dynamic, for detecting transform changes */
|
||||
short constflag; /* for quick detecting which constraints affect this channel */
|
||||
int depth; /* dependency sorting help */
|
||||
int pad;
|
||||
|
||||
struct Bone *bone; /* set on read file or rebuild pose */
|
||||
struct bPoseChannel *parent; /* set on read file or rebuild pose */
|
||||
struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */
|
||||
struct ListBase chain; /* only while evaluating pose */
|
||||
|
||||
float loc[3]; /* written in by actions or transform */
|
||||
@@ -69,7 +71,7 @@ typedef struct bPoseChannel {
|
||||
|
||||
float pose_head[3]; /* actually pose_mat[3] */
|
||||
float pose_tail[3]; /* also used for drawing help lines... */
|
||||
int pad;
|
||||
int pad1;
|
||||
} bPoseChannel;
|
||||
|
||||
|
||||
|
@@ -49,7 +49,7 @@ typedef struct Bone {
|
||||
ListBase childbase; /* Children */
|
||||
char name[32]; /* Name of the bone - must be unique within the armature */
|
||||
|
||||
float roll, length; /* */
|
||||
float roll, length; /* roll is input for editmode, length calculated */
|
||||
float head[3];
|
||||
float tail[3]; /* head/tail and roll in Bone Space */
|
||||
float bone_mat[3][3]; /* rotation derived from head/tail/roll */
|
||||
@@ -60,11 +60,13 @@ typedef struct Bone {
|
||||
float arm_tail[3]; /* head/tail and roll in Armature Space (rest pos) */
|
||||
float arm_mat[4][4]; /* matrix: (bonemat(b)+head(b))*arm_mat(b-1), rest pos*/
|
||||
|
||||
float dist, weight; /* dist for non-deformgroup deforms */
|
||||
float dist, weight; /* dist, weight: for non-deformgroup deforms */
|
||||
float xwidth, zwidth; /* width: for block bones */
|
||||
float ease1, ease2; /* length of bezier handles */
|
||||
|
||||
float size[3]; /* patch for upward compat, UNUSED! */
|
||||
short boneclass;
|
||||
short pad1;
|
||||
float size[3]; /* patch for upward compat, UNUSED! */
|
||||
short boneclass;
|
||||
short segments; /* for B-bones */
|
||||
}Bone;
|
||||
|
||||
typedef struct bArmature {
|
||||
@@ -99,6 +101,8 @@ typedef struct bArmature {
|
||||
#define ARM_DELAYDEFORM 0x0040
|
||||
#define ARM_DONT_USE 0x0080
|
||||
#define ARM_NO_ACTION 0x0100
|
||||
#define ARM_B_BONES 0x0200
|
||||
|
||||
|
||||
/* bone->flag */
|
||||
#define BONE_SELECTED 1
|
||||
|
@@ -1764,6 +1764,23 @@ void validate_editbonebutton_cb(void *bonev, void *namev)
|
||||
allqueue(REDRAWALL, 0);
|
||||
}
|
||||
|
||||
/* assumes armature posemode */
|
||||
static void validate_posebonebutton_cb(void *bonev, void *namev)
|
||||
{
|
||||
Bone *bone= bonev;
|
||||
Object *ob= OBACT;
|
||||
char oldname[32], newname[32];
|
||||
|
||||
/* need to be on the stack */
|
||||
BLI_strncpy(newname, bone->name, 32);
|
||||
BLI_strncpy(oldname, (char *)namev, 32);
|
||||
/* restore */
|
||||
BLI_strncpy(bone->name, oldname, 32);
|
||||
|
||||
armature_bone_rename(ob->data, oldname, newname); // editarmature.c
|
||||
allqueue(REDRAWALL, 0);
|
||||
}
|
||||
|
||||
static void armature_rest_pos_func(void *pointer1, void *pointer2)
|
||||
{
|
||||
Object *ob= pointer1;
|
||||
@@ -1775,7 +1792,7 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
int bx=148, by=100;
|
||||
int bx=148, by=120;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "editing_panel_armature_type", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Armature", "Editing", 320, 0, 318, 204)==0) return;
|
||||
@@ -1784,14 +1801,15 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
|
||||
"Rest Pos", bx,by,97,20, &arm->flag, 0, 0, 0, 0,
|
||||
"Disable all animation for this object");
|
||||
uiButSetFunc(but, armature_rest_pos_func, ob, arm);
|
||||
|
||||
|
||||
by-= 23;
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButI(block, TOG|BIT|ARM_DRAWAXESBIT,REDRAWVIEW3D, "Draw Axes", bx,by-46,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
|
||||
uiDefButBitI(block, TOG, ARM_B_BONES, REDRAWVIEW3D, "B-Bones", bx, by-23,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone as boxes, showing subdivision and b-splines");
|
||||
uiDefButI(block, TOG|BIT|ARM_DRAWAXESBIT,REDRAWVIEW3D, "Draw Axes", bx, by-46,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
|
||||
uiDefButI(block, TOG|BIT|ARM_DRAWNAMESBIT,REDRAWVIEW3D, "Draw Names", bx,by-69,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
|
||||
uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", bx,by-92,97,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects");
|
||||
uiDefButI(block, TOG|BIT|ARM_DELAYBIT,REDRAWVIEW3D,
|
||||
"Delay Deform", bx,by-115,97,20, &arm->flag, 0, 0, 0, 0,
|
||||
"Don't deform children when manipulating bones in pose mode");
|
||||
uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", bx, by-92,97,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects");
|
||||
uiDefButI(block, TOG|BIT|ARM_DELAYBIT,REDRAWVIEW3D, "Delay Deform", bx, by-115,97,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
|
||||
|
||||
}
|
||||
|
||||
static void editing_panel_armature_bones(Object *ob, bArmature *arm)
|
||||
@@ -1845,13 +1863,9 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
|
||||
|
||||
/* Dist and weight buttons */
|
||||
uiBlockBeginAlign(block);
|
||||
but=uiDefButS(block, MENU, REDRAWVIEW3D,
|
||||
"Skinnable %x0|" "Unskinnable %x1|" "Head %x2|"
|
||||
"Neck %x3|" "Back %x4|" "Shoulder %x5|" "Arm %x6|"
|
||||
"Hand %x7|" "Finger %x8|" "Thumb %x9|" "Pelvis %x10|"
|
||||
"Leg %x11|" "Foot %x12|" "Toe %x13|" "Tentacle %x14",
|
||||
bx-10,by-19,117,18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0,
|
||||
"Classification of armature element");
|
||||
uiDefButS(block, NUM, REDRAWVIEW3D, "Segm: ",
|
||||
bx-10,by-19,117,18, &curBone->segments, 1.0, 32.0, 0.0, 0.0,
|
||||
"Subdivisions for B-bones");
|
||||
|
||||
/* Dist and weight buttons */
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D, "Dist:", bx+110, by-19,
|
||||
@@ -1872,6 +1886,67 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
|
||||
|
||||
}
|
||||
|
||||
static void editing_panel_pose_bones(Object *ob, bArmature *arm)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
bPoseChannel *pchan;
|
||||
Bone *curBone;
|
||||
int bx=148, by=180;
|
||||
int index;
|
||||
|
||||
/* Draw the bone name block */
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "editing_panel_pose_bones", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Armature Bones", "Editing", 640, 0, 318, 204)==0) return;
|
||||
|
||||
/* this is a variable height panel, newpanel doesnt force new size on existing panels */
|
||||
/* so first we make it default height */
|
||||
uiNewPanelHeight(block, 204);
|
||||
|
||||
uiDefBut(block, LABEL, 0, "Selected Bones", bx,by,158,18, 0, 0, 0, 0, 0, "Only show in Armature Editmode/Posemode");
|
||||
by-=20;
|
||||
for (pchan=ob->pose->chanbase.first, index=0; pchan; pchan=pchan->next, index++){
|
||||
curBone= pchan->bone;
|
||||
if (curBone->flag & (BONE_SELECTED)) {
|
||||
|
||||
/* Hide in posemode flag */
|
||||
uiDefButI(block, TOG|BIT|BONE_HIDDENBIT, REDRAWVIEW3D, "Hide", bx-55,by,45,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode");
|
||||
|
||||
/* Bone naming button */
|
||||
uiBlockBeginAlign(block);
|
||||
but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx-10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name");
|
||||
uiButSetFunc(but, validate_posebonebutton_cb, curBone, NULL);
|
||||
|
||||
/* Dist and weight buttons */
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D, "Dist:", bx+107, by,
|
||||
105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0,
|
||||
"Bone deformation distance");
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D, "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, REDRAWVIEW3D, "Segm: ",
|
||||
bx-10,by-19,117,19, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones");
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D, "In:",
|
||||
bx+107, by-19,105, 19, &curBone->ease1, 0.0, 2.0, 10.0, 0.0, "First length of Bezier handle");
|
||||
uiDefButF(block, NUM,REDRAWVIEW3D, "Out:",
|
||||
bx+220, by-19, 110, 19, &curBone->ease2, 0.0, 2.0, 10.0, 0.0, "Second length of Bezier handle");
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
by-=42;
|
||||
}
|
||||
}
|
||||
|
||||
if(by<0) {
|
||||
uiNewPanelHeight(block, 204 - by);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* *************************** MESH ******************************** */
|
||||
|
||||
@@ -2806,6 +2881,9 @@ void editing_panels()
|
||||
if(G.obedit) {
|
||||
editing_panel_armature_bones(ob, arm);
|
||||
}
|
||||
else if(G.obpose==ob) {
|
||||
editing_panel_pose_bones(ob, arm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
uiClearButLock();
|
||||
|
@@ -82,8 +82,96 @@
|
||||
#include "blendef.h"
|
||||
#include "nla.h"
|
||||
|
||||
/* half the cube, in Y */
|
||||
static float cube[8][3] = {
|
||||
{-1.0, 0.0, -1.0},
|
||||
{-1.0, 0.0, 1.0},
|
||||
{-1.0, 1.0, 1.0},
|
||||
{-1.0, 1.0, -1.0},
|
||||
{ 1.0, 0.0, -1.0},
|
||||
{ 1.0, 0.0, 1.0},
|
||||
{ 1.0, 1.0, 1.0},
|
||||
{ 1.0, 1.0, -1.0},
|
||||
};
|
||||
|
||||
|
||||
/* *************** Armature drawing, helper calls for parts ******************* */
|
||||
|
||||
static void drawsolidcube_size(float xsize, float ysize, float zsize)
|
||||
{
|
||||
float n[3];
|
||||
|
||||
glScalef(xsize, ysize, zsize);
|
||||
|
||||
n[0]=0; n[1]=0; n[2]=0;
|
||||
glBegin(GL_QUADS);
|
||||
n[0]= -1.0;
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
||||
n[0]=0;
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
n[1]= -1.0;
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
|
||||
n[1]=0;
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
n[0]= 1.0;
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
|
||||
n[0]=0;
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
n[1]= 1.0;
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
||||
n[1]=0;
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
n[2]= 1.0;
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
|
||||
n[2]=0;
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
n[2]= -1.0;
|
||||
glNormal3fv(n);
|
||||
glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
static void drawcube_size(float xsize, float ysize, float zsize)
|
||||
{
|
||||
|
||||
glScalef(xsize, ysize, zsize);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
||||
glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
|
||||
glVertex3fv(cube[7]); glVertex3fv(cube[4]);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(cube[1]); glVertex3fv(cube[5]);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv(cube[3]); glVertex3fv(cube[7]);
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
/* *************** Armature drawing ******************* */
|
||||
|
||||
static void draw_bonevert(void)
|
||||
{
|
||||
@@ -241,8 +329,160 @@ static void draw_bone_solid_octahedral(void)
|
||||
else glCallList(displist);
|
||||
}
|
||||
|
||||
/* *************** Armature drawing, bones ******************* */
|
||||
|
||||
static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, char *name)
|
||||
|
||||
static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id, float length)
|
||||
{
|
||||
/* Draw root point if we have no IK parent */
|
||||
if (!(boneflag & BONE_IK_TOPARENT)){
|
||||
if (id != -1)
|
||||
glLoadName (id | BONESEL_ROOT);
|
||||
|
||||
if(dt<=OB_WIRE) {
|
||||
if(armflag & ARM_EDITMODE) {
|
||||
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
|
||||
else BIF_ThemeColor(TH_VERTEX);
|
||||
}
|
||||
}
|
||||
else
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
|
||||
if(dt>OB_WIRE) draw_bonevert_solid();
|
||||
else draw_bonevert();
|
||||
}
|
||||
|
||||
/* Draw tip point */
|
||||
if (id != -1)
|
||||
glLoadName (id | BONESEL_TIP);
|
||||
|
||||
if(dt<=OB_WIRE) {
|
||||
if(armflag & ARM_EDITMODE) {
|
||||
if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
|
||||
else BIF_ThemeColor(TH_VERTEX);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
}
|
||||
|
||||
glTranslatef(0.0, length, 0.0);
|
||||
if(dt>OB_WIRE) draw_bonevert_solid();
|
||||
else draw_bonevert();
|
||||
glTranslatef(0.0, -length, 0.0);
|
||||
|
||||
if(length > 0.05f) length-= 0.05f; // make vertices visible
|
||||
}
|
||||
|
||||
static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float length, float zwidth)
|
||||
{
|
||||
int segments= 0;
|
||||
|
||||
if(pchan) segments= pchan->bone->segments;
|
||||
|
||||
if(segments>1 && pchan) {
|
||||
float dlen= length/(float)segments;
|
||||
Mat4 *bbone= b_bone_spline_setup(pchan);
|
||||
int a;
|
||||
|
||||
for(a=0; a<segments; a++, bbone++) {
|
||||
glPushMatrix();
|
||||
glMultMatrixf(bbone->mat);
|
||||
if(dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
|
||||
else drawcube_size(xwidth, dlen, zwidth);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
else {
|
||||
glPushMatrix();
|
||||
if(dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
|
||||
else drawcube_size(xwidth, length, zwidth);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
|
||||
{
|
||||
float xwidth, length, zwidth;
|
||||
|
||||
if(pchan) {
|
||||
xwidth= pchan->bone->xwidth;
|
||||
length= pchan->bone->length;
|
||||
zwidth= pchan->bone->zwidth;
|
||||
}
|
||||
else {
|
||||
xwidth= ebone->xwidth;
|
||||
length= ebone->length;
|
||||
zwidth= ebone->zwidth;
|
||||
}
|
||||
|
||||
/* draw points only if... */
|
||||
if(armflag & ARM_EDITMODE) {
|
||||
draw_bone_points(dt, armflag, boneflag, id, length);
|
||||
}
|
||||
|
||||
/* colors for modes */
|
||||
if (armflag & ARM_POSEMODE) {
|
||||
if(dt==OB_WIRE) {
|
||||
if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
|
||||
else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
|
||||
else BIF_ThemeColor(TH_WIRE);
|
||||
}
|
||||
else
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
}
|
||||
else if (armflag & ARM_EDITMODE) {
|
||||
if(dt==OB_WIRE) {
|
||||
if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
|
||||
else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
|
||||
else BIF_ThemeColor(TH_WIRE);
|
||||
}
|
||||
else
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
}
|
||||
|
||||
if (id != -1) {
|
||||
glLoadName ((GLuint) id|BONESEL_BONE);
|
||||
}
|
||||
|
||||
/* set up solid drawing */
|
||||
if(dt > OB_WIRE) {
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_LIGHTING);
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
|
||||
draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
|
||||
|
||||
/* disable solid drawing */
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
else { // wire
|
||||
if (armflag & ARM_POSEMODE){
|
||||
if(constflag) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
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
|
||||
|
||||
draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
/* restore colors */
|
||||
if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
|
||||
else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
|
||||
else BIF_ThemeColor(TH_WIRE);
|
||||
}
|
||||
}
|
||||
|
||||
draw_b_bone_boxes(OB_WIRE, pchan, xwidth, length, zwidth);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id)
|
||||
{
|
||||
|
||||
/* Draw a 3d octahedral bone, we use normalized space based on length,
|
||||
@@ -266,52 +506,13 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
}
|
||||
|
||||
/* Draw root point if we have no IK parent */
|
||||
if (!(boneflag & BONE_IK_TOPARENT)){
|
||||
if (id != -1)
|
||||
glLoadName (id | BONESEL_ROOT);
|
||||
if (armflag & ARM_EDITMODE) {
|
||||
if(dt<=OB_WIRE) {
|
||||
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
|
||||
else BIF_ThemeColor(TH_VERTEX);
|
||||
}
|
||||
else
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
}
|
||||
if(dt>OB_WIRE) draw_bonevert_solid();
|
||||
else draw_bonevert();
|
||||
}
|
||||
|
||||
/* Draw tip point */
|
||||
if (id != -1)
|
||||
glLoadName (id | BONESEL_TIP);
|
||||
if (armflag & ARM_EDITMODE) {
|
||||
if(dt<=OB_WIRE) {
|
||||
if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
|
||||
else BIF_ThemeColor(TH_VERTEX);
|
||||
}
|
||||
else
|
||||
BIF_ThemeColor(TH_BONE_SOLID);
|
||||
}
|
||||
|
||||
glTranslatef(0.0, 1.0, 0.0);
|
||||
if(dt>OB_WIRE) draw_bonevert_solid();
|
||||
else draw_bonevert();
|
||||
|
||||
/* Draw additional axes */
|
||||
if (armflag & ARM_DRAWAXES){
|
||||
drawaxes(0.25f);
|
||||
}
|
||||
draw_bone_points(dt, armflag, boneflag, id, 1.0);
|
||||
|
||||
/* now draw the bone itself */
|
||||
glTranslatef(0.0, -1.0, 0.0);
|
||||
|
||||
if (id != -1) {
|
||||
if (armflag & ARM_POSEMODE)
|
||||
glLoadName((GLuint) id);
|
||||
else{
|
||||
glLoadName ((GLuint) id|BONESEL_BONE);
|
||||
}
|
||||
glLoadName ((GLuint) id|BONESEL_BONE);
|
||||
}
|
||||
|
||||
/* wire? */
|
||||
@@ -327,8 +528,8 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 100);
|
||||
else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 100);
|
||||
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
|
||||
|
||||
draw_bone_solid_octahedral();
|
||||
@@ -384,16 +585,19 @@ static void draw_pose_channels(Object *ob, int dt)
|
||||
glPushMatrix();
|
||||
glMultMatrixf(pchan->pose_mat);
|
||||
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(bone->length, bone->length, bone->length);
|
||||
|
||||
/* catch exception for bone with hidden parent */
|
||||
flag= bone->flag;
|
||||
if(bone->parent && (bone->parent->flag & BONE_HIDDEN))
|
||||
flag &= ~BONE_IK_TOPARENT;
|
||||
|
||||
draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->name);
|
||||
|
||||
if(arm->flag & ARM_B_BONES)
|
||||
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
|
||||
else {
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(bone->length, bone->length, bone->length);
|
||||
|
||||
draw_bone(OB_SOLID, arm->flag, flag, 0, index);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
if (index!= -1) index++;
|
||||
@@ -433,9 +637,6 @@ static void draw_pose_channels(Object *ob, int dt)
|
||||
glPushMatrix();
|
||||
glMultMatrixf(pchan->pose_mat);
|
||||
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(bone->length, bone->length, bone->length);
|
||||
|
||||
/* catch exception for bone with hidden parent */
|
||||
flag= bone->flag;
|
||||
if(bone->parent && (bone->parent->flag & BONE_HIDDEN))
|
||||
@@ -446,7 +647,14 @@ static void draw_pose_channels(Object *ob, int dt)
|
||||
if(pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
|
||||
constflag |= PCHAN_HAS_ACTION;
|
||||
|
||||
draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->name);
|
||||
if(arm->flag & ARM_B_BONES)
|
||||
draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
|
||||
else {
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(bone->length, bone->length, bone->length);
|
||||
|
||||
draw_bone(OB_WIRE, arm->flag, flag, constflag, index);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
@@ -458,8 +666,8 @@ static void draw_pose_channels(Object *ob, int dt)
|
||||
bglPolygonOffset(0.0);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
/* finally names */
|
||||
if(arm->flag & ARM_DRAWNAMES) {
|
||||
/* finally names and axes */
|
||||
if(arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
|
||||
// patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
|
||||
if((G.f & G_PICKSEL) == 0) {
|
||||
float vec[3];
|
||||
@@ -475,10 +683,20 @@ static void draw_pose_channels(Object *ob, int dt)
|
||||
}
|
||||
else if(dt > OB_WIRE) BIF_ThemeColor(TH_TEXT);
|
||||
|
||||
VecMidf(vec, pchan->pose_head, pchan->pose_tail);
|
||||
glRasterPos3fv(vec);
|
||||
BMF_DrawString(G.font, " ");
|
||||
BMF_DrawString(G.font, pchan->name);
|
||||
if (arm->flag & ARM_DRAWNAMES){
|
||||
VecMidf(vec, pchan->pose_head, pchan->pose_tail);
|
||||
glRasterPos3fv(vec);
|
||||
BMF_DrawString(G.font, " ");
|
||||
BMF_DrawString(G.font, pchan->name);
|
||||
}
|
||||
/* Draw additional axes */
|
||||
if( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ){
|
||||
glPushMatrix();
|
||||
glMultMatrixf(pchan->pose_mat);
|
||||
glTranslatef(0.0f, pchan->bone->length, 0.0f);
|
||||
drawaxes(0.25f);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
||||
@@ -497,9 +715,7 @@ static void set_matrix_editbone(EditBone *eBone)
|
||||
|
||||
glTranslatef (offset[0],offset[1],offset[2]);
|
||||
|
||||
delta[0]= eBone->tail[0]-eBone->head[0];
|
||||
delta[1]= eBone->tail[1]-eBone->head[1];
|
||||
delta[2]= eBone->tail[2]-eBone->head[2];
|
||||
VecSubf(delta, eBone->tail, eBone->head);
|
||||
|
||||
eBone->length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]);
|
||||
|
||||
@@ -508,8 +724,95 @@ static void set_matrix_editbone(EditBone *eBone)
|
||||
|
||||
glMultMatrixf (bmat);
|
||||
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(eBone->length, eBone->length, eBone->length);
|
||||
}
|
||||
|
||||
static void draw_ebones(Object *ob, int dt)
|
||||
{
|
||||
EditBone *eBone;
|
||||
bArmature *arm= ob->data;
|
||||
unsigned int index;
|
||||
|
||||
/* if solid we draw it first */
|
||||
if(dt>OB_WIRE) {
|
||||
for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
|
||||
glPushMatrix();
|
||||
set_matrix_editbone(eBone);
|
||||
|
||||
if(arm->flag & ARM_B_BONES)
|
||||
draw_b_bone(OB_SOLID, arm->flag, eBone->flag, 0, index, NULL, eBone);
|
||||
else {
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(eBone->length, eBone->length, eBone->length);
|
||||
draw_bone(OB_SOLID, arm->flag, eBone->flag, 0, index);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
/* if wire over solid, set offset */
|
||||
index= -1;
|
||||
if (dt>OB_WIRE) bglPolygonOffset(1.0);
|
||||
else if(arm->flag & ARM_EDITMODE) index= 0; // do selection codes
|
||||
|
||||
for (eBone=G.edbo.first; eBone; eBone=eBone->next){
|
||||
|
||||
glPushMatrix();
|
||||
set_matrix_editbone(eBone);
|
||||
|
||||
if(arm->flag & ARM_B_BONES)
|
||||
draw_b_bone(OB_WIRE, arm->flag, eBone->flag, 0, index, NULL, eBone);
|
||||
else {
|
||||
/* scale the matrix to unit bone space */
|
||||
glScalef(eBone->length, eBone->length, eBone->length);
|
||||
draw_bone(OB_WIRE, arm->flag, eBone->flag, index, -1);
|
||||
}
|
||||
if(arm->flag & ARM_DRAWAXES)
|
||||
drawaxes(0.25f);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
/* offset to parent */
|
||||
if (eBone->parent) {
|
||||
BIF_ThemeColor(TH_WIRE);
|
||||
glLoadName (-1);
|
||||
setlinestyle(3);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(eBone->parent->tail);
|
||||
glVertex3fv(eBone->head);
|
||||
glEnd();
|
||||
|
||||
setlinestyle(0);
|
||||
}
|
||||
if(index!=-1) index++;
|
||||
}
|
||||
|
||||
/* restore */
|
||||
if (dt>OB_WIRE) bglPolygonOffset(0.0);
|
||||
|
||||
/* finally names */
|
||||
if(arm->flag & ARM_DRAWNAMES) {
|
||||
// patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
|
||||
if((G.f & G_PICKSEL) == 0) {
|
||||
float vec[3];
|
||||
|
||||
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
|
||||
|
||||
for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
|
||||
|
||||
if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
|
||||
else BIF_ThemeColor(TH_TEXT);
|
||||
|
||||
VecMidf(vec, eBone->head, eBone->tail);
|
||||
glRasterPos3fv(vec);
|
||||
BMF_DrawString(G.font, " ");
|
||||
BMF_DrawString(G.font, eBone->name);
|
||||
}
|
||||
|
||||
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -522,76 +825,10 @@ void draw_armature(Object *ob, int dt)
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
||||
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // only for lighting...
|
||||
|
||||
/* If we're in editmode, draw the Global edit data */
|
||||
/* editmode? */
|
||||
if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
|
||||
EditBone *eBone;
|
||||
unsigned int index;
|
||||
|
||||
if(ob==G.obedit) arm->flag |= ARM_EDITMODE;
|
||||
|
||||
/* if solid we draw it first */
|
||||
if(dt>OB_WIRE && (arm->flag & ARM_EDITMODE)) {
|
||||
for (eBone=G.edbo.first; eBone; eBone=eBone->next){
|
||||
glPushMatrix();
|
||||
set_matrix_editbone(eBone);
|
||||
|
||||
draw_bone(OB_SOLID, arm->flag, eBone->flag, 0, -1, eBone->name);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
/* if wire over solid, set offset */
|
||||
if (dt>OB_WIRE) bglPolygonOffset(1.0);
|
||||
|
||||
for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
|
||||
|
||||
glPushMatrix();
|
||||
set_matrix_editbone(eBone);
|
||||
|
||||
draw_bone(OB_WIRE, arm->flag, eBone->flag, 0, index, eBone->name);
|
||||
glPopMatrix();
|
||||
|
||||
/* offset to parent */
|
||||
if (eBone->parent) {
|
||||
BIF_ThemeColor(TH_WIRE);
|
||||
glLoadName (-1);
|
||||
setlinestyle(3);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(eBone->parent->tail);
|
||||
glVertex3fv(eBone->head);
|
||||
glEnd();
|
||||
|
||||
setlinestyle(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore */
|
||||
if (dt>OB_WIRE) bglPolygonOffset(0.0);
|
||||
|
||||
/* finally names */
|
||||
if(arm->flag & ARM_DRAWNAMES) {
|
||||
// patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
|
||||
if((G.f & G_PICKSEL) == 0) {
|
||||
float vec[3];
|
||||
|
||||
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
|
||||
|
||||
for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
|
||||
|
||||
if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
|
||||
else BIF_ThemeColor(TH_TEXT);
|
||||
|
||||
VecMidf(vec, eBone->head, eBone->tail);
|
||||
glRasterPos3fv(vec);
|
||||
BMF_DrawString(G.font, " ");
|
||||
BMF_DrawString(G.font, eBone->name);
|
||||
}
|
||||
|
||||
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
draw_ebones(ob, dt);
|
||||
arm->flag &= ~ARM_EDITMODE;
|
||||
}
|
||||
else{
|
||||
|
@@ -1255,8 +1255,8 @@ static void draw_ipocurves(int sel)
|
||||
|
||||
correct_bezpart(v1, v2, v3, v4);
|
||||
|
||||
maakbez(v1[0], v2[0], v3[0], v4[0], data, resol);
|
||||
maakbez(v1[1], v2[1], v3[1], v4[1], data+1, resol);
|
||||
forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, 3);
|
||||
forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data+1, resol, 3);
|
||||
|
||||
fp= data;
|
||||
while(resol--) {
|
||||
|
@@ -3737,6 +3737,7 @@ void draw_object(Base *base)
|
||||
drawlattice(ob);
|
||||
break;
|
||||
case OB_ARMATURE:
|
||||
if(dt>OB_WIRE) set_gl_material(0); // we use defmaterial
|
||||
draw_armature(ob, dt);
|
||||
break;
|
||||
default:
|
||||
|
@@ -156,7 +156,10 @@ static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
|
||||
eBone->length= curBone->length;
|
||||
eBone->dist= curBone->dist;
|
||||
eBone->weight= curBone->weight;
|
||||
eBone->xwidth= curBone->xwidth;
|
||||
eBone->zwidth= curBone->zwidth;
|
||||
eBone->boneclass = curBone->boneclass;
|
||||
eBone->segments = curBone->segments;
|
||||
|
||||
BLI_addtail (list, eBone);
|
||||
|
||||
@@ -245,6 +248,10 @@ static void editbones_to_armature (ListBase *list, Object *ob)
|
||||
newBone->dist = eBone->dist;
|
||||
newBone->boneclass = eBone->boneclass;
|
||||
|
||||
newBone->xwidth = eBone->xwidth;
|
||||
newBone->zwidth = eBone->zwidth;
|
||||
newBone->segments= eBone->segments;
|
||||
|
||||
}
|
||||
|
||||
/* Fix parenting in a separate pass to ensure ebone->bone connections
|
||||
@@ -1156,11 +1163,15 @@ static void add_bone_input (Object *ob)
|
||||
|
||||
bone->flag |= (BONE_SELECTED);
|
||||
deselectall_armature();
|
||||
|
||||
bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
|
||||
|
||||
bone->weight= 1.0F;
|
||||
bone->dist= 1.0F;
|
||||
bone->xwidth= 0.1;
|
||||
bone->zwidth= 0.1;
|
||||
bone->boneclass = BONE_SKINNABLE;
|
||||
bone->segments= 1;
|
||||
|
||||
/* Project cursor center to screenspace. */
|
||||
getmouseco_areawin(mval);
|
||||
@@ -1503,11 +1514,15 @@ void extrude_armature(void)
|
||||
VECCOPY (newbone->head, curbone->tail);
|
||||
VECCOPY (newbone->tail, newbone->head);
|
||||
newbone->parent = curbone;
|
||||
|
||||
newbone->flag = BONE_TIPSEL;
|
||||
newbone->weight= curbone->weight;
|
||||
newbone->dist= curbone->dist;
|
||||
newbone->xwidth= curbone->xwidth;
|
||||
newbone->zwidth= curbone->zwidth;
|
||||
newbone->segments= curbone->segments;
|
||||
newbone->boneclass= curbone->boneclass;
|
||||
|
||||
|
||||
/* See if there are any ik children of the parent */
|
||||
for (partest = G.edbo.first; partest; partest=partest->next){
|
||||
if ((partest->parent == curbone) && (partest->flag & BONE_IK_TOPARENT))
|
||||
|
@@ -1250,15 +1250,19 @@ void borderselect(void)
|
||||
if (val==LEFTMOUSE){
|
||||
if (index != -1){
|
||||
bone = get_indexed_bone(G.obpose, index &~(BONESEL_TIP|BONESEL_ROOT));
|
||||
bone->flag |= BONE_SELECTED;
|
||||
select_actionchannel_by_name(G.obpose->action, bone->name, 1);
|
||||
if(bone) {
|
||||
bone->flag |= BONE_SELECTED;
|
||||
select_actionchannel_by_name(G.obpose->action, bone->name, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (index != -1){
|
||||
bone = get_indexed_bone(G.obpose, index &~(BONESEL_TIP|BONESEL_ROOT));
|
||||
bone->flag &= ~(BONE_ACTIVE|BONE_SELECTED);
|
||||
select_actionchannel_by_name(G.obpose->action, bone->name, 0);
|
||||
if(bone) {
|
||||
bone->flag &= ~(BONE_ACTIVE|BONE_SELECTED);
|
||||
select_actionchannel_by_name(G.obpose->action, bone->name, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -606,7 +606,7 @@ void BIF_InitTheme(void)
|
||||
btheme->tv3d.facedot_size= 4;
|
||||
|
||||
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
|
||||
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 100); // alpha 100 is not meant editable, used for wire+action draw
|
||||
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw
|
||||
|
||||
|
||||
/* space buttons */
|
||||
@@ -716,7 +716,7 @@ void BIF_InitTheme(void)
|
||||
|
||||
char *BIF_ThemeColorsPup(int spacetype)
|
||||
{
|
||||
char *cp= MEM_callocN(21*32, "theme pup");
|
||||
char *cp= MEM_callocN(32*32, "theme pup");
|
||||
char str[32];
|
||||
|
||||
if(spacetype==0) {
|
||||
@@ -766,8 +766,8 @@ char *BIF_ThemeColorsPup(int spacetype)
|
||||
sprintf(str, "Face Selected (transp) %%x%d|", TH_FACE_SELECT); strcat(cp, str);
|
||||
sprintf(str, "Face Dot Selected %%x%d|", TH_FACE_DOT); strcat(cp, str);
|
||||
sprintf(str, "Face Dot Size %%x%d|", TH_FACEDOT_SIZE); strcat(cp, str);
|
||||
sprintf(str, "Normal %%x%d", TH_NORMAL); strcat(cp, str);
|
||||
sprintf(str, "Bone Solid %%x%d", TH_BONE_SOLID); strcat(cp, str);
|
||||
sprintf(str, "Normal %%x%d|", TH_NORMAL); strcat(cp, str);
|
||||
sprintf(str, "Bone Solid %%x%d|", TH_BONE_SOLID); strcat(cp, str);
|
||||
sprintf(str, "Bone Pose %%x%d", TH_BONE_POSE); strcat(cp, str);
|
||||
}
|
||||
else if(spacetype==SPACE_IPO) {
|
||||
|
@@ -1549,8 +1549,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
doredraw= 1;
|
||||
}
|
||||
else if(G.obedit) {
|
||||
|
||||
if(G.qual==LR_ALTKEY) {
|
||||
initTransform(TFM_SHRINKFATTEN, CTX_NONE);
|
||||
if(G.obedit->type==OB_ARMATURE)
|
||||
initTransform(TFM_BONESIZE, CTX_NONE);
|
||||
else
|
||||
initTransform(TFM_SHRINKFATTEN, CTX_NONE);
|
||||
Transform();
|
||||
}
|
||||
else if(G.qual==LR_CTRLKEY) {
|
||||
|
@@ -497,6 +497,9 @@ void initTransform(int mode, int context) {
|
||||
case TFM_CREASE:
|
||||
initCrease(&Trans);
|
||||
break;
|
||||
case TFM_BONESIZE:
|
||||
initBoneSize(&Trans);
|
||||
break;
|
||||
}
|
||||
|
||||
initConstraint(&Trans);
|
||||
@@ -2207,6 +2210,121 @@ void Mirror(short mode)
|
||||
scrarea_queue_headredraw(curarea);
|
||||
}
|
||||
|
||||
/* ******************** EditBone scaling *************** */
|
||||
|
||||
static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
|
||||
{
|
||||
float tmat[3][3], smat[3][3], oldy;
|
||||
float sizemat[3][3];
|
||||
|
||||
Mat3MulMat3(smat, mat, td->mtx);
|
||||
Mat3MulMat3(tmat, td->smtx, smat);
|
||||
|
||||
if (t->con.applySize) {
|
||||
t->con.applySize(t, td, tmat);
|
||||
}
|
||||
|
||||
/* we've tucked the scale in loc */
|
||||
oldy= td->iloc[1];
|
||||
SizeToMat3(td->iloc, sizemat);
|
||||
Mat3MulMat3(tmat, smat, sizemat);
|
||||
Mat3ToSize(tmat, td->loc);
|
||||
td->loc[1]= oldy;
|
||||
}
|
||||
|
||||
|
||||
int BoneSize(TransInfo *t, short mval[2])
|
||||
{
|
||||
TransData *td = t->data;
|
||||
float size[3], mat[3][3];
|
||||
float ratio;
|
||||
int i;
|
||||
char str[50];
|
||||
|
||||
/* for manipulator, center handle, the scaling can't be done relative to center */
|
||||
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
|
||||
ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f;
|
||||
}
|
||||
else {
|
||||
|
||||
if(t->flag & T_SHIFT_MOD) {
|
||||
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
|
||||
float dx= (float)(t->center2d[0] - t->shiftmval[0]);
|
||||
float dy= (float)(t->center2d[1] - t->shiftmval[1]);
|
||||
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
|
||||
|
||||
dx= (float)(t->center2d[0] - mval[0]);
|
||||
dy= (float)(t->center2d[1] - mval[1]);
|
||||
ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
|
||||
|
||||
}
|
||||
else {
|
||||
float dx= (float)(t->center2d[0] - mval[0]);
|
||||
float dy= (float)(t->center2d[1] - mval[1]);
|
||||
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
|
||||
}
|
||||
|
||||
/* flip scale, but not for manipulator center handle */
|
||||
if ((t->center2d[0] - mval[0]) * (t->center2d[0] - t->imval[0]) +
|
||||
(t->center2d[1] - mval[1]) * (t->center2d[1] - t->imval[1]) < 0)
|
||||
ratio *= -1.0f;
|
||||
}
|
||||
|
||||
size[0] = size[1] = size[2] = ratio;
|
||||
|
||||
snapGrid(t, size);
|
||||
|
||||
if (hasNumInput(&t->num)) {
|
||||
applyNumInput(&t->num, size);
|
||||
constraintNumInput(t, size);
|
||||
}
|
||||
|
||||
SizeToMat3(size, mat);
|
||||
|
||||
if (t->con.applySize) {
|
||||
t->con.applySize(t, NULL, mat);
|
||||
}
|
||||
|
||||
Mat3CpyMat3(t->mat, mat); // used in manipulator
|
||||
|
||||
headerResize(t, size, str);
|
||||
|
||||
for(i = 0 ; i < t->total; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
ElementBoneSize(t, td, mat);
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
headerprint(str);
|
||||
|
||||
force_draw(0);
|
||||
|
||||
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t->center);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void initBoneSize(TransInfo *t)
|
||||
{
|
||||
t->idx_max = 0;
|
||||
t->num.idx_max = 0;
|
||||
t->snap[0] = 0.0f;
|
||||
t->snap[1] = 0.1f;
|
||||
t->snap[2] = t->snap[1] * 0.1f;
|
||||
t->transform = BoneSize;
|
||||
t->fac = (float)sqrt( (float)(
|
||||
(t->center2d[1] - t->imval[1])*(t->center2d[1] - t->imval[1])
|
||||
+
|
||||
(t->center2d[0] - t->imval[0])*(t->center2d[0] - t->imval[0])
|
||||
) );
|
||||
|
||||
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
|
||||
}
|
||||
|
||||
/* ************************************ */
|
||||
|
||||
void BIF_TransformSetUndo(char *str)
|
||||
{
|
||||
|
@@ -496,15 +496,19 @@ static void createTransArmatureVerts(TransInfo *t)
|
||||
{
|
||||
EditBone *ebo;
|
||||
TransData *td;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3];
|
||||
|
||||
t->total = 0;
|
||||
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
|
||||
if (ebo->flag & BONE_TIPSEL){
|
||||
t->total++;
|
||||
for (ebo=G.edbo.first;ebo;ebo=ebo->next) {
|
||||
if (t->mode==TFM_BONESIZE) {
|
||||
if (ebo->flag & BONE_SELECTED)
|
||||
t->total++;
|
||||
}
|
||||
if (ebo->flag & BONE_ROOTSEL){
|
||||
t->total++;
|
||||
else {
|
||||
if (ebo->flag & BONE_TIPSEL)
|
||||
t->total++;
|
||||
if (ebo->flag & BONE_ROOTSEL)
|
||||
t->total++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,37 +520,62 @@ static void createTransArmatureVerts(TransInfo *t)
|
||||
td = t->data = MEM_mallocN(t->total*sizeof(TransData), "TransEditBone");
|
||||
|
||||
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
|
||||
if (ebo->flag & BONE_TIPSEL){
|
||||
VECCOPY (td->iloc, ebo->tail);
|
||||
VECCOPY (td->center, td->iloc);
|
||||
td->loc= ebo->tail;
|
||||
td->flag= TD_SELECTED;
|
||||
if (t->mode==TFM_BONESIZE) {
|
||||
if (ebo->flag & BONE_SELECTED) {
|
||||
// abusive storage of scale in the loc pointer :)
|
||||
td->loc= &ebo->xwidth;
|
||||
VECCOPY (td->iloc, td->loc);
|
||||
VECCOPY (td->center, ebo->head);
|
||||
td->flag= TD_SELECTED;
|
||||
|
||||
/* use local bone matrix */
|
||||
VecSubf(delta, ebo->tail, ebo->head);
|
||||
vec_roll_to_mat3(delta, ebo->roll, bonemat);
|
||||
Mat3MulMat3(td->mtx, mtx, bonemat);
|
||||
Mat3Inv(td->smtx, td->mtx);
|
||||
|
||||
Mat3CpyMat3(td->axismtx, td->mtx);
|
||||
Mat3Ortho(td->axismtx);
|
||||
|
||||
Mat3CpyMat3(td->smtx, smtx);
|
||||
Mat3CpyMat3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->tdi = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td++;
|
||||
td->ext = NULL;
|
||||
td->tdi = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
if (ebo->flag & BONE_ROOTSEL){
|
||||
VECCOPY (td->iloc, ebo->head);
|
||||
VECCOPY (td->center, td->iloc);
|
||||
td->loc= ebo->head;
|
||||
td->flag= TD_SELECTED;
|
||||
else {
|
||||
if (ebo->flag & BONE_TIPSEL){
|
||||
VECCOPY (td->iloc, ebo->tail);
|
||||
VECCOPY (td->center, td->iloc);
|
||||
td->loc= ebo->tail;
|
||||
td->flag= TD_SELECTED;
|
||||
|
||||
Mat3CpyMat3(td->smtx, smtx);
|
||||
Mat3CpyMat3(td->mtx, mtx);
|
||||
Mat3CpyMat3(td->smtx, smtx);
|
||||
Mat3CpyMat3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->tdi = NULL;
|
||||
td->val = NULL;
|
||||
td->ext = NULL;
|
||||
td->tdi = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td++;
|
||||
td++;
|
||||
}
|
||||
if (ebo->flag & BONE_ROOTSEL){
|
||||
VECCOPY (td->iloc, ebo->head);
|
||||
VECCOPY (td->center, td->iloc);
|
||||
td->loc= ebo->head;
|
||||
td->flag= TD_SELECTED;
|
||||
|
||||
Mat3CpyMat3(td->smtx, smtx);
|
||||
Mat3CpyMat3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->tdi = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1600,6 +1629,12 @@ void createTransData(TransInfo *t)
|
||||
}
|
||||
}
|
||||
t->flag |= T_EDIT;
|
||||
|
||||
/* exception... hackish, we want bonescale to use bone orientation matrix (ton) */
|
||||
if(t->mode==TFM_BONESIZE) {
|
||||
t->flag &= ~T_EDIT;
|
||||
t->flag |= T_POSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
createTransObject(t);
|
||||
|
@@ -232,7 +232,7 @@ static void init_userdef_file(void)
|
||||
/* check for alpha==0 is safe, then color was never set */
|
||||
if(btheme->tv3d.bone_solid[3]==0) {
|
||||
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
|
||||
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 100);
|
||||
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user