diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2008-06-23 01:56:52 +0400 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2008-06-23 01:56:52 +0400 |
commit | 749054fe077dc6d0d5de35068669a98b4e491a59 (patch) | |
tree | 28cb6480f83aead33d59024d7669ba5ff5b91140 /source/blender/blenkernel/intern | |
parent | 831384a9bb0b29ebaf4c7837dc23f4676cdc80a8 (diff) | |
parent | d229db61e9f7e7e25a2c9c5cb5f4a8ce1623cc4d (diff) |
Merge with trunk (r15316)
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 4 | ||||
-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/cdderivedmesh.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 267 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sca.c | 4 |
11 files changed, 341 insertions, 81 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index fa749d8849a..80f57e520d2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -186,10 +186,6 @@ void DM_init_funcs(DerivedMesh *dm) void DM_init(DerivedMesh *dm, int numVerts, int numEdges, int numFaces) { - CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); - CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces); - dm->numVertData = numVerts; dm->numEdgeData = numEdges; dm->numFaceData = numFaces; 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/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 2ffb985e989..4b7573b8563 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -733,6 +733,10 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces) DM_init(dm, numVerts, numEdges, numFaces); + CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); + CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); + CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces); + CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces); @@ -754,6 +758,11 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) * with an exception for fluidsim */ DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface); + + CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert); + CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge); + CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface); + dm->deformedOnly = 1; if(ob && ob->fluidsimSettings && ob->fluidsimSettings->meshSurface) diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 902fcc48a39..17e9bf423aa 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1313,7 +1313,7 @@ void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n) int layer_index; /* get the layer index of the first layer of type */ - layer_index = CustomData_get_active_layer_index(data, type); + layer_index = CustomData_get_layer_index(data, type); if(layer_index < 0) return NULL; return (char *)block + data->layers[layer_index+n].offset; 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/library.c b/source/blender/blenkernel/intern/library.c index cc3f3f211a4..7c50b409693 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -934,7 +934,7 @@ int new_id(ListBase *lb, ID *id, const char *tname) } /* if result > 21, strncpy don't put the final '\0' to name. */ - if( result > 21 ) name[21]= 0; + if( result >= 21 ) name[21]= 0; result = check_for_dupid( lb, id, name ); strcpy( id->name+2, name ); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a6ddf6c24f1..0cf297076c2 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,11 +1310,123 @@ 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, - int initFlags, - int axis) + Object *ob, + DerivedMesh *dm, + int initFlags, + int axis) { int i; float tolerance = mmd->tolerance; @@ -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=0, j, a, b; + bDeformGroup *def, *defb; + bDeformGroup **vector_def = NULL; int (*indexMap)[2]; float mtx[4][4], imtx[4][4]; @@ -1331,9 +1447,24 @@ 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]; - + Mat4Invert(obinv, mmd->mirror_ob->obmat); Mat4MulMat4(mtx, ob->obmat, obinv); Mat4Invert(imtx, mtx); @@ -1344,16 +1475,16 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, MVert *mv = CDDM_get_vert(result, numVerts); int isShared; float co[3]; - + dm->getVert(dm, i, &inMV); - + VecCopyf(co, inMV.co); - + if (mmd->mirror_ob) { VecMat4MulVecfl(co, mtx, co); } isShared = ABS(co[axis])<=tolerance; - + /* Because the topology result (# of vertices) must be the same if * the mesh data is overridden by vertex cos, have to calc sharedness * based on original coordinates. This is why we test before copy. @@ -1361,10 +1492,10 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, DM_copy_vert_data(dm, result, i, numVerts, 1); *mv = inMV; numVerts++; - + indexMap[i][0] = numVerts - 1; indexMap[i][1] = !isShared; - + if(isShared) { co[axis] = 0; if (mmd->mirror_ob) { @@ -1375,41 +1506,73 @@ 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++; } } for(i = 0; i < maxEdges; i++) { MEdge inMED; MEdge *med = CDDM_get_edge(result, numEdges); - + dm->getEdge(dm, i, &inMED); - + DM_copy_edge_data(dm, result, i, numEdges, 1); *med = inMED; numEdges++; - + med->v1 = indexMap[inMED.v1][0]; med->v2 = indexMap[inMED.v2][0]; if(initFlags) med->flag |= ME_EDGEDRAW | ME_EDGERENDER; - + if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) { MEdge *med2 = CDDM_get_edge(result, numEdges); - + DM_copy_edge_data(dm, result, i, numEdges, 1); *med2 = *med; numEdges++; - + med2->v1 += indexMap[inMED.v1][1]; med2->v2 += indexMap[inMED.v2][1]; } @@ -1418,13 +1581,13 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, for(i = 0; i < maxFaces; i++) { MFace inMF; MFace *mf = CDDM_get_face(result, numFaces); - + dm->getFace(dm, i, &inMF); - + DM_copy_face_data(dm, result, i, numFaces, 1); *mf = inMF; numFaces++; - + mf->v1 = indexMap[inMF.v1][0]; mf->v2 = indexMap[inMF.v2][0]; mf->v3 = indexMap[inMF.v3][0]; @@ -1436,15 +1599,15 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, || (mf->v4 && indexMap[inMF.v4][1])) { MFace *mf2 = CDDM_get_face(result, numFaces); static int corner_indices[4] = {2, 1, 0, 3}; - + DM_copy_face_data(dm, result, i, numFaces, 1); *mf2 = *mf; - + mf2->v1 += indexMap[inMF.v1][1]; mf2->v2 += indexMap[inMF.v2][1]; mf2->v3 += indexMap[inMF.v3][1]; if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1]; - + /* mirror UVs if enabled */ if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) { MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE); @@ -1458,16 +1621,18 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } } } - + /* Flip face normal */ SWAP(int, mf2->v1, mf2->v3); DM_swap_face_data(result, numFaces, corner_indices); - + test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3); numFaces++; - } + } } + if (vector_def) MEM_freeN(vector_def); + MEM_freeN(indexMap); CDDM_lower_num_verts(result, numVerts); @@ -1478,8 +1643,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, - Object *ob, DerivedMesh *dm, - int initFlags) + Object *ob, DerivedMesh *dm, + int initFlags) { DerivedMesh *result = dm; @@ -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 4f901ba7216..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){ @@ -2380,3 +2382,31 @@ int give_obdata_texspace(Object *ob, int **texflag, float **loc, float **size, f } return 1; } + +/* + * Test a bounding box for ray intersection + * assumes the ray is already local to the boundbox space + */ +int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]) +{ + static int triangle_indexes[12][3] = {{0, 1, 2}, {0, 2, 3}, + {3, 2, 6}, {3, 6, 7}, + {1, 2, 6}, {1, 6, 5}, + {5, 6, 7}, {4, 5, 7}, + {0, 3, 7}, {0, 4, 7}, + {0, 1, 5}, {0, 4, 5}}; + int result = 0; + int i; + + for (i = 0; i < 12 && result == 0; i++) + { + float lambda; + int v1, v2, v3; + v1 = triangle_indexes[i][0]; + v2 = triangle_indexes[i][1]; + v3 = triangle_indexes[i][2]; + result = RayIntersectsTriangle(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL); + } + + return result; +} diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 5112fb08fe6..f06ef221795 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4814,9 +4814,20 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier pa->flag &= ~PARS_NO_DISP; } - /* ok now we're all set so let's go */ - if(psys->totpart) - dynamics_step(ob,psys,psmd,cfra,vg_vel,vg_tan,vg_rot,vg_size); + if(psys->totpart) { + int dframe, totframesback = 0; + + /* handle negative frame start at the first frame by doing + * all the steps before the first frame */ + if(framenr == startframe && part->sta < startframe) + totframesback = (startframe - (int)part->sta); + + for(dframe=-totframesback; dframe<=0; dframe++) { + /* ok now we're all set so let's go */ + dynamics_step(ob,psys,psmd,cfra+dframe,vg_vel,vg_tan,vg_rot,vg_size); + psys->cfra = cfra+dframe; + } + } cache->simframe= framenr; cache->flag |= PTCACHE_SIMULATION_VALID; diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 86e395b3770..16ca5d7542d 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 @@ -464,6 +465,9 @@ void init_actuator(bActuator *act) case ACT_PARENT: act->data = MEM_callocN(sizeof( bParentActuator ), "parent act"); break; + case ACT_STATE: + act->data = MEM_callocN(sizeof( bStateActuator ), "state act"); + break; default: ; /* this is very severe... I cannot make any memory for this */ /* logic brick... */ |