diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_action.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_key.h | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_scene.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 24 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 61 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 207 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sca.c | 1 |
9 files changed, 272 insertions, 43 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index b5e34444d13..716eac81b55 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -44,6 +44,7 @@ struct bActionChannel; struct bPose; struct bPoseChannel; struct Object; +struct ID; /* Kernel prototypes */ #ifdef __cplusplus @@ -157,6 +158,10 @@ void rest_pose(struct bPose *pose); float get_action_frame(struct Object *ob, float cframe); /* map strip time to global time (frame nr) */ float get_action_frame_inv(struct Object *ob, float cframe); +/* builds a list of NlaIpoChannel with ipo values to write in datablock */ +void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, char *name, float ctime); +/* write values returned by extract_ipochannels_from_action, returns the number of value written */ +int execute_ipochannels(ListBase *lb); #ifdef __cplusplus }; diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index a6871aa837f..faf8692b89a 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -40,6 +40,11 @@ struct Object; struct Lattice; struct Mesh; +/* Kernel prototypes */ +#ifdef __cplusplus +extern "C" { +#endif + void free_key(struct Key *sc); struct Key *add_key(struct ID *id); struct Key *copy_key(struct Key *key); @@ -57,6 +62,12 @@ int do_ob_key(struct Object *ob); struct Key *ob_get_key(struct Object *ob); struct KeyBlock *ob_get_keyblock(struct Object *ob); struct KeyBlock *key_get_keyblock(struct Key *key, int index); +// needed for the GE +void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode); + +#ifdef __cplusplus +}; +#endif #endif diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index c50f5498de9..2bd528ab8c8 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -53,7 +53,7 @@ struct RenderData; } /* note; doesn't work when scene is empty */ -#define SETLOOPER(s, b) sce= s, b= sce->base.first; b; b= (b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) +#define SETLOOPER(s, b) sce= s, b= (Base*)sce->base.first; b; b= (Base*)(b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) void free_avicodecdata(struct AviCodecData *acd); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 5fb3d6f869a..05f2e69fce1 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -290,6 +290,12 @@ void copy_pose(bPose **dst, bPose *src, int copycon) return; } + if (*dst==src) { + printf("copy_pose source and target are the same\n"); + *dst=NULL; + return; + } + outPose= MEM_callocN(sizeof(bPose), "pose"); duplicatelist(&outPose->chanbase, &src->chanbase); @@ -740,6 +746,11 @@ void extract_pose_from_pose(bPose *pose, const bPose *src) const bPoseChannel *schan; bPoseChannel *pchan= pose->chanbase.first; + if (pose==src) { + printf("extract_pose_from_pose source and target are the same\n"); + return; + } + for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) { copy_pose_channel_data(pchan, schan); } @@ -817,6 +828,12 @@ void copy_pose_result(bPose *to, bPose *from) return; } + if (to==from) { + printf("copy_pose_result source and target are the same\n"); + return; + } + + for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) { pchanto= get_pose_channel(to, pchanfrom->name); if(pchanto) { @@ -843,7 +860,7 @@ typedef struct NlaIpoChannel { int type; } NlaIpoChannel; -static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime) +void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime) { bActionChannel *achan= get_action_channel(act, name); IpoCurve *icu; @@ -936,15 +953,18 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int } } -static void execute_ipochannels(ListBase *lb) +int execute_ipochannels(ListBase *lb) { NlaIpoChannel *nic; + int count = 0; for(nic= lb->first; nic; nic= nic->next) { if(nic->poin) { write_ipo_poin(nic->poin, nic->type, nic->val); + count++; } } + return count; } /* nla timing */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index eca10e5b079..fb7d59c137a 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1709,13 +1709,13 @@ static void execute_posetree(Object *ob, PoseTree *tree) if (tree->totchannel == 0) return; - + iktree= MEM_mallocN(sizeof(void*)*tree->totchannel, "ik tree"); for(a=0; a<tree->totchannel; a++) { pchan= tree->pchan[a]; bone= pchan->bone; - + /* set DoF flag */ flag= 0; if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP)) @@ -1724,32 +1724,32 @@ static void execute_posetree(Object *ob, PoseTree *tree) flag |= IK_YDOF; if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP)) flag |= IK_ZDOF; - + if(tree->stretch && (pchan->ikstretch > 0.0)) { flag |= IK_TRANS_YDOF; hasstretch = 1; } - + seg= iktree[a]= IK_CreateSegment(flag); - + /* find parent */ if(a == 0) parent= NULL; else parent= iktree[tree->parent[a]]; - + IK_SetParent(seg, parent); - + /* get the matrix that transforms from prevbone into this bone */ Mat3CpyMat4(R_bonemat, pchan->pose_mat); - + /* gather transformations for this IK segment */ - + if (pchan->parent) Mat3CpyMat4(R_parmat, pchan->parent->pose_mat); else Mat3One(R_parmat); - + /* bone offset */ if (pchan->parent && (a > 0)) VecSubf(start, pchan->pose_head, pchan->parent->pose_tail); @@ -1759,37 +1759,37 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* change length based on bone size */ length= bone->length*VecLength(R_bonemat[1]); - + /* compute rest basis and its inverse */ Mat3CpyMat3(rest_basis, bone->bone_mat); Mat3CpyMat3(irest_basis, bone->bone_mat); Mat3Transp(irest_basis); - + /* compute basis with rest_basis removed */ Mat3Inv(iR_parmat, R_parmat); Mat3MulMat3(full_basis, iR_parmat, R_bonemat); Mat3MulMat3(basis, irest_basis, full_basis); - + /* basis must be pure rotation */ Mat3Ortho(basis); - + /* transform offset into local bone space */ Mat3Ortho(iR_parmat); Mat3MulVecfl(iR_parmat, start); - + IK_SetTransform(seg, start, rest_basis, basis, length); - + if (pchan->ikflag & BONE_IK_XLIMIT) IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]); if (pchan->ikflag & BONE_IK_YLIMIT) IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]); if (pchan->ikflag & BONE_IK_ZLIMIT) IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]); - + IK_SetStiffness(seg, IK_X, pchan->stiffness[0]); IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]); IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]); - + if(tree->stretch && (pchan->ikstretch > 0.0)) { float ikstretch = pchan->ikstretch*pchan->ikstretch; IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.99)); @@ -1818,7 +1818,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) for (target=tree->targets.first; target; target=target->next) { float polepos[3]; int poleconstrain= 0; - + data= (bKinematicConstraint*)target->con->data; /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though @@ -1835,7 +1835,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* same for pole vector target */ if(data->poletar) { get_constraint_target_matrix(target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); - + if(data->flag & CONSTRAINT_IK_SETANGLE) { /* don't solve IK when we are setting the pole angle */ break; @@ -1844,7 +1844,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) Mat4MulMat4(goal, rootmat, goalinv); VECCOPY(polepos, goal[3]); poleconstrain= 1; - + if(data->flag & CONSTRAINT_IK_GETANGLE) { poleangledata= data; data->flag &= ~CONSTRAINT_IK_GETANGLE; @@ -1903,36 +1903,35 @@ static void execute_posetree(Object *ob, PoseTree *tree) tree->basis_change= MEM_mallocN(sizeof(float[3][3])*tree->totchannel, "ik basis change"); if(hasstretch) ikstretch= MEM_mallocN(sizeof(float)*tree->totchannel, "ik stretch"); - + for(a=0; a<tree->totchannel; a++) { IK_GetBasisChange(iktree[a], tree->basis_change[a]); - + if(hasstretch) { /* have to compensate for scaling received from parent */ float parentstretch, stretch; - + pchan= tree->pchan[a]; parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0; - + if(tree->stretch && (pchan->ikstretch > 0.0)) { float trans[3], length; - + IK_GetTranslationChange(iktree[a], trans); length= pchan->bone->length*VecLength(pchan->pose_mat[1]); - + ikstretch[a]= (length == 0.0)? 1.0: (trans[1]+length)/length; } else ikstretch[a] = 1.0; - + stretch= (parentstretch == 0.0)? 1.0: ikstretch[a]/parentstretch; - + VecMulf(tree->basis_change[a][0], stretch); VecMulf(tree->basis_change[a][1], stretch); VecMulf(tree->basis_change[a][2], stretch); - } - + IK_FreeSegment(iktree[a]); } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 3b4e562a87a..dd6c7ddacd2 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -630,7 +630,7 @@ void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end) } -static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode) +void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode) { KeyBlock *kb; int *ofsp, ofs[3], elemsize, b; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index dfd76a9c9d4..e64064d01c2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -40,6 +40,7 @@ #include "stdarg.h" #include "math.h" #include "float.h" +#include "ctype.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -1270,7 +1271,7 @@ static void mirrorModifier_initData(ModifierData *md) { MirrorModifierData *mmd = (MirrorModifierData*) md; - mmd->flag |= MOD_MIR_AXIS_X; + mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP); mmd->tolerance = 0.001; mmd->mirror_ob = NULL; } @@ -1309,6 +1310,118 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, } } +/* finds the best possible flipped name. For renaming; check for unique names afterwards */ +/* if strip_number: removes number extensions */ +void vertgroup_flip_name (char *name, int strip_number) +{ + int len; + char prefix[128]={""}; /* The part before the facing */ + char suffix[128]={""}; /* The part after the facing */ + char replace[128]={""}; /* The replacement string */ + char number[128]={""}; /* The number extension string */ + char *index=NULL; + + len= strlen(name); + if(len<3) return; // we don't do names like .R or .L + + /* We first check the case with a .### extension, let's find the last period */ + if(isdigit(name[len-1])) { + index= strrchr(name, '.'); // last occurrance + if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! + if(strip_number==0) + strcpy(number, index); + *index= 0; + len= strlen(name); + } + } + + strcpy (prefix, name); + +#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') + + /* first case; separator . - _ with extensions r R l L */ + if( IS_SEPARATOR(name[len-2]) ) { + switch(name[len-1]) { + case 'l': + prefix[len-1]= 0; + strcpy(replace, "r"); + break; + case 'r': + prefix[len-1]= 0; + strcpy(replace, "l"); + break; + case 'L': + prefix[len-1]= 0; + strcpy(replace, "R"); + break; + case 'R': + prefix[len-1]= 0; + strcpy(replace, "L"); + break; + } + } + /* case; beginning with r R l L , with separator after it */ + else if( IS_SEPARATOR(name[1]) ) { + switch(name[0]) { + case 'l': + strcpy(replace, "r"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'r': + strcpy(replace, "l"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'L': + strcpy(replace, "R"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'R': + strcpy(replace, "L"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + } + } + else if(len > 5) { + /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ + index = BLI_strcasestr(prefix, "right"); + if (index==prefix || index==prefix+len-5) { + if(index[0]=='r') + strcpy (replace, "left"); + else { + if(index[1]=='I') + strcpy (replace, "LEFT"); + else + strcpy (replace, "Left"); + } + *index= 0; + strcpy (suffix, index+5); + } + else { + index = BLI_strcasestr(prefix, "left"); + if (index==prefix || index==prefix+len-4) { + if(index[0]=='l') + strcpy (replace, "right"); + else { + if(index[1]=='E') + strcpy (replace, "RIGHT"); + else + strcpy (replace, "Right"); + } + *index= 0; + strcpy (suffix, index+4); + } + } + } + +#undef IS_SEPARATOR + + sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); +} + static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, Object *ob, DerivedMesh *dm, @@ -1322,6 +1435,9 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, int maxVerts = dm->getNumVerts(dm); int maxEdges = dm->getNumEdges(dm); int maxFaces = dm->getNumFaces(dm); + int vector_size, j, a, b; + bDeformGroup *def, *defb; + bDeformGroup **vector_def = NULL; int (*indexMap)[2]; float mtx[4][4], imtx[4][4]; @@ -1331,6 +1447,21 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2); + + if (mmd->flag & MOD_MIR_VGROUP) { + /* calculate the number of deformedGroups */ + for(vector_size = 0, def = ob->defbase.first; def; + def = def->next, vector_size++); + + /* load the deformedGroups for fast access */ + vector_def = + (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size, + "group_index"); + for(a = 0, def = ob->defbase.first; def; def = def->next, a++) { + vector_def[a] = def; + } + } + if (mmd->mirror_ob) { float obinv[4][4]; @@ -1375,16 +1506,48 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, mv->flag |= ME_VERT_MERGED; } else { MVert *mv2 = CDDM_get_vert(result, numVerts); + MDeformVert *dvert = NULL; DM_copy_vert_data(dm, result, i, numVerts, 1); *mv2 = *mv; - numVerts++; co[axis] = -co[axis]; if (mmd->mirror_ob) { VecMat4MulVecfl(co, imtx, co); } VecCopyf(mv2->co, co); + + if (mmd->flag & MOD_MIR_VGROUP){ + dvert = DM_get_vert_data(result, numVerts, CD_MDEFORMVERT); + + if (dvert) + { + for(j = 0; j < dvert[0].totweight; ++j) + { + char tmpname[32]; + + if(dvert->dw[j].def_nr < 0 || + dvert->dw[j].def_nr >= vector_size) + continue; + + def = vector_def[dvert->dw[j].def_nr]; + strcpy(tmpname, def->name); + vertgroup_flip_name(tmpname,0); + + for(b = 0, defb = ob->defbase.first; defb; + defb = defb->next, b++) + { + if(!strcmp(defb->name, tmpname)) + { + dvert->dw[j].def_nr = b; + break; + } + } + } + } + } + + numVerts++; } } @@ -1468,6 +1631,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } } + if (vector_def) MEM_freeN(vector_def); + MEM_freeN(indexMap); CDDM_lower_num_verts(result, numVerts); @@ -4361,13 +4526,13 @@ static void castModifier_deformVertsEM( /* Wave */ -static void waveModifier_initData(ModifierData *md) +static void waveModifier_initData(ModifierData *md) { WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq - + wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z); - + wmd->objectcenter = NULL; wmd->texture = NULL; wmd->map_object = NULL; @@ -4377,6 +4542,7 @@ static void waveModifier_initData(ModifierData *md) wmd->narrow= 1.5f; wmd->lifetime= 0.0f; wmd->damp= 10.0f; + wmd->falloff= 0.0f; wmd->texmapping = MOD_WAV_MAP_LOCAL; wmd->defgrp_name[0] = 0; } @@ -4396,6 +4562,7 @@ static void waveModifier_copyData(ModifierData *md, ModifierData *target) twmd->starty = wmd->starty; twmd->timeoffs = wmd->timeoffs; twmd->width = wmd->width; + twmd->falloff = wmd->falloff; twmd->objectcenter = wmd->objectcenter; twmd->texture = wmd->texture; twmd->map_object = wmd->map_object; @@ -4606,7 +4773,7 @@ static void waveModifier_do( if(x > wmd->lifetime) { lifefac = x - wmd->lifetime; - + if(lifefac > wmd->damp) lifefac = 0.0; else lifefac = (float)(wmd->height * (1.0 - sqrt(lifefac / wmd->damp))); @@ -4627,6 +4794,8 @@ static void waveModifier_do( float x = co[0] - wmd->startx; float y = co[1] - wmd->starty; float amplit= 0.0f; + float dist = 0.0f; + float falloff_fac = 0.0f; TexResult texres; MDeformWeight *def_weight = NULL; @@ -4649,14 +4818,29 @@ static void waveModifier_do( get_texture_value(wmd->texture, tex_co[i], &texres); } + /*get dist*/ + if(wmd->flag & MOD_WAVE_X) { + if(wmd->flag & MOD_WAVE_Y){ + dist = (float)sqrt(x*x + y*y); + } + else{ + dist = fabs(x); + } + } + else if(wmd->flag & MOD_WAVE_Y) { + dist = fabs(y); + } + + falloff_fac = (1.0-(dist / wmd->falloff)); + CLAMP(falloff_fac,0,1); if(wmd->flag & MOD_WAVE_X) { if(wmd->flag & MOD_WAVE_Y) amplit = (float)sqrt(x*x + y*y); else amplit = x; } - else if(wmd->flag & MOD_WAVE_Y) + else if(wmd->flag & MOD_WAVE_Y) amplit= y; - + /* this way it makes nice circles */ amplit -= (ctime - wmd->timeoffs) * wmd->speed; @@ -4669,12 +4853,19 @@ static void waveModifier_do( if(amplit > -wmd->width && amplit < wmd->width) { amplit = amplit * wmd->narrow; amplit = (float)(1.0 / exp(amplit * amplit) - minfac); + + /*apply texture*/ if(wmd->texture) amplit = amplit * texres.tin; + /*apply weight*/ if(def_weight) amplit = amplit * def_weight->weight; + /*apply falloff*/ + if (wmd->falloff > 0) + amplit = amplit * falloff_fac; + if(mvert) { /* move along normals */ if(wmd->flag & MOD_WAVE_NORM_X) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 125243bc56f..b72d9a0b044 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1100,6 +1100,8 @@ static void copy_object_pose(Object *obn, Object *ob) { bPoseChannel *chan; + /* note: need to clear obn->pose pointer first, so that copy_pose works (otherwise there's a crash) */ + obn->pose= NULL; copy_pose(&obn->pose, ob->pose, 1); /* 1 = copy constraints */ for (chan = obn->pose->chanbase.first; chan; chan=chan->next){ diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 86e395b3770..92544f19721 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -411,6 +411,7 @@ void init_actuator(bActuator *act) switch(act->type) { #ifdef __NLA case ACT_ACTION: + case ACT_SHAPEACTION: act->data= MEM_callocN(sizeof(bActionActuator), "actionact"); break; #endif |