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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Genrich <daniel.genrich@gmx.net>2008-01-09 15:04:54 +0300
committerDaniel Genrich <daniel.genrich@gmx.net>2008-01-09 15:04:54 +0300
commit43cd8a9f71da3e0d1a78a5c1e089afd464862a42 (patch)
tree3615d80057d47d114e0ff19e38d51cdb4710be09
parent86d8ef3f9125b4439b5231a756cee5cb89e3f270 (diff)
parent048170bc6f8e20beec8aedb4753991b027c65f4f (diff)
svn merge -r 13148:13177 https://svn.blender.org/svnroot/bf-blender/trunk/blender + fixed one crash on enabling deflection
-rw-r--r--source/blender/blenkernel/BKE_softbody.h1
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/intern/anim.c165
-rw-r--r--source/blender/blenkernel/intern/particle_system.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c843
-rw-r--r--source/blender/blenloader/intern/readfile.c54
-rw-r--r--source/blender/include/BIF_editaction.h1
-rw-r--r--source/blender/include/BSE_node.h6
-rw-r--r--source/blender/makesdna/DNA_action_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h9
-rw-r--r--source/blender/makesdna/DNA_object_force.h5
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_blur.c15
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_curves.c8
-rw-r--r--source/blender/render/intern/source/convertblender.c10
-rw-r--r--source/blender/src/buttons_object.c34
-rw-r--r--source/blender/src/drawnode.c147
-rw-r--r--source/blender/src/drawobject.c17
-rw-r--r--source/blender/src/editaction.c106
-rw-r--r--source/blender/src/editipo.c20
-rw-r--r--source/blender/src/editnode.c59
-rw-r--r--source/blender/src/editparticle.c1
-rw-r--r--source/blender/src/header_action.c13
-rw-r--r--source/blender/src/header_node.c12
-rw-r--r--source/blender/src/toolbox.c3
24 files changed, 1282 insertions, 256 deletions
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 0f58b93730a..512ee67b36f 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -41,6 +41,7 @@ typedef struct BodyPoint {
float origS[3], origE[3], origT[3], pos[3], vec[3], force[3];
float goal;
float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
+ float impdv[3],impdx[3];
int nofsprings; int *springs;
float choke;
float colball;
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 355cd19da33..f8f2f0b9f57 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -9,6 +9,7 @@ incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes'
incs += ' #/intern/iksolver/extern ../blenloader ../quicktime'
incs += ' #/extern/bullet2/src'
incs += ' #/intern/bmfont'
+incs += ' #/intern/opennl/extern'
incs += ' ' + env['BF_OPENGL_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 8651996515b..40c776248cf 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -47,6 +47,7 @@
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
@@ -76,7 +77,7 @@
#define MAX_DUPLI_RECUR 4
-static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level);
+static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level);
void free_path(Path *path)
{
@@ -327,7 +328,7 @@ static void group_duplilist(ListBase *lb, Object *ob, int level)
if(go->ob->transflag & OB_DUPLI) {
Mat4CpyMat4(dob->ob->obmat, dob->mat);
- object_duplilist_recursive((ID *)group, go->ob, lb, &ob->obmat, level+1);
+ object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1);
Mat4CpyMat4(dob->ob->obmat, dob->omat);
}
}
@@ -412,12 +413,12 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
float tmpmat[4][4];
Mat4CpyMat4(tmpmat, vdd->ob->obmat);
Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
- object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, &obmat, vdd->level+1);
+ object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1);
Mat4CpyMat4(vdd->ob->obmat, tmpmat);
}
}
-static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4], int level)
+static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level)
{
Object *ob, *ob_iter;
Base *base = NULL;
@@ -473,11 +474,11 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac
/* par_space_mat - only used for groups so we can modify the space dupli's are in
when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
*/
- if (par_space_mat) {
- Mat4MulMat4(vdd.obmat, ob->obmat, *par_space_mat);
- } else {
+ if(par_space_mat)
+ Mat4MulMat4(vdd.obmat, ob->obmat, par_space_mat);
+ else
Mat4CpyMat4(vdd.obmat, ob->obmat);
- }
+
vdd.id= id;
vdd.level= level;
vdd.lb= lb;
@@ -512,7 +513,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac
dm->release(dm);
}
-static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4], int level)
+static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level)
{
Object *ob, *ob_iter;
Base *base = NULL;
@@ -583,11 +584,10 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_
/* par_space_mat - only used for groups so we can modify the space dupli's are in
when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
*/
- if (par_space_mat) {
- Mat4MulMat4(ob__obmat, ob->obmat, *par_space_mat);
- } else {
+ if(par_space_mat)
+ Mat4MulMat4(ob__obmat, ob->obmat, par_space_mat);
+ else
Mat4CpyMat4(ob__obmat, ob->obmat);
- }
Mat3CpyMat4(imat, ob->parentinv);
@@ -638,7 +638,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_
float tmpmat[4][4];
Mat4CpyMat4(tmpmat, ob->obmat);
Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
- object_duplilist_recursive((ID *)id, ob, lb, &ob->obmat, level+1);
+ object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1);
Mat4CpyMat4(ob->obmat, tmpmat);
}
}
@@ -660,17 +660,46 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_
dm->release(dm);
}
-static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSystem *psys, int level)
+static void particle_dupli_path_rotation(Object *ob, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
+{
+ float loc[3], nor[3], vec[3], side[3], len;
+
+ VecSubf(vec, (cache+cache->steps-1)->co, cache->co);
+ len= Normalize(vec);
+
+ if(pa)
+ psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+ else
+ psys_particle_on_emitter(ob, psmd,
+ (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+ cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
+
+ Crossf(side, nor, vec);
+ Normalize(side);
+ Crossf(nor, vec, side);
+
+ Mat4One(mat);
+ VECCOPY(mat[0], vec);
+ VECCOPY(mat[1], side);
+ VECCOPY(mat[2], nor);
+
+ *scale= len;
+}
+
+static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level)
{
GroupObject *go;
- Object *ob, **oblist=0;
+ Object *ob=0, **oblist=0;
ParticleSettings *part;
ParticleData *pa;
ParticleKey state;
- float ctime, pa_time;
- float tmat[4][4], mat[3][3], obrotmat[3][3], parotmat[3][3], size=0.0;
+ ParticleCacheKey *cache;
+ ParticleSystemModifierData *psmd;
+ float ctime, pa_time, scale = 1.0f;
+ float tmat[4][4], mat[4][4], obrotmat[4][4], pamat[4][4], size=0.0;
+ float obmat[4][4], (*obmatlist)[4][4]=0;
float xvec[3] = {-1.0, 0.0, 0.0}, *q;
- int lay, a, k, step_nbr = 0, counter;
+ int lay, a, b, k, step_nbr = 0, counter, hair = 0;
int totpart, totchild, totgroup=0, pa_num;
if(psys==0) return;
@@ -678,9 +707,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
/* simple preventing of too deep nested groups */
if(level>MAX_DUPLI_RECUR) return;
- if (GS(id->name)!=ID_SCE) return; /* No support for groups YET! TODO */
-
part=psys->part;
+ psmd= psys_get_modifier(par, psys);
if(part==0) return;
@@ -700,6 +728,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
else
step_nbr = 0;
+ if(psys->flag & PSYS_HAIR_DONE)
+ hair= (totchild == 0 || psys->childcache) && psys->pathcache;
+
psys->lattice = psys_get_lattice(par, psys);
if(part->draw_as==PART_DRAW_GR) {
@@ -712,9 +743,16 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
}
oblist= MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
+ obmatlist= MEM_callocN(totgroup*sizeof(float)*4*4, "dupgroup obmat list");
go= part->dup_group->gobject.first;
- for(a=0; a<totgroup; a++, go=go->next)
+ for(a=0; a<totgroup; a++, go=go->next) {
oblist[a]=go->ob;
+ Mat4CpyMat4(obmatlist[a], go->ob->obmat);
+ }
+ }
+ else {
+ ob = part->dup_ob;
+ Mat4CpyMat4(obmat, ob->obmat);
}
if(totchild==0 || part->draw & PART_DRAW_PARENT)
@@ -724,7 +762,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) {
if(a<totpart) {
- if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
+ if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP))
+ continue;
pa_num=pa->num;
@@ -742,61 +781,91 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy
if(part->draw_as==PART_DRAW_GR) {
if(part->draw&PART_DRAW_RAND_GR)
- ob = oblist[BLI_rand() % totgroup];
+ b= BLI_rand() % totgroup;
else if(part->from==PART_FROM_PARTICLE)
- ob = oblist[pa_num % totgroup];
+ b= pa_num % totgroup;
else
- ob = oblist[a % totgroup];
+ b= a % totgroup;
+
+ ob = oblist[b];
+ Mat4CpyMat4(obmat, obmatlist[b]);
}
- else
- ob = part->dup_ob;
for(k=0; k<=step_nbr; k++, counter++) {
- if(step_nbr) {
+ if(hair) {
+ if(a < totpart) {
+ cache = psys->pathcache[a];
+ particle_dupli_path_rotation(par, part, psmd, pa, 0, cache, pamat, &scale);
+ }
+ else {
+ ChildParticle *cpa= psys->child+(a-totpart);
+ cache = psys->childcache[a-totpart];
+ particle_dupli_path_rotation(par, part, psmd, 0, cpa, cache, pamat, &scale);
+ }
+
+ VECCOPY(pamat[3], cache->co);
+ }
+ else if(step_nbr) {
state.time = (float)k / (float)step_nbr;
psys_get_particle_on_path(par, psys, a, &state, 0);
+
+ QuatToMat4(state.rot, pamat);
+ VECCOPY(pamat[3], state.co);
+ pamat[3][3]= 1.0f;
}
else {
state.time = -1.0;
if(psys_get_particle_state(par, psys, a, &state, 0) == 0)
continue;
- }
- QuatToMat3(state.rot, parotmat);
+ QuatToMat4(state.rot, pamat);
+ VECCOPY(pamat[3], state.co);
+ pamat[3][3]= 1.0f;
+ }
if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
- for(go= part->dup_group->gobject.first; go; go= go->next) {
-
- Mat4CpyMat4(tmat, go->ob->obmat);
- Mat4MulMat43(tmat, go->ob->obmat, parotmat);
- Mat4MulFloat3((float *)tmat, size);
+ for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
- VECADD(tmat[3], go->ob->obmat[3], state.co);
+ Mat4MulMat4(tmat, obmatlist[b], pamat);
+ Mat4MulFloat3((float *)tmat, size*scale);
+ if(par_space_mat)
+ Mat4MulMat4(mat, tmat, par_space_mat);
+ else
+ Mat4CpyMat4(mat, tmat);
- new_dupli_object(lb, go->ob, tmat, par->lay, counter, OB_DUPLIPARTS);
+ new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS);
}
}
else {
/* to give ipos in object correct offset */
where_is_object_time(ob, ctime-pa_time);
- q = vectoquat(xvec, ob->trackflag, ob->upflag);
- QuatToMat3(q, obrotmat);
+ if(!hair) {
+ q = vectoquat(xvec, ob->trackflag, ob->upflag);
+ QuatToMat4(q, obrotmat);
+ obrotmat[3][3]= 1.0f;
- Mat3MulMat3(mat, parotmat, obrotmat);
- Mat4CpyMat4(tmat, ob->obmat);
- Mat4MulMat43(tmat, ob->obmat, mat);
- Mat4MulFloat3((float *)tmat, size);
+ Mat4MulMat4(mat, obrotmat, pamat);
+ }
+ else
+ Mat4CpyMat4(mat, pamat);
- VECCOPY(tmat[3], state.co);
+ Mat4MulMat4(tmat, obmat, mat);
+ Mat4MulFloat3((float *)tmat, size*scale);
+ if(par_space_mat)
+ Mat4MulMat4(mat, tmat, par_space_mat);
+ else
+ Mat4CpyMat4(mat, tmat);
- new_dupli_object(lb, ob, tmat, par->lay, counter, OB_DUPLIPARTS);
+ new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS);
}
}
}
}
if(oblist)
MEM_freeN(oblist);
+ if(obmatlist)
+ MEM_freeN(obmatlist);
if(psys->lattice) {
end_latt_deform();
@@ -877,7 +946,7 @@ static void font_duplilist(ListBase *lb, Object *par, int level)
}
/* ***************************** */
-static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level)
+static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level)
{
if((ob->transflag & OB_DUPLI)==0)
return;
@@ -896,7 +965,7 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist,
if(ob->transflag & OB_DUPLIPARTS) {
ParticleSystem *psys = ob->particlesystem.first;
for(; psys; psys=psys->next)
- new_particle_duplilist(duplilist, id, ob, psys, level+1);
+ new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1);
}
else if(ob->transflag & OB_DUPLIVERTS) {
if(ob->type==OB_MESH) {
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 1235d9f5391..436d4d2210d 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1533,10 +1533,10 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
ParticleTexture ptex;
ParticleKey state;
IpoCurve *icu=0;
- float fac, rotfac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],*q2=0;
+ float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],*q2=0;
float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
- float q_one[4]={1.0,0.0,0.0,0.0}, q_phase[4];
+ float q_phase[4];
part=psys->part;
ptex.ivel=1.0;
@@ -4241,7 +4241,7 @@ static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd,
}
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && (psys_in_edit_mode(psys)
- || part->draw_as==PART_DRAW_PATH || part->draw&PART_DRAW_KEYS)){
+ || (part->type==PART_HAIR || part->draw_as==PART_DRAW_PATH) || part->draw&PART_DRAW_KEYS)){
psys_cache_paths(ob, psys, cfra, 0);
/* for render, child particle paths are computed on the fly */
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index f2258f0e1c4..b08b3e819d9 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -87,6 +87,7 @@ variables on the UI for now
#include "BIF_editdeform.h"
#include "BIF_graphics.h"
#include "PIL_time.h"
+#include "ONL_opennl.h"
/* callbacks for errors and interrupts and some goo */
static int (*SB_localInterruptCallBack)(void) = NULL;
@@ -97,7 +98,7 @@ static int (*SB_localInterruptCallBack)(void) = NULL;
typedef struct BodySpring {
int v1, v2;
- float len, strength, cf;
+ float len, strength, cf,load;
float ext_force[3]; /* edges colliding and sailing */
short order;
short flag;
@@ -120,6 +121,11 @@ typedef struct SBScratch {
float aabbmin[3],aabbmax[3];
}SBScratch;
+#define NLF_BUILD 1
+#define NLF_SOLVE 2
+
+#define MID_PRESERVE 1
+
#define SOFTGOALSNAP 0.999f
/* if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp
removes *unnecessary* stiffnes from ODE system
@@ -585,6 +591,7 @@ static void add_mesh_quad_diag_springs(Object *ob)
if (ob->soft){
int nofquads;
+ float s_shear = ob->soft->shearstiff*ob->soft->shearstiff;
nofquads = count_mesh_quads(me);
if (nofquads) {
@@ -605,12 +612,12 @@ static void add_mesh_quad_diag_springs(Object *ob)
if(mface->v4) {
bs->v1= mface->v1;
bs->v2= mface->v3;
- bs->strength= 1.0;
+ bs->strength= s_shear;
bs->order =2;
bs++;
bs->v1= mface->v2;
bs->v2= mface->v4;
- bs->strength= 1.0;
+ bs->strength= s_shear;
bs->order =2;
bs++;
@@ -692,6 +699,7 @@ static void add_2nd_order_springs(Object *ob,float stiffness)
{
int counter = 0;
BodySpring *bs_new;
+ stiffness *=stiffness;
add_2nd_order_roller(ob,stiffness,&counter,0); /* counting */
if (counter) {
@@ -1450,6 +1458,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
}
+
void scan_for_ext_spring_forces(Object *ob,float timenow)
{
SoftBody *sb = ob->soft;
@@ -2095,8 +2104,110 @@ static int sb_deflect_face(Object *ob,float *actpos,float *facenormal,float *for
return(deflected);
}
+static void dfdx_spring(int ia, int ic, int op, float dir[3],float L,float len,float factor)
+{
+ float m,delta_ij;
+ int i ,j;
+ if (L < len){
+ for(i=0;i<3;i++)
+ for(j=0;j<3;j++){
+ delta_ij = (i==j ? (1.0f): (0.0f));
+ m=factor*(dir[i]*dir[j] + (1-L/len)*(delta_ij - dir[i]*dir[j]));
+ nlMatrixAdd(ia+i,op+ic+j,m);
+ }
+ }
+ else{
+ for(i=0;i<3;i++)
+ for(j=0;j<3;j++){
+ m=factor*dir[i]*dir[j];
+ nlMatrixAdd(ia+i,op+ic+j,m);
+ }
+ }
+}
-static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
+
+static void dfdx_goal(int ia, int ic, int op, float factor)
+{
+ int i;
+ for(i=0;i<3;i++) nlMatrixAdd(ia+i,op+ic+i,factor);
+}
+
+static void dfdv_goal(int ia, int ic,float factor)
+{
+ int i;
+ for(i=0;i<3;i++) nlMatrixAdd(ia+i,ic+i,factor);
+}
+static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there */
+ BodyPoint *bp1,*bp2;
+
+ float dir[3],dvel[3];
+ float distance,forcefactor,kd,absvel,projvel;
+ int ia,ic;
+ /* prepare depending on which side of the spring we are on */
+ if (bpi == bs->v1){
+ bp1 = &sb->bpoint[bs->v1];
+ bp2 = &sb->bpoint[bs->v2];
+ ia =3*bs->v1;
+ ic =3*bs->v2;
+ }
+ else if (bpi == bs->v2){
+ bp1 = &sb->bpoint[bs->v2];
+ bp2 = &sb->bpoint[bs->v1];
+ ia =3*bs->v2;
+ ic =3*bs->v1;
+ }
+ else{
+ /* TODO make this debug option */
+ /**/
+ printf("bodypoint <bpi> is not attached to spring <*bs> --> sb_spring_force()\n");
+ return;
+ }
+
+ /* do bp1 <--> bp2 elastic */
+ VecSubf(dir,bp1->pos,bp2->pos);
+ distance = Normalize(dir);
+ if (bs->len < distance)
+ iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
+ else
+ iks = 1.0f/(1.0f-sb->inpush)-1.0f ;/* inner spring constants function */
+
+ if(bs->len > 0.0f) /* check for degenerated springs */
+ forcefactor = iks/bs->len;
+ else
+ forcefactor = iks;
+ forcefactor *= bs->strength;
+ Vec3PlusStVec(bp1->force,(bs->len - distance)*forcefactor,dir);
+
+ /* do bp1 <--> bp2 viscous */
+ VecSubf(dvel,bp1->vec,bp2->vec);
+ kd = sb->infrict * sb_fric_force_scale(ob);
+ absvel = Normalize(dvel);
+ projvel = Inpf(dir,dvel);
+ kd *= absvel * projvel;
+ Vec3PlusStVec(bp1->force,-kd,dir);
+
+ /* do jacobian stuff if needed */
+ if(nl_flags & NLF_BUILD){
+ int op =3*sb->totpoint;
+ float mvel = -forcetime*kd;
+ float mpos = -forcetime*forcefactor;
+ /* depending on my pos */
+ dfdx_spring(ia,ia,op,dir,bs->len,distance,-mpos);
+ /* depending on my vel */
+ dfdv_goal(ia,ia,mvel); // well that ignores geometie
+ if(bp2->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
+ /* depending on other pos */
+ dfdx_spring(ia,ic,op,dir,bs->len,distance,mpos);
+ /* depending on other vel */
+ dfdv_goal(ia,ia,-mvel); // well that ignores geometie
+ }
+ }
+}
+
+
+static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int nl_flags)
{
/* rule we never alter free variables :bp->vec bp->pos in here !
* this will ruin adaptive stepsize AKA heun! (BM)
@@ -2106,10 +2217,20 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
BodyPoint *bproot;
BodySpring *bs;
ListBase *do_effector;
- float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
+ float iks, ks, kd, gravity;
float fieldfactor = 1000.0f, windfactor = 250.0f;
float tune = sb->ballstiff;
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
+
+
+
+ NLboolean success;
+
+ if(nl_flags){
+ nlBegin(NL_SYSTEM);
+ nlBegin(NL_MATRIX);
+ }
+
gravity = sb->grav * sb_grav_force_scale(ob);
@@ -2131,7 +2252,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
float defforce[3];
do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
}
-
+/*
if (do_selfcollision ){
float ce[3];
VecMidf(ce,sb->scratch->aabbmax,sb->scratch->aabbmin);
@@ -2139,10 +2260,33 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
bp->octantflag = set_octant_flags(ce,bp->pos,bp->colball);
}
}
-
+*/
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* clear forces accumulator */
bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
+ if(nl_flags & NLF_BUILD){
+ int ia =3*(sb->totpoint-a);
+ int op =3*sb->totpoint;
+ /* dF/dV = v */
+
+ nlMatrixAdd(op+ia,ia,-forcetime);
+ nlMatrixAdd(op+ia+1,ia+1,-forcetime);
+ nlMatrixAdd(op+ia+2,ia+2,-forcetime);
+
+
+ /* we need [unit - h* dF/dy]^-1 */
+
+ nlMatrixAdd(ia,ia,1);
+ nlMatrixAdd(ia+1,ia+1,1);
+ nlMatrixAdd(ia+2,ia+2,1);
+
+ nlMatrixAdd(op+ia,op+ia,1);
+ nlMatrixAdd(op+ia+1,op+ia+1,1);
+ nlMatrixAdd(op+ia+2,op+ia+2,1);
+
+
+
+ }
/* naive ball self collision */
/* needs to be done if goal snaps or not */
@@ -2156,7 +2300,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
for(c=sb->totpoint, obp= sb->bpoint; c>=a; c--, obp++) {
- if ((bp->octantflag & obp->octantflag) == 0) continue;
+ //if ((bp->octantflag & obp->octantflag) == 0) continue;
compare = (obp->colball + bp->colball);
VecSubf(def, bp->pos, obp->pos);
@@ -2182,8 +2326,33 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
VecSubf(dvel,velcenter,bp->vec);
VecMulf(dvel,sb->nodemass);
- Vec3PlusStVec(bp->force,sb->balldamp,dvel);
Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
+ Vec3PlusStVec(bp->force,sb->balldamp,dvel);
+
+ if(nl_flags & NLF_BUILD){
+ int ia =3*(sb->totpoint-a);
+ int ic =3*(sb->totpoint-c);
+ int op =3*sb->totpoint;
+ float mvel = forcetime*sb->nodemass*sb->balldamp;
+ float mpos = forcetime*tune*(1.0f-sb->balldamp);
+ /*some quick and dirty entries to the jacobian*/
+ dfdx_goal(ia,ia,op,mpos);
+ dfdv_goal(ia,ia,mvel);
+ /* exploit force(a,b) == -force(b,a) part1/2 */
+ dfdx_goal(ic,ic,op,mpos);
+ dfdv_goal(ic,ic,mvel);
+
+
+ /*TODO sit down an X-out the true jacobian entries*/
+ /*well does not make to much sense because the eigenvalues
+ of the jacobian go negative; and negative eigenvalues
+ on a complex iterative system z(n+1)=A * z(n)
+ give imaginary roots in the charcateristic polynom
+ --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here
+ where u(t) is a unknown amplitude function (worst case rising fast)
+ */
+ }
+
/* exploit force(a,b) == -force(b,a) part2/2 */
VecSubf(dvel,velcenter,obp->vec);
VecMulf(dvel,sb->nodemass);
@@ -2191,6 +2360,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
Vec3PlusStVec(obp->force,sb->balldamp,dvel);
Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
+
}
}
}
@@ -2201,23 +2371,39 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
float auxvect[3];
float velgoal[3];
float absvel =0, projvel= 0;
-
/* do goal stuff */
if(ob->softflag & OB_SB_GOAL) {
/* true elastic goal */
- VecSubf(auxvect,bp->origT,bp->pos);
+ VecSubf(auxvect,bp->pos,bp->origT);
ks = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
- bp->force[0]+= ks*(auxvect[0]);
- bp->force[1]+= ks*(auxvect[1]);
- bp->force[2]+= ks*(auxvect[2]);
+ bp->force[0]+= -ks*(auxvect[0]);
+ bp->force[1]+= -ks*(auxvect[1]);
+ bp->force[2]+= -ks*(auxvect[2]);
+
+ if(nl_flags & NLF_BUILD){
+ int ia =3*(sb->totpoint-a);
+ int op =3*(sb->totpoint);
+ /* depending on my pos */
+ dfdx_goal(ia,ia,op,ks*forcetime);
+ }
+
+
/* calulate damping forces generated by goals*/
VecSubf(velgoal,bp->origS, bp->origE);
kd = sb->goalfrict * sb_fric_force_scale(ob) ;
+ VecAddf(auxvect,velgoal,bp->vec);
if (forcetime > 0.0 ) { /* make sure friction does not become rocket motor on time reversal */
- bp->force[0]-= kd * (velgoal[0] + bp->vec[0]);
- bp->force[1]-= kd * (velgoal[1] + bp->vec[1]);
- bp->force[2]-= kd * (velgoal[2] + bp->vec[2]);
+ bp->force[0]-= kd * (auxvect[0]);
+ bp->force[1]-= kd * (auxvect[1]);
+ bp->force[2]-= kd * (auxvect[2]);
+ if(nl_flags & NLF_BUILD){
+ int ia =3*(sb->totpoint-a);
+ Normalize(auxvect);
+ /* depending on my vel */
+ dfdv_goal(ia,ia,kd*forcetime);
+ }
+
}
else {
bp->force[0]-= kd * (velgoal[0] - bp->vec[0]);
@@ -2230,6 +2416,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
/* gravitation */
bp->force[2]-= gravity*sb->nodemass; /* individual mass of node here */
+ //bp->force[1]-= gravity*sb->nodemass; /* individual mass of node here */
/* particle field & vortex */
@@ -2260,6 +2447,16 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
bp->force[1]-= bp->vec[1]*kd;
bp->force[2]-= bp->vec[2]*kd;
/* friction in media done */
+ if(nl_flags & NLF_BUILD){
+ int ia =3*(sb->totpoint-a);
+ int op =3*sb->totpoint;
+ /* da/dv = */
+
+ nlMatrixAdd(ia,ia,forcetime*kd);
+ nlMatrixAdd(ia+1,ia+1,forcetime*kd);
+ nlMatrixAdd(ia+2,ia+2,forcetime*kd);
+ }
+
}
/* +++cached collision targets */
bp->choke = 0.0f;
@@ -2269,7 +2466,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
kd = 1.0f;
if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){
- if (intrusion < 0.0f){
+ if ((!nl_flags)&&(intrusion < 0.0f)){
/*bjornmose: uugh.. what an evil hack
violation of the 'don't touch bp->pos in here' rule
but works nice, like this-->
@@ -2287,8 +2484,15 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
VECSUB(cfforce,bp->vec,vel);
Vec3PlusStVec(bp->force,-cf*50.0f,cfforce);
}
-
Vec3PlusStVec(bp->force,kd,defforce);
+ if (nl_flags & NLF_BUILD){
+ int ia =3*(sb->totpoint-a);
+ int op =3*sb->totpoint;
+ //dfdx_goal(ia,ia,op,mpos); // don't do unless you know
+ //dfdv_goal(ia,ia,-cf);
+
+ }
+
}
}
@@ -2305,48 +2509,8 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
bp->choke = bs->cf;
}
-
- if (( (sb->totpoint-a) == bs->v1) ){
- VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
- actspringlen=Normalize(sd);
-
- /* friction stuff V1 */
- VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec);
- kd = sb->infrict * sb_fric_force_scale(ob);
- absvel = Normalize(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
- if(bs->len > 0.0f) /* check for degenerated springs */
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- forcefactor *= bs->strength;
-
- Vec3PlusStVec(bp->force,-forcefactor,sd);
-
- }
-
- if (( (sb->totpoint-a) == bs->v2) ){
- VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
- actspringlen=Normalize(sd);
-
- /* friction stuff V2 */
- VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec);
- kd = sb->infrict * sb_fric_force_scale(ob);
- absvel = Normalize(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
- if(bs->len > 0.0)
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- forcefactor *= bs->strength;
- Vec3PlusStVec(bp->force,+forcefactor,sd);
- }
+ // sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
+ sb_spring_force(ob,sb->totpoint-a,bs,iks,forcetime,nl_flags);
}/* loop springs */
}/* existing spring list */
}/*any edges*/
@@ -2356,14 +2520,206 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
/* finally add forces caused by face collision */
- if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
+ if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
+
+ /* finish matrix and solve */
+ if(nl_flags & NLF_SOLVE){
+ //double sct,sst=PIL_check_seconds_timer();
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ int iv =3*(sb->totpoint-a);
+ int ip =3*(2*sb->totpoint-a);
+ int n;
+ for (n=0;n<3;n++) {nlRightHandSideSet(0, iv+n, bp->force[0+n]);}
+ for (n=0;n<3;n++) {nlRightHandSideSet(0, ip+n, bp->vec[0+n]);}
+ }
+ nlEnd(NL_MATRIX);
+ nlEnd(NL_SYSTEM);
+
+ if ((G.rt >0) && (nl_flags & NLF_BUILD))
+ {
+ printf("####MEE#####\n");
+ nlPrintMatrix();
+ }
+
+ success= nlSolveAdvanced(NULL, 1);
+
+ // nlPrintMatrix(); /* for debug purpose .. anyhow cropping B vector looks like working */
+ if(success){
+ float f;
+ int index =0;
+ /* for debug purpose .. anyhow cropping B vector looks like working */
+ if (G.rt >0)
+ for(a=2*sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ f=nlGetVariable(0,index);
+ printf("(%f ",f);index++;
+ f=nlGetVariable(0,index);
+ printf("%f ",f);index++;
+ f=nlGetVariable(0,index);
+ printf("%f)",f);index++;
+ }
+
+ index =0;
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ f=nlGetVariable(0,index);
+ bp->impdv[0] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdv[1] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdv[2] = f; index++;
+ }
+ /*
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ f=nlGetVariable(0,index);
+ bp->impdx[0] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdx[1] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdx[2] = f; index++;
+ }
+ */
+ }
+ else{
+ printf("Matrix inversion failed \n");
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ VECCOPY(bp->impdv,bp->force);
+ }
+
+ }
+
+ //sct=PIL_check_seconds_timer();
+ //if (sct-sst > 0.01f) printf(" implicit solver time %f %s \r",sct-sst,ob->id.name);
+ }
/* cleanup */
+
if(do_effector) pdEndEffectors(do_effector);
}
+static void softbody_apply_fake_implicit_forces(Object *ob, float forcetime, float *err, float *err_ref_pos,float *err_ref_vel)
+{
+ /* time evolution */
+ /* do semi implicit euler */
+ SoftBody *sb= ob->soft; /* is supposed to be there */
+ BodyPoint *bp;
+ float *perp,*perv;
+ float erp[3],erv[3],dx[3],dv[3],aabbmin[3],aabbmax[3],cm[3]={0.0f,0.0f,0.0f};
+ float timeovermass;
+ float maxerrpos= 0.0f,maxerrvel = 0.0f,maxerrvel2 = 0.0f;
+ int a,fuzzy=0;
+
+ forcetime *= sb_time_scale(ob);
+
+ aabbmin[0]=aabbmin[1]=aabbmin[2] = 1e20f;
+ aabbmax[0]=aabbmax[1]=aabbmax[2] = -1e20f;
+
+ /* claim a minimum mass for vertex */
+ if (sb->nodemass > 0.009999f) timeovermass = forcetime/sb->nodemass;
+ else timeovermass = forcetime/0.009999f;
+ /* step along error reference vector */
+ perp =err_ref_pos;
+ perv =err_ref_vel;
-static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err)
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ /* step along error reference vector */
+ if(perp) {VECCOPY(erp,perp);perp +=3;}
+ if(perv) {VECCOPY(erv,perv);perv +=3;}
+ if(bp->goal < SOFTGOALSNAP){
+
+ /* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/
+ /* the ( ... )' operator denotes derivate respective time */
+ /* the "implicit" euler step for velocity then becomes */
+ /* v(t + dt) = v(t) + O * X(t) * dt */
+ /* O = [1-dt*dA/d(X)]^1 */
+ /* with X = (a[n],v[n]) */
+ /* da/dv | da/dx */
+ /* dA/d(X) = ( ------------- )*/
+ /* dv/dv | dv/dx */
+ /* note!! we did not solve any implicit system but looking forward more or less smart
+ what a implicit solution may look like by means of taylor expansion */
+ VECCOPY(dx,bp->vec);
+
+ bp->force[0]= timeovermass * bp->impdv[0]; /* individual mass of node here */
+ bp->force[1]= timeovermass * bp->impdv[1];
+ bp->force[2]= timeovermass * bp->impdv[2];
+ VECCOPY(dv,bp->force);
+ if(perv){
+ maxerrvel = MAX2(maxerrvel,ABS(dv[0] - erv[0]));
+ maxerrvel = MAX2(maxerrvel,ABS(dv[1] - erv[1]));
+ maxerrvel = MAX2(maxerrvel,ABS(dv[2] - erv[2]));
+ }
+
+ maxerrvel2 = MAX2(maxerrvel2,ABS(dv[0]));
+ maxerrvel2 = MAX2(maxerrvel2,ABS(dv[1]));
+ maxerrvel2 = MAX2(maxerrvel2,ABS(dv[2]));
+
+ VECADD(bp->vec, bp->vec, dv);
+
+ /* so here is (x)'= v(elocity) */
+ /* the euler step for location then becomes */
+ /* x(t + dt) = x(t) + v(t) * dt */
+
+// VECCOPY(dx,bp->vec);
+
+ dx[0]*=forcetime;
+ dx[1]*=forcetime;
+ dx[2]*=forcetime;
+
+ /* bp->choke is set when we need to pull a vertex or edge out of the collider.
+ the collider object signals to get out by pushing hard. on the other hand
+ we don't want to end up in deep space so we add some <viscosity>
+ to balance that out */
+ if (bp->choke > 0.0f){
+ dx[0]*=(1.0f - bp->choke);
+ dx[1]*=(1.0f - bp->choke);
+ dx[2]*=(1.0f - bp->choke);
+ }
+
+
+ /* should be possible to get more out of the matrix inversion
+ but not verified yet
+ dx[0]*=forcetime*forcetime*bp->impdx[0];
+ dx[1]*=forcetime*forcetime*bp->impdx[1];
+ dx[2]*=forcetime*forcetime*bp->impdx[2];
+ */
+ VECADD(bp->pos, bp->pos, dx);
+ if (perp){
+ maxerrpos = MAX2(maxerrpos,ABS(bp->pos[0]-erp[0]));
+ maxerrpos = MAX2(maxerrpos,ABS(bp->pos[1]-erp[1]));
+ maxerrpos = MAX2(maxerrpos,ABS(bp->pos[2]-erp[2]));
+ }
+
+
+ }/*snap*/
+ /* so while we are looping BPs anyway do statistics on the fly */
+ aabbmin[0] = MIN2(aabbmin[0],bp->pos[0]);
+ aabbmin[1] = MIN2(aabbmin[1],bp->pos[1]);
+ aabbmin[2] = MIN2(aabbmin[2],bp->pos[2]);
+ aabbmax[0] = MAX2(aabbmax[0],bp->pos[0]);
+ aabbmax[1] = MAX2(aabbmax[1],bp->pos[1]);
+ aabbmax[2] = MAX2(aabbmax[2],bp->pos[2]);
+ if (bp->flag & SBF_DOFUZZY) fuzzy =1;
+ } /*for*/
+
+ if (sb->totpoint) VecMulf(cm,1.0f/sb->totpoint);
+ if (sb->scratch){
+ VECCOPY(sb->scratch->aabbmin,aabbmin);
+ VECCOPY(sb->scratch->aabbmax,aabbmax);
+ }
+
+ if (err){ /* so step size will be controlled by biggest difference in slope */
+ if (sb->solverflags & SBSO_OLDERR)
+ *err = MAX2(maxerrpos,maxerrvel);
+ else
+ if (perp) *err = maxerrpos;
+ else *err = maxerrvel2;
+ //printf("EP %f EV %f \n",maxerrpos,maxerrvel);
+ if (fuzzy){
+ *err /= sb->fuzzyness;
+ }
+ }
+}
+
+static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err, int mid_flags)
{
/* time evolution */
/* actually does an explicit euler step mode == 0 */
@@ -2386,6 +2742,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
if(bp->goal < SOFTGOALSNAP){
+ if(mid_flags & MID_PRESERVE) VECCOPY(dx,bp->vec);
/* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/
/* the ( ... )' operator denotes derivate respective time */
@@ -2417,8 +2774,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
/* so here is (x)'= v(elocity) */
/* the euler step for location then becomes */
/* x(t + dt) = x(t) + v(t) * dt */
-
- VECCOPY(dx,bp->vec);
+ if(!(mid_flags & MID_PRESERVE)) VECCOPY(dx,bp->vec);
dx[0]*=forcetime;
dx[1]*=forcetime;
dx[2]*=forcetime;
@@ -2490,6 +2846,79 @@ static void softbody_restore_prev_step(Object *ob)
}
}
+static void softbody_store_step(Object *ob)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ VECCOPY(bp->prevvec,bp->vec);
+ VECCOPY(bp->prevpos,bp->pos);
+ }
+}
+
+
+/* used by predictors and correctors */
+static void softbody_store_state(Object *ob,float *ppos,float *pvel)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+ float *pp=ppos,*pv=pvel;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+ VECCOPY(pv, bp->vec);
+ pv+=3;
+
+ VECCOPY(pp, bp->pos);
+ pp+=3;
+ }
+}
+
+/* used by predictors and correctors */
+static void softbody_retrieve_state(Object *ob,float *ppos,float *pvel)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+ float *pp=ppos,*pv=pvel;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+ VECCOPY(bp->vec,pv);
+ pv+=3;
+
+ VECCOPY(bp->pos,pp);
+ pp+=3;
+ }
+}
+
+/* used by predictors and correctors */
+static void softbody_swap_state(Object *ob,float *ppos,float *pvel)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+ float *pp=ppos,*pv=pvel;
+ float temp[3];
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+ VECCOPY(temp, bp->vec);
+ VECCOPY(bp->vec,pv);
+ VECCOPY(pv,temp);
+ pv+=3;
+
+ VECCOPY(temp, bp->pos);
+ VECCOPY(bp->pos,pp);
+ VECCOPY(pp,temp);
+ pp+=3;
+ }
+}
+
+
/* care for bodypoints taken out of the 'ordinary' solver step
** because they are screwed to goal by bolts
** they just need to move along with the goal in time
@@ -3193,6 +3622,8 @@ SoftBody *sbNew(void)
sb->inspring= 0.5f;
sb->infrict= 0.5f;
+ /*todo backward file compat should copy infrict to inpush while reading old files*/
+ sb->inpush = 0.5f;
sb->interval= 10;
sb->sfra= G.scene->r.sfra;
@@ -3205,9 +3636,13 @@ SoftBody *sbNew(void)
sb->minloops = 10;
+ sb->maxloops = 300;
sb->choke = 3;
sb_new_scratch(sb);
+ /*todo backward file compat should set sb->shearstiff = 1.0f while reading old files*/
+ sb->shearstiff = 1.0f;
+ sb->solverflags |= SBSO_OLDERR;
return sb;
}
@@ -3256,7 +3691,7 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
HairKey *key= NULL;
BodyPoint *bp;
int a;
- float dtime,ctime,forcetime,err;
+ float dtime,ctime,forcetime;
float hairmat[4][4];
/* This part only sets goals and springs, based on original mesh/curve/lattice data.
@@ -3446,8 +3881,10 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
}
- if (TRUE) { /* */
+ if (sb->solver_ID < 2) {
/* special case of 2nd order Runge-Kutta type AKA Heun */
+ int mid_flags=0;
+ float err = 0;
float forcetimemax = 1.0f;
float forcetimemin = 0.001f;
float timedone =0.0; /* how far did we get without violating error condition */
@@ -3459,7 +3896,8 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
-
+
+ if(sb->solver_ID>0) mid_flags |= MID_PRESERVE;
//forcetime = dtime; /* hope for integrating in one step */
forcetime =forcetimemax; /* hope for integrating in one step */
@@ -3470,13 +3908,13 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
sb->scratch->flag &= ~SBF_DOFUZZY;
/* do predictive euler step */
- softbody_calc_forces(ob, forcetime,timedone/dtime);
- softbody_apply_forces(ob, forcetime, 1, NULL);
+ softbody_calc_forces(ob, forcetime,timedone/dtime,0);
+ softbody_apply_forces(ob, forcetime, 1, NULL,mid_flags);
/* crop new slope values to do averaged slope step */
- softbody_calc_forces(ob, forcetime,timedone/dtime);
- softbody_apply_forces(ob, forcetime, 2, &err);
+ softbody_calc_forces(ob, forcetime,timedone/dtime,0);
+ softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
softbody_apply_goalsnap(ob);
@@ -3517,6 +3955,7 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
sct=PIL_check_seconds_timer();
if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
}
+ /* ask for user break */
if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
}
@@ -3531,11 +3970,263 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
}
}
+ else if (sb->solver_ID == 2)
+ {
+ /* do semi "fake" implicit euler */
+ float *predict_vel=NULL,*predict_pos=NULL; /* for BDF style stepping */
+ NLContext *sb_nlc = NULL;
+ int npredict=0,predict_mem_size;
+ int nvar = 3*2*sb->totpoint;
+ int loops =0 ;
+ float forcetimemax = 1.0f; // this one needs 5 steps as a minimum
+ float forcetimemin = 0.001f;
+ float timedone =0.0; /* how far did we get without violating error condition */
+ /* loops = counter for emergency brake
+ * we don't want to lock up the system if physics fail
+ */
+ SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
+ if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
+ if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
+
+
+ forcetime =forcetimemax; /* hope for integrating as fast as possible */
+
+ //allocate predictor buffers
+ npredict =1;
+ predict_mem_size =3*sizeof(float)*npredict*sb->totpoint;
+ predict_pos = MEM_mallocN(predict_mem_size,"SB_predict_pos");
+ predict_vel = MEM_mallocN(predict_mem_size,"SB_predict_vel");
+
+
+ while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) ){
+ float loss_of_accuracy=0;
+ // create new solver context for this loop
+ sb_nlc = (NLContext*)nlNewContext();
+ /* hum it smells like threading trouble */
+ nlSolverParameteri(NL_NB_VARIABLES, nvar);
+ nlSolverParameteri(NL_LEAST_SQUARES, NL_FALSE);
+
+ interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
+ softbody_store_step(ob); /* used for rolling back step guessing */
+ softbody_store_state(ob,predict_pos,predict_vel);
+ softbody_calc_forces(ob, forcetime,timedone/dtime,NLF_BUILD|NLF_SOLVE);
+ // go full step
+ softbody_apply_fake_implicit_forces(ob, forcetime, NULL,NULL,NULL);
+
+ // restore old situation and store 1rst solution to predictors
+ softbody_swap_state(ob,predict_pos,predict_vel);
+ // the following is to find out how good we were
+ // may be we can do smarter
+ // so now using the forces and jacobian we calculated before
+ // go only 1/2
+ softbody_apply_fake_implicit_forces(ob, forcetime/2.0f, NULL,NULL,NULL);
+ // explore situation here without redoing the jacobian
+ softbody_calc_forces(ob, forcetime,timedone/dtime,NLF_SOLVE);
+ // go next 1/2
+ softbody_apply_fake_implicit_forces(ob, forcetime/2.0f,&loss_of_accuracy,predict_pos,predict_vel );
+ // now we have "loss_of_accuracy"
+
+ softbody_apply_goalsnap(ob);
+
+ if (loss_of_accuracy > SoftHeunTol) { /* error needs to be scaled to some quantity */
+
+ if (forcetime > forcetimemin){
+ forcetime = MAX2(forcetime / 2.0f,forcetimemin);
+ softbody_restore_prev_step(ob);
+ //printf("down,");
+ }
+ else {
+ timedone += forcetime;
+ }
+ }
+ else {
+ float newtime = forcetime * 1.5f; /* hope for 1.1 times better conditions in next step */
+ // all that 1/2 stepping was useless ... hum we know now ..
+ softbody_swap_state(ob,predict_pos,predict_vel);
+ if (0){//(sb->scratch->flag & SBF_DOFUZZY){
+ //if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) { /* stay with this stepsize unless err really small */
+ newtime = forcetime;
+ //}
+ }
+ else {
+ if (loss_of_accuracy > SoftHeunTol/1.1f) { /* stay with this stepsize unless err really small */
+ newtime = forcetime;
+ }
+ }
+
+ timedone += forcetime;
+ newtime=MIN2(forcetimemax,MAX2(newtime,forcetimemin));
+ //if (newtime > forcetime) printf("up,");
+ if (forcetime > 0.0)
+ forcetime = MIN2(dtime - timedone,newtime);
+ else
+ forcetime = MAX2(dtime - timedone,newtime);
+ }
+ loops++;
+ // give away solver context within loop
+ if (sb_nlc)
+ {
+ if (sb_nlc != nlGetCurrent())printf("Aye NL context mismatch! in softbody.c !\n");
+ nlDeleteContext(sb_nlc);
+ sb_nlc = NULL;
+ }
+
+ if(sb->solverflags & SBSO_MONITOR ){
+ sct=PIL_check_seconds_timer();
+ if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
+ }
+
+ /* ask for user break */
+ if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
+ }
+
+ // give away buffers
+ if (predict_pos) MEM_freeN(predict_pos);
+ if (predict_vel) MEM_freeN(predict_vel);
+
+ if(sb->solverflags & SBSO_MONITOR ){
+ if (loops > HEUNWARNLIMIT) /* monitor high loop counts */
+ printf("\r needed %d steps/frame ",loops);
+ }
+
+
+ }/*SOLVER SELECT*/
+ else if (sb->solver_ID == 4)
+ {
+ /* do semi "fake" implicit euler */
+ NLContext *sb_nlc = NULL;
+ int nvar = 3*2*sb->totpoint;
+ int loops =0 ;
+ float forcetimemax = 1.0f; // this one needs 5 steps as a minimum
+ float forcetimemin = 0.001f;
+ float timedone =0.0; /* how far did we get without violating error condition */
+ /* loops = counter for emergency brake
+ * we don't want to lock up the system if physics fail
+ */
+ SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
+ if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
+ if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
+
+
+ forcetime =forcetimemax; /* hope for integrating as fast as possible */
+ while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) ){
+ float loss_of_accuracy=0;
+ // create new solver context for this loop
+ sb_nlc = (NLContext*)nlNewContext();
+ /* hum it smells like threading trouble */
+ nlSolverParameteri(NL_NB_VARIABLES, nvar);
+ nlSolverParameteri(NL_LEAST_SQUARES, NL_FALSE);
+
+
+ interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
+ softbody_store_step(ob); /* used for rolling back step guessing */
+ softbody_calc_forces(ob, forcetime,timedone/dtime,NLF_BUILD|NLF_SOLVE);
+ softbody_apply_fake_implicit_forces(ob, forcetime,&loss_of_accuracy,NULL,NULL);
+ softbody_apply_goalsnap(ob);
+
+ if (loss_of_accuracy > SoftHeunTol) { /* error needs to be scaled to some quantity */
+
+ if (forcetime > forcetimemin){
+ forcetime = MAX2(forcetime / 2.0f,forcetimemin);
+ softbody_restore_prev_step(ob);
+ //printf("down,");
+ }
+ else {
+ timedone += forcetime;
+ }
+ }
+ else {
+ float newtime = forcetime * 1.1f; /* hope for 1.1 times better conditions in next step */
+ if (0){//(sb->scratch->flag & SBF_DOFUZZY){
+ //if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) { /* stay with this stepsize unless err really small */
+ newtime = forcetime;
+ //}
+ }
+ else {
+ if (loss_of_accuracy > SoftHeunTol/2.0f) { /* stay with this stepsize unless err really small */
+ newtime = forcetime;
+ }
+ }
+
+ timedone += forcetime;
+ newtime=MIN2(forcetimemax,MAX2(newtime,forcetimemin));
+ //if (newtime > forcetime) printf("up,");
+ if (forcetime > 0.0)
+ forcetime = MIN2(dtime - timedone,newtime);
+ else
+ forcetime = MAX2(dtime - timedone,newtime);
+ }
+ loops++;
+ // give away solver context within loop
+ if (sb_nlc)
+ {
+ if (sb_nlc != nlGetCurrent())printf("Aye NL context mismatch! in softbody.c !\n");
+ nlDeleteContext(sb_nlc);
+ sb_nlc = NULL;
+ }
+
+ if(sb->solverflags & SBSO_MONITOR ){
+ sct=PIL_check_seconds_timer();
+ if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
+ }
+
+ /* ask for user break */
+ if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
+ }
+
+
+ if(sb->solverflags & SBSO_MONITOR ){
+ if (loops > HEUNWARNLIMIT) /* monitor high loop counts */
+ printf("\r needed %d steps/frame ",loops);
+ }
+
+
+ }/*SOLVER SELECT*/
+ else if (sb->solver_ID == 3){
+ /* do "stupid" semi "fake" implicit euler */
+ NLContext *sb_nlc = NULL;
+ int nvar = 3*2*sb->totpoint;
+ int loops =0 ;
+ float forcetimemax = 1.0f; // this one needs 5 steps as a minimum
+ float timedone =0.0; /* how far did we get without violating error condition */
+ /* loops = counter for emergency brake
+ * we don't want to lock up the system if physics fail
+ */
+ if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
+
+
+ forcetime =forcetimemax; /* hope for integrating as fast as possible */
+
+ while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) ){
+
+ sb_nlc = (NLContext*)nlNewContext();
+ /* hum it smells like threading trouble */
+ nlSolverParameteri(NL_NB_VARIABLES, nvar);
+ nlSolverParameteri(NL_LEAST_SQUARES, NL_FALSE);
+
+ interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
+ softbody_calc_forces(ob, forcetime,timedone/dtime,NLF_BUILD|NLF_SOLVE);
+ softbody_apply_fake_implicit_forces(ob, forcetime, NULL,NULL,NULL);
+ softbody_apply_goalsnap(ob);
+ timedone += forcetime;
+ loops++;
+ if (sb_nlc)
+ {
+ if (sb_nlc != nlGetCurrent())printf("Aye NL context mismatch! in softbody.c !\n");
+ nlDeleteContext(sb_nlc);
+ sb_nlc = NULL;
+ }
+ /* ask for user break */
+ if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
+ }
+
+
+
+ }/*SOLVER SELECT*/
else{
- /* do brute force explicit euler */
- /* removed but left this branch for better integrators / solvers (BM) */
- /* yah! Nicholas Guttenberg (NichG) here is the place to plug in */
- }
+ printf("softbody no valid solver ID!");
+ }/*SOLVER SELECT*/
+
if(sb->solverflags & SBSO_MONITOR ){
sct=PIL_check_seconds_timer();
if (sct-sst > 0.5f) printf(" solver time %f %s \r",sct-sst,ob->id.name);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 96b0c372835..54d405132a9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6661,29 +6661,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
World *wrld;
if(main->versionfile != 244 || main->subversionfile < 2) {
- Mesh *me;
-
for(sce= main->scene.first; sce; sce= sce->id.next)
sce->r.mode |= R_SSS;
- /* Copy over old per-level multires vertex data
- into a single vertex array in struct Multires */
-
- for(me = main->mesh.first; me; me=me->id.next) {
- if(me->mr) {
- MultiresLevel *lvl = me->mr->levels.last;
- if(lvl) {
- me->mr->verts = lvl->verts;
- lvl->verts = NULL;
- /* Don't need the other vert arrays */
- for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
- MEM_freeN(lvl->verts);
- lvl->verts = NULL;
- }
- }
- }
- }
-
/* correct older action editors - incorrect scrolling */
for(sc= main->screen.first; sc; sc= sc->id.next) {
ScrArea *sa;
@@ -6737,6 +6717,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Lamp *la;
Material *ma;
ParticleSettings *part;
+ Mesh *me;
/* unless the file was created 2.44.3 but not 2.45, update the constraints */
if ( !(main->versionfile==244 && main->subversionfile==3) &&
@@ -6766,14 +6747,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
}
break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data= (bStretchToConstraint *)curcon->data;
-
- /* force recalc of rest-length */
- data->orglength = 0;
- }
- break;
}
}
}
@@ -6805,14 +6778,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
}
break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data= (bStretchToConstraint *)curcon->data;
-
- /* force recalc of rest-length */
- data->orglength = 0;
- }
- break;
}
}
@@ -6876,6 +6841,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ /* Copy over old per-level multires vertex data
+ into a single vertex array in struct Multires */
+ for(me = main->mesh.first; me; me=me->id.next) {
+ if(me->mr && !me->mr->verts) {
+ MultiresLevel *lvl = me->mr->levels.last;
+ if(lvl) {
+ me->mr->verts = lvl->verts;
+ lvl->verts = NULL;
+ /* Don't need the other vert arrays */
+ for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
+ MEM_freeN(lvl->verts);
+ lvl->verts = NULL;
+ }
+ }
+ }
+ }
if (main->versionfile != 245 || main->subversionfile < 1) {
for(la=main->lamp.first; la; la= la->id.next) {
diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h
index b32da691451..eb4adb4bbcf 100644
--- a/source/blender/include/BIF_editaction.h
+++ b/source/blender/include/BIF_editaction.h
@@ -112,6 +112,7 @@ void insertkey_action(void);
void delete_action_keys(void);
void delete_action_channels(void);
void clean_action(void);
+void sample_action_keys(void);
/* Column/Channel Key select */
void column_select_action_keys(int mode);
diff --git a/source/blender/include/BSE_node.h b/source/blender/include/BSE_node.h
index 5862918953c..b1854e31d50 100644
--- a/source/blender/include/BSE_node.h
+++ b/source/blender/include/BSE_node.h
@@ -54,6 +54,8 @@ struct Material *editnode_get_active_material(struct Material *ma);
struct bNode *editnode_get_active_idnode(struct bNodeTree *ntree, short id_code);
struct bNode *editnode_get_active(struct bNodeTree *ntree);
+void node_rename(struct SpaceNode *snode);
+
void snode_tag_dirty(struct SpaceNode *snode);
void snode_set_context(struct SpaceNode *snode);
@@ -72,7 +74,7 @@ void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode);
void node_hide(struct SpaceNode *snode);
void node_read_renderlayers(struct SpaceNode *snode);
void clear_scene_in_nodes(struct Scene *sce);
-void node_toggle_link(struct SpaceNode *snode);
+void node_make_link(struct SpaceNode *snode);
void node_transform_ext(int mode, int unused);
void node_shader_default(struct Material *ma);
@@ -97,6 +99,8 @@ struct SpaceNode;
struct bNodeLink;
void node_draw_link(struct SpaceNode *snode, struct bNodeLink *link);
+void node_rename_but(char *s);
+
void init_node_butfuncs(void);
/* exported to CMP and SHD nodes */
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 7ec81cfcf35..1f591894a90 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -90,7 +90,6 @@ typedef struct bPoseChannel {
*/
typedef struct bPose {
ListBase chanbase; /* list of pose channels */
- struct bAction *poselib; /* poselib-action for this pose */
short flag, proxy_layer; /* proxy layer: copy from armature, gets synced */
@@ -104,6 +103,7 @@ typedef struct bPose {
*/
typedef struct bActionChannel {
struct bActionChannel *next, *prev;
+
struct Ipo *ipo; /* IPO block this action channel references */
ListBase constraintChannels; /* Constraint Channels (when Action Channel represents an Object or Bone) */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index ceab9a1c9c1..d13ec7df8ca 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -107,6 +107,7 @@ typedef struct bNode {
struct bNode *next, *prev, *new_node;
char name[32];
+ char username[32]; /* custom name defined by user */
short type, flag;
short done, level; /* both for dependency and sorting */
short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */
@@ -196,11 +197,13 @@ typedef struct NodeImageAnim {
} NodeImageAnim;
typedef struct NodeBlurData {
- short sizex, sizey, samples, maxspeed, minspeed, pad1;
- float fac;
+ short sizex, sizey;
+ short samples, maxspeed, minspeed, relative;
+ float fac, percentx, percenty;
short filtertype;
char bokeh, gamma;
- int pad2;
+ int pad;
+ int image_in_width, image_in_height; /* needed for absolute/relative conversions */
} NodeBlurData;
typedef struct NodeDBlurData {
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 9a6a477bb47..b0408f2f4d9 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -129,10 +129,13 @@ typedef struct SoftBody {
minloops,
maxloops,
choke,
- pad3,pad4,pad5
+ solver_ID,
+ pad4,pad5
;
struct SBScratch *scratch; /* scratch pad/cache on live time not saved in file */
+ float shearstiff;
+ float inpush;
} SoftBody;
/* pd->forcefield: Effector Fields types */
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
index 8ef4af4d219..3d6b3dd2955 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
@@ -22,7 +22,8 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva,
+ * Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -556,16 +557,20 @@ static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf
static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
CompBuf *new, *img= in[0]->data;
+ NodeBlurData *nbd= node->storage;
- if(img==NULL || out[0]->hasoutput==0)
- return;
+ if(img==NULL) return;
+
+ /* store image in size that is needed for absolute/relative conversions on ui level */
+ nbd->image_in_width= img->x;
+ nbd->image_in_height= img->y;
+
+ if(out[0]->hasoutput==0) return;
if (((NodeBlurData *)node->storage)->filtertype == R_FILTER_FAST_GAUSS) {
CompBuf *new, *img = in[0]->data;
/*from eeshlo's original patch, removed to fit in with the existing blur node */
/*const float sx = in[1]->vec[0], sy = in[2]->vec[0];*/
-
- NodeBlurData *nbd= node->storage;
const float sx = ((float)nbd->sizex)/2.0f, sy = ((float)nbd->sizey)/2.0f;
int c;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c b/source/blender/nodes/intern/CMP_nodes/CMP_curves.c
index 17d9821a5ef..01af0e1db1d 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_curves.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Björn C. Schaefer
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -123,6 +123,8 @@ bNodeType cmp_node_curve_vec= {
static bNodeSocketType cmp_node_curve_rgb_in[]= {
{ SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
{ SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_RGBA, 1, "Black Level", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_RGBA, 1, "White Level", 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f},
{ -1, 0, "" }
};
@@ -157,7 +159,7 @@ static void do_curves_fac(bNode *node, float *out, float *in, float *fac)
static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
- /* stack order input: fac, image */
+ /* stack order input: fac, image, black level, white level */
/* stack order output: image */
if(out[0]->hasoutput==0)
@@ -172,6 +174,8 @@ static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **i
CompBuf *cbuf= in[1]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
+ curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec);
+
if(in[0]->vec[0] == 1.0)
composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA);
else
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index c0ebab1390a..56e7265b69e 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1496,7 +1496,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
- float loc_tex[3], size_tex[3], adapt_angle=0.0, adapt_pix=0.0, random;
+ float adapt_angle=0.0, adapt_pix=0.0, random;
float simplify[2];
int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0;
int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
@@ -1608,8 +1608,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
totpart=psys->totpart;
- mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
-
if(psys->pathcache){
path_possible=1;
keys_possible=1;
@@ -1789,12 +1787,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
}
- if(orco) {
- orco[0] = (orco[0]-loc_tex[0])/size_tex[0];
- orco[1] = (orco[1]-loc_tex[1])/size_tex[1];
- orco[2] = (orco[2]-loc_tex[2])/size_tex[2];
- }
-
/* surface normal shading setup */
if(ma->mode_l & MA_STR_SURFDIFF) {
Mat3MulVecfl(nmat, nor);
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 3883db39c74..f1b75d075f3 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -3181,7 +3181,7 @@ static void object_panel_deflection(Object *ob)
PartDeflect *pd= ob->pd;
but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
- uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
+ // uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
if(pd->deflect) {
uiDefBut(block, LABEL, 0, "Particles", 160,140,75,20, NULL, 0.0, 0, 0, 0, "");
@@ -3445,6 +3445,12 @@ static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
allqueue(REDRAWBUTSEDIT, 0);
}
+
+#ifdef _work_on_sb_solver
+static char sbsolvers[] = "Solver %t|RKP almost SOFT not usable but for some german teachers %x1|STU ip semi implicit euler%x3|SI1 (half step)adaptive semi implict euler %x2|SI2 (use dv)adaptive semi implict euler %x4|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
+#else
+static char sbsolvers[] = "STU PID semi implicit euler%x3|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
+#endif
static void object_softbodies_II(Object *ob)
{
SoftBody *sb=ob->soft;
@@ -3462,7 +3468,7 @@ static void object_softbodies_II(Object *ob)
}
block= uiNewBlock(&curarea->uiblocks, "object_softbodies_II", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Soft Body", "Physics");
- if(uiNewPanel(curarea, block, "Soft Body Collision", "Physics", 651, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Soft Body Col&Solv", "Physics", 651, 0, 318, 204)==0) return;
uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
@@ -3534,10 +3540,13 @@ static void object_softbodies_II(Object *ob)
uiBlockEndAlign(block);
/*SOLVER SETTINGS*/
- uiDefButF(block, NUM, B_DIFF, "Error Lim:", 10,100,130,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
- uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"O", 140,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Old Error Calculation");
- uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,100,130,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
- uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, MENU, B_DIFF, sbsolvers,10,100,50,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
+ uiDefButF(block, NUM, B_DIFF, "Error Lim:", 60,100,130,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+ uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"O", 190,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Old Error Calculation");
+ uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 210,100,90,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+ uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 300,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
+ uiBlockEndAlign(block);
uiDefButS(block, NUM, B_DIFF, "MinS:", 10,80,100,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
uiDefButS(block, NUM, B_DIFF, "MaxS:", 110,80,100,20, &sb->maxloops, 0.00, 30000.0, 10, 0, "Maximal # solver steps/frame ");
uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
@@ -3619,6 +3628,7 @@ static void object_softbodies(Object *ob)
else
but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
+
uiButSetFunc(but, object_softbodies__enable, ob, NULL);
}
@@ -3721,11 +3731,15 @@ static void object_softbodies(Object *ob)
uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,50,90,20, softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_DIFF, "CEdge", 220,50,45,20, softflag, 0, 0, 0, 0, "Edge collide too");
uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_DIFF, "CFace", 265,50,45,20, softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning ");
- uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,30,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness");
- uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,30,150,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
- uiDefButS(block, NUM, B_DIFF, "Aero:", 10,10,150,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
+ uiDefButF(block, NUM, B_DIFF, "E Pull:", 10,30,100,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness");
+ uiDefButF(block, NUM, B_DIFF, "E Push:", 110,30,100,20, &sb->inpush, 0.0, 0.999, 10, 0, "Edge spring stiffness");
+ uiDefButF(block, NUM, B_DIFF, "E Damp:", 210,30,100,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
+ uiDefButS(block, NUM, B_DIFF, "Aero:", 10,10,100,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
if(ob->type==OB_MESH) {
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Rigidity:", 160,10,150,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Strenght of Springs over 2 Edges");
+ uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Bend:", 110,10,100,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Strenght of Springs over 2 Edges");
+ if (*softflag & OB_SB_QUADS){
+ uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Shear:", 210,10,100,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Strenght of Springs over 2 Edges");
+ }
}
else sb->secondspring = 0;
uiDefBut(block, LABEL, 0, "",10,10,1,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index 491ecb6e741..961cad5f840 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -1047,12 +1047,41 @@ static int node_composit_buts_renderlayers(uiBlock *block, bNodeTree *ntree, bNo
return 19;
}
+static void node_blur_relative_cb(void *node, void *poin2)
+{
+ bNode *nodev= node;
+ NodeBlurData *nbd= nodev->storage;
+ if(nbd->image_in_width != 0){
+ if(nbd->relative){ /* convert absolute values to relative */
+ nbd->percentx= (float)(nbd->sizex)/nbd->image_in_width;
+ nbd->percenty= (float)(nbd->sizey)/nbd->image_in_height;
+ }else{ /* convert relative values to absolute */
+ nbd->sizex= (int)(nbd->percentx*nbd->image_in_width);
+ nbd->sizey= (int)(nbd->percenty*nbd->image_in_height);
+ }
+ }
+ allqueue(REDRAWNODE, 0);
+}
+static void node_blur_update_sizex_cb(void *node, void *poin2)
+{
+ bNode *nodev= node;
+ NodeBlurData *nbd= nodev->storage;
+
+ nbd->sizex= (int)(nbd->percentx*nbd->image_in_width);
+}
+static void node_blur_update_sizey_cb(void *node, void *poin2)
+{
+ bNode *nodev= node;
+ NodeBlurData *nbd= nodev->storage;
+
+ nbd->sizey= (int)(nbd->percenty*nbd->image_in_height);
+}
static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
NodeBlurData *nbd= node->storage;
uiBut *bt;
- short dy= butr->ymin+38;
+ short dy= butr->ymin+58;
short dx= (butr->xmax-butr->xmin)/2;
char str[256];
@@ -1074,15 +1103,33 @@ static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node
uiBlockBeginAlign(block);
}
dy-=19;
- bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X:",
- butr->xmin, dy, dx, 19,
- &nbd->sizex, 0, 256, 0, 0, "");
- bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y:",
- butr->xmin+dx, dy, dx, 19,
- &nbd->sizey, 0, 256, 0, 0, "");
+ bt= uiDefButS(block, TOG, B_NOP, "Relative",
+ butr->xmin, dy, dx*2, 19,
+ &nbd->relative, 0, 0, 0, 0, "Use relative (percent) values to define blur radius");
+ uiButSetFunc(bt, node_blur_relative_cb, node, NULL);
+
+ dy-=19;
+ if(nbd->relative) {
+ bt= uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "X:",
+ butr->xmin, dy, dx, 19,
+ &nbd->percentx, 0.0f, 1.0f, 0, 0, "");
+ uiButSetFunc(bt, node_blur_update_sizex_cb, node, NULL);
+ bt= uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Y:",
+ butr->xmin+dx, dy, dx, 19,
+ &nbd->percenty, 0.0f, 1.0f, 0, 0, "");
+ uiButSetFunc(bt, node_blur_update_sizey_cb, node, NULL);
+ }
+ else {
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X:",
+ butr->xmin, dy, dx, 19,
+ &nbd->sizex, 0, 256, 0, 0, "");
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y:",
+ butr->xmin+dx, dy, dx, 19,
+ &nbd->sizey, 0, 256, 0, 0, "");
+ }
uiBlockEndAlign(block);
}
- return 57;
+ return 77;
}
static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
@@ -1996,6 +2043,45 @@ void init_node_butfuncs(void)
/* ************** Generic drawing ************** */
+void node_rename_but(char *s)
+{
+ uiBlock *block;
+ ListBase listb={0, 0};
+ int dy, x1, y1, sizex=80, sizey=30;
+ short pivot[2], mval[2], ret=0;
+
+ getmouseco_sc(mval);
+
+ pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30);
+ pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10);
+
+ if (pivot[0]!=mval[0] || pivot[1]!=mval[1])
+ warp_pointer(pivot[0], pivot[1]);
+
+ mywinset(G.curscreen->mainwin);
+
+ x1= pivot[0]-sizex+10;
+ y1= pivot[1]-sizey/2;
+ dy= sizey/2;
+
+ block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK);
+
+ /* buttons have 0 as return event, to prevent menu to close on hotkeys */
+ uiBlockBeginAlign(block);
+
+ uiDefBut(block, TEX, B_NOP, "Name: ", (short)(x1),(short)(y1+dy), 150, 19, s, 0.0, 19.0, 0, 0, "Node user name");
+
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, BUT, 32767, "OK", (short)(x1+150), (short)(y1+dy), 29, 19, NULL, 0, 0, 0, 0, "");
+
+ uiBoundsBlock(block, 2);
+
+ ret= uiDoBlocks(&listb, 0, 0);
+}
+
+
static void draw_nodespace_grid(SpaceNode *snode)
{
float start, step= 25.0f;
@@ -2439,6 +2525,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
rctf *rct= &node->totr;
float slen, iconofs;
int ofs, color_id= node_get_colorid(node);
+ char showname[128];
uiSetRoundBox(15-4);
ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
@@ -2517,8 +2604,18 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
BIF_ThemeColor(TH_TEXT);
ui_rasterpos_safe(rct->xmin+19.0f, rct->ymax-NODE_DY+5.0f, snode->aspect);
- snode_drawstring(snode, node->name, (int)(iconofs - rct->xmin-18.0f));
-
+
+ if(node->username[0]) {
+ strcpy(showname,"(");
+ strcat(showname, node->username);
+ strcat(showname,") ");
+ strcat(showname, node->name);
+ }
+ else
+ strcpy(showname, node->name);
+
+ snode_drawstring(snode, showname, (int)(iconofs - rct->xmin-18.0f));
+
/* body */
BIF_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
@@ -2633,13 +2730,14 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
}
-void node_draw_hidden(SpaceNode *snode, bNode *node)
+static void node_draw_hidden(SpaceNode *snode, bNode *node)
{
bNodeSocket *sock;
rctf *rct= &node->totr;
float dx, centy= 0.5f*(rct->ymax+rct->ymin);
float hiddenrad= 0.5f*(rct->ymax-rct->ymin);
int color_id= node_get_colorid(node);
+ char showname[128];
/* shadow */
uiSetRoundBox(15);
@@ -2673,7 +2771,17 @@ void node_draw_hidden(SpaceNode *snode, bNode *node)
if(node->miniwidth>0.0f) {
ui_rasterpos_safe(rct->xmin+21.0f, centy-4.0f, snode->aspect);
- snode_drawstring(snode, node->name, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
+
+ if(node->username[0]) {
+ strcpy(showname,"(");
+ strcat(showname, node->username);
+ strcat(showname,") ");
+ strcat(showname, node->name);
+ }
+ else
+ strcpy(showname, node->name);
+
+ snode_drawstring(snode, showname, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
}
/* scale widget thing */
@@ -2875,6 +2983,7 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode)
bNodeTree *ngroup= (bNodeTree *)gnode->id;
bNodeSocket *sock;
rctf rect= gnode->totr;
+ char showname[128];
/* backdrop header */
glEnable(GL_BLEND);
@@ -2898,7 +3007,17 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode)
/* backdrop title */
BIF_ThemeColor(TH_TEXT_HI);
ui_rasterpos_safe(rect.xmin+8.0f, rect.ymax+5.0f, snode->aspect);
- BIF_DrawString(snode->curfont, ngroup->id.name+2, 0);
+
+ if(gnode->username[0]) {
+ strcpy(showname,"(");
+ strcat(showname, gnode->username);
+ strcat(showname,") ");
+ strcat(showname, ngroup->id.name+2);
+ }
+ else
+ strcpy(showname, ngroup->id.name+2);
+
+ BIF_DrawString(snode->curfont, showname, 0);
/* links from groupsockets to the internal nodes */
node_draw_group_links(snode, gnode);
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 61e4c6d5660..56eaeae29c9 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -3860,8 +3860,8 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys)
if(psys->childcache==0)
psys_cache_child_paths(ob, psys, CFRA, 0);
}
- else if(psys->childcache)
- free_child_path_cache(psys);
+ else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache)
+ free_child_path_cache(psys);
if((G.vd->flag & V3D_ZBUF_SELECT)==0)
glDisable(GL_DEPTH_TEST);
@@ -3905,13 +3905,14 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys)
}
glEnable(GL_LIGHTING);
+ if(psys->part->draw_as == PART_DRAW_PATH) {
+ for(i=0, path=psys->childcache; i<totchild; i++,path++){
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
+ glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
+ glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
- for(i=0, path=psys->childcache; i<totchild; i++,path++){
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
- glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
-
- glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
+ glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
+ }
}
glDisable(GL_COLOR_MATERIAL);
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 3d8f70824aa..62ee9563b3f 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -160,9 +160,9 @@ void remake_action_ipos (bAction *act)
testhandles_ipocurve(icu);
}
}
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (conchan->ipo) {
- for (icu = conchan->ipo->curve.first; icu; icu=icu->next){
+ for (icu = conchan->ipo->curve.first; icu; icu=icu->next) {
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
}
@@ -962,7 +962,7 @@ void insertkey_action(void)
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
-
+
/* ask user what to keyframe */
mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2");
if (mode <= 0) return;
@@ -1047,7 +1047,7 @@ void delete_action_keys (void)
allqueue(REDRAWNLA, 0);
}
-/* delete selected keyframes */
+/* delete selected action-channels (only achans and conchans are considered) */
void delete_action_channels (void)
{
ListBase act_data = {NULL, NULL};
@@ -1142,6 +1142,99 @@ void clean_action (void)
allqueue(REDRAWNLA, 0);
}
+
+/* little cache for values... */
+typedef struct tempFrameValCache {
+ float frame, val;
+} tempFrameValCache;
+
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
+void sample_action_keys (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* sanity checks */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
+ BezTriple *bezt, *start=NULL, *end=NULL;
+ tempFrameValCache *value_cache, *fp;
+ int sfra, range;
+ int i, n;
+
+ /* find selected keyframes... once pair has been found, add keyframes */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* check if selected, and which end this is */
+ if (BEZSELECTED(bezt)) {
+ if (start) {
+ /* set end */
+ end= bezt;
+
+ /* cache values then add keyframes using these values, as adding
+ * keyframes while sampling will affect the outcome...
+ */
+ range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
+ sfra= (int)( floor(start->vec[1][0]) );
+
+ if (range) {
+ value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
+
+ /* sample values */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ fp->frame= (float)(sfra + n);
+ fp->val= eval_icu(icu, fp->frame);
+ }
+
+ /* add keyframes with these */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ insert_vert_icu(icu, fp->frame, fp->val, 1);
+ }
+
+ /* free temp cache */
+ MEM_freeN(value_cache);
+ }
+
+ /* as we added keyframes, we need to compensate so that bezt is at the right place */
+ bezt = icu->bezt + i + range - 1;
+ i += (range - 1);
+
+ /* bezt was selected, so it now marks the start of a whole new chain to search */
+ start= bezt;
+ end= NULL;
+ }
+ else {
+ /* just set start keyframe */
+ start= bezt;
+ end= NULL;
+ }
+ }
+ }
+
+ /* recalculate channel's handles? */
+ calchandles_ipocurve(icu);
+ }
+
+ /* admin and redraws */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Sample Action Keys");
+ allqueue(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+}
+
/* **************************************************** */
/* COPY/PASTE FOR ACTIONS */
/* - The copy/paste buffer currently stores a set of Action Channels, with temporary
@@ -3087,7 +3180,10 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case OKEY:
- clean_action();
+ if (G.qual & LR_ALTKEY)
+ sample_action_keys();
+ else
+ clean_action();
break;
case PKEY:
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 8d75090d911..f66e3bfc22c 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -5653,22 +5653,24 @@ void delete_ipo_keys(Ipo *ipo)
IpoCurve *icu, *next;
int i;
- if (!ipo)
+ if (ipo == NULL)
return;
- for (icu=ipo->curve.first; icu; icu=next){
+ for (icu= ipo->curve.first; icu; icu= next) {
next = icu->next;
- for (i=0; i<icu->totvert; i++){
- if (icu->bezt[i].f2 & 1){
- // Delete the item
- memcpy (&icu->bezt[i], &icu->bezt[i+1], sizeof (BezTriple)*(icu->totvert-i-1));
+
+ /* Delete selected BezTriples */
+ for (i=0; i<icu->totvert; i++) {
+ if (icu->bezt[i].f2 & SELECT) {
+ memcpy(&icu->bezt[i], &icu->bezt[i+1], sizeof(BezTriple)*(icu->totvert-i-1));
icu->totvert--;
i--;
}
}
- if (!icu->totvert){
- /* Delete the curve */
- BLI_remlink( &(ipo->curve), icu);
+
+ /* Only delete if there isn't an ipo-driver still hanging around on an empty curve */
+ if (icu->totvert==0 && icu->driver==NULL) {
+ BLI_remlink(&ipo->curve, icu);
free_ipo_curve(icu);
}
}
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index d035908994c..645dc77c337 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -1083,7 +1083,29 @@ static void scale_node(SpaceNode *snode, bNode *node)
allqueue(REDRAWNODE, 1);
}
+/* ******************** rename ******************* */
+void node_rename(SpaceNode *snode)
+{
+ bNode *node, *rename_node;
+ short found_node= 0;
+
+ /* check if a node is selected */
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(node->flag & SELECT) {
+ found_node= 1;
+ break;
+ }
+ }
+
+ if(found_node) {
+ rename_node= nodeGetActive(snode->edittree);
+ node_rename_but((char *)rename_node->username);
+ BIF_undo_push("Rename Node");
+
+ allqueue(REDRAWNODE, 1);
+ }
+}
/* ********************** select ******************** */
@@ -1855,34 +1877,31 @@ void node_select_linked(SpaceNode *snode, int out)
allqueue(REDRAWNODE, 1);
}
-void node_toggle_link(SpaceNode *snode)
+/* makes a link between selected output and input sockets */
+void node_make_link(SpaceNode *snode)
{
bNode *fromnode, *tonode;
- bNodeLink *remlink, *link;
+ bNodeLink *link;
bNodeSocket *outsock= snode->edittree->selout;
bNodeSocket *insock= snode->edittree->selin;
if(!insock || !outsock) return;
+ if(nodeFindLink(snode->edittree, outsock, insock)) return;
- remlink= nodeFindLink(snode->edittree, outsock, insock);
-
- if(remlink) nodeRemLink(snode->edittree, remlink);
- else {
- if(nodeFindNode(snode->edittree, outsock, &fromnode, NULL) &&
- nodeFindNode(snode->edittree, insock, &tonode, NULL)) {
- link= nodeAddLink(snode->edittree, fromnode, outsock, tonode, insock);
- NodeTagChanged(snode->edittree, tonode);
- node_remove_extra_links(snode, insock, link);
- }
- else return;
+ if(nodeFindNode(snode->edittree, outsock, &fromnode, NULL) &&
+ nodeFindNode(snode->edittree, insock, &tonode, NULL)) {
+ link= nodeAddLink(snode->edittree, fromnode, outsock, tonode, insock);
+ NodeTagChanged(snode->edittree, tonode);
+ node_remove_extra_links(snode, insock, link);
}
+ else return;
ntreeSolveOrder(snode->edittree);
snode_verify_groups(snode);
snode_handle_recalc(snode);
allqueue(REDRAWNODE, 0);
- BIF_undo_push("Toggle Link");
+ BIF_undo_push("Make Link Between Sockets");
}
static void node_border_link_delete(SpaceNode *snode)
@@ -2278,7 +2297,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
snode_handle_recalc(snode);
break;
case FKEY:
- node_toggle_link(snode);
+ node_make_link(snode);
break;
case GKEY:
if(fromlib) fromlib= -1;
@@ -2308,8 +2327,12 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
node_select_linked(snode, G.qual==LR_SHIFTKEY);
break;
case RKEY:
- if(okee("Read saved Render Layers"))
- node_read_renderlayers(snode);
+ if(G.qual==LR_CTRLKEY) {
+ node_rename(snode);
+ } else{
+ if(okee("Read saved Render Layers"))
+ node_read_renderlayers(snode);
+ }
break;
case DELKEY:
case XKEY:
diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c
index 2274cc63980..eb98f3243f7 100644
--- a/source/blender/src/editparticle.c
+++ b/source/blender/src/editparticle.c
@@ -2392,6 +2392,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
ekey->time = &hkey->time;
}
+ pa->size= 1.0f;
initialize_particle(pa,i,ob,psys,psmd);
reset_particle(pa,psys,psmd,ob,0.0,1.0,0,0,0);
pa->flag |= PARS_EDIT_RECALC;
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index 1707dc82870..ab30c4cad52 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -117,7 +117,8 @@ enum {
enum {
ACTMENU_KEY_DUPLICATE = 0,
ACTMENU_KEY_DELETE,
- ACTMENU_KEY_CLEAN
+ ACTMENU_KEY_CLEAN,
+ ACTMENU_KEY_SAMPLEKEYS
};
enum {
@@ -1006,11 +1007,14 @@ static void do_action_keymenu(void *arg, int event)
duplicate_action_keys();
break;
case ACTMENU_KEY_DELETE:
- delete_action_keys ();
+ delete_action_keys();
break;
case ACTMENU_KEY_CLEAN:
clean_action();
break;
+ case ACTMENU_KEY_SAMPLEKEYS:
+ sample_action_keys();
+ break;
}
}
@@ -1052,6 +1056,11 @@ static uiBlock *action_keymenu(void *arg_unused)
"Clean Action|O", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_CLEAN, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Sample Keys|Alt O", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_SAMPLEKEYS, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
diff --git a/source/blender/src/header_node.c b/source/blender/src/header_node.c
index 7255dcd3286..a00cbd1290b 100644
--- a/source/blender/src/header_node.c
+++ b/source/blender/src/header_node.c
@@ -23,7 +23,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -513,8 +513,11 @@ static void do_node_nodemenu(void *arg, int event)
case 10: /* execute */
addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
break;
- case 11: /* toggle link */
- node_toggle_link(snode);
+ case 11: /* make link */
+ node_make_link(snode);
+ break;
+ case 12: /* rename */
+ node_rename(snode);
break;
}
@@ -541,7 +544,7 @@ static uiBlock *node_nodemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Toggle Link|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Link|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -552,6 +555,7 @@ static uiBlock *node_nodemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide/Unhide|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c
index f56434c8c4e..615cb1900bc 100644
--- a/source/blender/src/toolbox.c
+++ b/source/blender/src/toolbox.c
@@ -1674,13 +1674,14 @@ static TBitem tb_node_node[]= {
{ 0, "Duplicate|Shift D", TB_SHIFT|'d', NULL},
{ 0, "Delete|X", 'x', NULL},
{ 0, "SEPR", 0, NULL},
- { 0, "Toggle Link|F", 'f', NULL},
+ { 0, "Make Link|F", 'f', NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Make Group|Ctrl G", TB_CTRL|'g', NULL},
{ 0, "Ungroup|Alt G", TB_ALT|'g', NULL},
{ 0, "Edit Group|Tab", TB_TAB, NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Hide/Unhide|H", 'h', NULL},
+ { 0, "Rename|Ctrl R", TB_CTRL|'r', NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Read Saved Render Results|R", 'r', NULL},
{ 0, "Show Cyclic Dependencies|C", 'c', NULL},