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:
authorTon Roosendaal <ton@blender.org>2005-04-02 17:57:23 +0400
committerTon Roosendaal <ton@blender.org>2005-04-02 17:57:23 +0400
commitbdb86d7c6765724d297e7aa97dec4c0cc7d2bae9 (patch)
treefd00e10fd560504d58150c8ce13ce9fb11dd5b9a /source/blender/blenkernel
parent02d3ad0b34c88be3cd8b581812a7faa08fa16d1b (diff)
Integration stage of Softbody project
User level notes are in Wiki here; http://wiki.blender.org/bin/view.pl/Blenderdev/Softbodies And will be added in blender3d.org CMS later. Tech level notes are still pending, but here's the most relevant ones; - made ob->soft struct SoftBody to hold all settings, and read/save in files - added (temporal!) conversion for the old settings. So: read old files with softbody experiments now, and save over! - cleaned API calls for softbody, which are only 5 of them now: sbNew() sbFree() sbObjectStep() (animation steps) sbObjectToSoftbody() (full re-initialize data) sbObjectReset() (only reset motion) - API calls accepts time in frames now, within softbody.c it converts Further, internally code was cleaned some (missing tabs etc). Also tried to keep a well defined structure with hints how to add support for more objects. Can write notes about that...
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_softbody.h30
-rw-r--r--source/blender/blenkernel/intern/deform.c12
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenkernel/intern/softbody.c807
5 files changed, 438 insertions, 415 deletions
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 24abff44a2b..09be644c9e7 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -46,29 +46,23 @@ typedef struct BodySpring {
float len, strength;
} BodySpring;
-typedef struct SoftBody {
- int totpoint, totspring;
-
- BodyPoint *bpoint;
- BodySpring *bspring;
-
- float ctime; // last time calculated
-} SoftBody;
+struct Object;
+struct SoftBody;
-/* temporal data, nothing saved in file */
-extern void free_softbody(SoftBody *sb);
+/* allocates and initializes general main data */
+extern struct SoftBody *sbNew(void);
-/* makes totally fresh start situation */
-extern void object_to_softbody(Object *ob,float ctime);
+/* frees internal data and softbody itself */
+extern void sbFree(struct SoftBody *sb);
-/* copy original (but new) situation in softbody, as result of matrices or deform */
-void object_update_softbody(Object *ob);
+/* go one step in simulation, copy result in displist vertices */
+extern void sbObjectStep(struct Object *ob, float framnr);
-/* copies softbody result back to object (in displist) */
-extern void softbody_to_object(Object *ob);
+/* makes totally fresh start situation, resets time */
+extern void sbObjectToSoftbody(struct Object *ob);
-/* go one step in simulation */
-extern void object_softbody_step(Object *ob, float ctime);
+/* resets all motion and time */
+extern void sbObjectReset(struct Object *ob);
#endif
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index fbf72fb71b2..d1c156380e8 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -264,19 +264,17 @@ int mesh_modifier(Object *ob, char mode)
if(ob->effect.first) done |= object_wave(ob);
- if((ob->softflag & 0x01) && !(ob->softflag & 0x08)) {
- float ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
+ if((ob->softflag & OB_SB_ENABLE) && !(ob->softflag & OB_SB_POSTDEF)) {
done= 1;
- object_softbody_step(ob, ctime);
+ sbObjectStep(ob, (float)G.scene->r.cfra);
}
- /* deform: input mesh, output ob dl_verts. is used by subsurf (output should be in mesh ton!) */
+ /* object_deform: output for mesh is in mesh->mvert */
done |= object_deform(ob);
- if((ob->softflag & 0x01) && (ob->softflag & 0x08)) {
- float ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
+ if((ob->softflag & OB_SB_ENABLE) && (ob->softflag & OB_SB_POSTDEF)) {
done= 1;
- object_softbody_step(ob, ctime);
+ sbObjectStep(ob, (float)G.scene->r.cfra);
}
/* put deformed vertices in dl->verts, optional subsurf will replace that */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 5efbcd832b0..4d6f0942f91 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -507,7 +507,7 @@ static void calc_curve_deform(Object *par, float *co, short axis, CurveDeform *c
}
-
+/* Mesh now applies on mesh itself, others do displist */
static int _object_deform(Object *ob, int applyflag)
{
Mesh *me;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 9285ed785a9..4342e5b3c8d 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -222,7 +222,7 @@ void free_object(Object *ob)
BPY_free_scriptlink(&ob->scriptlink);
if(ob->pd) MEM_freeN(ob->pd);
- if(ob->soft) free_softbody(ob->soft);
+ if(ob->soft) sbFree(ob->soft);
}
void unlink_object(Object *ob)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index bfc58070974..601b7e45afd 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -34,22 +34,18 @@
/*
******
variables on the UI for now
-typedef struct Object {
-.....
- float formfactor, softtime; softtime = #euler integrations steps per frame
-.....
- float sb_goalspring; softbody goal springs
- float sb_goalfrict; softbody goal springs friction
- float sb_inspring; softbody inner springs
- float sb_infrict; softbody inner springs friction
- float sb_nodemass; softbody mass of *vertex*
- float sb_grav; softbody amount of gravitaion to apply
- float sb_mingoal; quick limits for goal
- float sb_maxgoal;
- float sb_mediafrict; friction to env
- float sb_pad1; free
-
-
+
+ float mediafrict; friction to env
+ float nodemass; softbody mass of *vertex*
+ float grav; softbody amount of gravitaion to apply
+
+ float goalspring; softbody goal springs
+ float goalfrict; softbody goal springs friction
+ float mingoal; quick limits for goal
+ float maxgoal;
+
+ float inspring; softbody inner springs
+ float infrict; softbody inner springs friction
*****
*/
@@ -62,7 +58,6 @@ typedef struct Object {
#include "MEM_guardedalloc.h"
/* types */
-#include "DNA_ika_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -71,10 +66,11 @@ typedef struct Object {
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BKE_displist.h"
#include "BKE_global.h"
-#include "BKE_utildefines.h"
+#include "BKE_object.h"
#include "BKE_softbody.h"
-#include "BKE_displist.h"
+#include "BKE_utildefines.h"
#include "BIF_editdeform.h"
@@ -93,30 +89,32 @@ float steptime = 1.0f/25.0f; // translate framerate to *real* time
float rescale_grav_to_framerate = 1.0f; // since unit of g is [m/sec^2] we need translation from frames to physics time
float rescale_friction_to_framerate = 1.0f; // since unit of drag is [kg/sec] we need translation from frames to physics time
-short SB_ENABLE = 0; // quick hack to switch sb integration in 3d header
-
/* local prototypes */
-void softbody_scale_time(float steptime);
-int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target);
+static void softbody_scale_time(float steptime);
+static int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target);
+static void free_softbody_intern(SoftBody *sb);
-void softbody_scale_time(float steptime)
+static void softbody_scale_time(float steptime)
{
rescale_grav_to_framerate = steptime*steptime;
rescale_friction_to_framerate = steptime;
}
-static int count_quads( Mesh *me)
+static int count_mesh_quads(Mesh *me)
{
int a,result = 0;
MFace *mface= me->mface;
- if(mface ) {
- for(a=me->totface; a>0; a--, mface++) {if(mface->v4) result++;}
+
+ if(mface) {
+ for(a=me->totface; a>0; a--, mface++) {
+ if(mface->v4) result++;
+ }
}
return result;
}
-static void add_quad_diag_springs(Object *ob)
+static void add_mesh_quad_diag_springs(Object *ob)
{
Mesh *me= ob->data;
MFace *mface= me->mface;
@@ -125,22 +123,23 @@ static void add_quad_diag_springs(Object *ob)
int a ;
if (ob->soft){
- int nofquads;
- nofquads = count_quads(me);
+ int nofquads;
+
+ nofquads = count_mesh_quads(me);
if (nofquads) {
/* resize spring-array to hold additional quad springs */
bs_new= MEM_callocN( (ob->soft->totspring + nofquads *2 )*sizeof(BodySpring), "bodyspring");
memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
MEM_freeN(ob->soft->bspring); /* do this before reassigning the pointer or have a 1st class memory leak */
- ob->soft->bspring = bs_new;
+ ob->soft->bspring = bs_new;
+
/* fill the tail */
a = 0;
bs = bs_new+ob->soft->totspring;
bp= ob->soft->bpoint;
if(mface ) {
for(a=me->totface; a>0; a--, mface++) {
- if(mface->v4)
- {
+ if(mface->v4) {
bs->v1= mface->v1;
bs->v2= mface->v3;
bs->strength= 1.0;
@@ -158,15 +157,15 @@ static void add_quad_diag_springs(Object *ob)
/* now we can announce new springs */
ob->soft->totspring += nofquads *2;
-
}
}
}
-static void add_bp_springlist(BodyPoint *bp,int springID)
+static void add_bp_springlist(BodyPoint *bp,int springID)
{
int *newlist;
+
if (bp->springs == NULL) {
bp->springs = MEM_callocN( sizeof(int), "bpsprings");
bp->springs[0] = springID;
@@ -185,14 +184,15 @@ static void add_bp_springlist(BodyPoint *bp,int springID)
/* do this once when sb is build
it is O(N^2) so scanning for springs every iteration is too expensive
*/
-static void build_bps_springlist(Object *ob)
+static void build_bps_springlist(Object *ob)
{
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
BodySpring *bs;
-
int a,b;
- if (!sb) return; // paranoya check
+
+ if (sb==NULL) return; // paranoya check
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* scan for attached inner springs */
for(b=sb->totspring, bs= sb->bspring; b>0; b--, bs++) {
@@ -203,18 +203,22 @@ static void build_bps_springlist(Object *ob)
add_bp_springlist(bp,sb->totspring -b);
}
}//for springs
- if (bp->nofsprings) printf(" node %d has %d spring links\n",a,bp->nofsprings);
+ // if (bp->nofsprings) printf(" node %d has %d spring links\n",a,bp->nofsprings);
}//for bp
}
-
-static SoftBody *new_softbody(int totpoint, int totspring)
+/* creates new softbody if didn't exist yet, makes new points and springs arrays */
+/* called in mesh_to_softbody */
+static void renew_softbody(Object *ob, int totpoint, int totspring)
{
- SoftBody *sb= NULL;
+ SoftBody *sb;
+ if(ob->soft==NULL) ob->soft= sbNew();
+ else free_softbody_intern(ob->soft);
+ sb= ob->soft;
+
if(totpoint) {
- sb= MEM_callocN(sizeof(SoftBody), "softbody");
sb->totpoint= totpoint;
sb->totspring= totspring;
@@ -222,14 +226,15 @@ static SoftBody *new_softbody(int totpoint, int totspring)
if(totspring)
sb->bspring= MEM_mallocN( totspring*sizeof(BodySpring), "bodyspring");
}
- return sb;
}
-void free_softbody(SoftBody *sb)
+/* only frees internal data */
+static void free_softbody_intern(SoftBody *sb)
{
if(sb) {
int a;
BodyPoint *bp;
+
if(sb->bpoint){
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* free spring list */
@@ -239,10 +244,16 @@ void free_softbody(SoftBody *sb)
}
MEM_freeN(sb->bpoint);
}
+
if(sb->bspring) MEM_freeN(sb->bspring);
- MEM_freeN(sb);
+
+ sb->totpoint= sb->totspring= 0;
+ sb->bpoint= NULL;
+ sb->bspring= NULL;
}
}
+
+
/* ************ dynamics ********** */
/* aye this belongs to arith.c */
@@ -258,17 +269,18 @@ static void softbody_calc_forces(Object *ob, float dtime)
{
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
- float iks,ks,kd,gravity,actspringlen,forcefactor,sd[3];
- int a,b;
BodyPoint *bproot;
BodySpring *bs;
+ float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
+ int a, b;
+
/* clear forces */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
}
- gravity = ob->sb_nodemass * ob->sb_grav * rescale_grav_to_framerate;
- iks = 1.0f/(1.0f-ob->sb_inspring)-1.0f ;/* inner spring constants function */
+ gravity = sb->nodemass * sb->grav * rescale_grav_to_framerate;
+ iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
bproot= sb->bpoint; /* need this for proper spring addressing */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
@@ -278,34 +290,36 @@ static void softbody_calc_forces(Object *ob, float dtime)
float absvel =0, projvel= 0;
/* do goal stuff */
- /* true elastic goal */
- VecSubf(auxvect,bp->origT,bp->pos);
- ks = 1.0f/(1.0f- bp->goal*ob->sb_goalspring)-1.0f ;
- bp->force[0]= ks*(auxvect[0]);
- bp->force[1]= ks*(auxvect[1]);
- bp->force[2]= ks*(auxvect[2]);
- /* calulate damping forces generated by goals*/
- VecSubf(velgoal,bp->origS, bp->origE);
- kd = ob->sb_goalfrict * rescale_friction_to_framerate ;
-
- if (dtime > 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]);
- }
- else {
- 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]);
+ if(ob->softflag & OB_SB_GOAL) {
+ /* true elastic goal */
+ VecSubf(auxvect,bp->origT,bp->pos);
+ 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]);
+ /* calulate damping forces generated by goals*/
+ VecSubf(velgoal,bp->origS, bp->origE);
+ kd = sb->goalfrict * rescale_friction_to_framerate ;
+
+ if (dtime > 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]);
+ }
+ else {
+ 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]);
+ }
}
/* done goal stuff */
/* gravitation */
- bp->force[2]-= gravity*ob->sb_nodemass; /* individual mass of node here */
+ bp->force[2]-= gravity*sb->nodemass; /* individual mass of node here */
/* friction in media */
- kd= ob->sb_mediafrict* rescale_friction_to_framerate;
+ kd= sb->mediafrict* rescale_friction_to_framerate;
/* assume it to be proportional to actual velocity */
bp->force[0]-= bp->vec[0]*kd;
bp->force[1]-= bp->vec[1]*kd;
@@ -326,85 +340,87 @@ static void softbody_calc_forces(Object *ob, float dtime)
hrms .. may be a rough one could be used as well .. let's see
*/
- if (1){ /* big mesh optimization */
- /* run over attached inner spring list */
- if (sb->bspring){ // spring list exists at all ?
- for(b=bp->nofsprings;b>0;b--){
- bs = sb->bspring + bp->springs[b-1];
+ if(ob->softflag & OB_SB_EDGES) {
+ if (1){ /* big mesh optimization */
+ /* run over attached inner spring list */
+ if (sb->bspring){ // spring list exists at all ?
+ for(b=bp->nofsprings;b>0;b--){
+ bs = sb->bspring + bp->springs[b-1];
+ if (( (sb->totpoint-a) == bs->v1) ){
+ actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
+ VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
+ Normalise(sd);
+
+ // friction stuff V1
+ VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec);
+ kd = sb->infrict * rescale_friction_to_framerate ;
+ absvel = Normalise(velgoal);
+ projvel = ABS(Inpf(sd,velgoal));
+ kd *= absvel * projvel;
+ Vec3PlusStVec(bp->force,-kd,velgoal);
+
+ if(bs->len > 0.0) /* check for degenerated springs */
+ forcefactor = (bs->len - actspringlen)/bs->len * iks;
+ else
+ forcefactor = actspringlen * iks;
+
+ Vec3PlusStVec(bp->force,-forcefactor,sd);
+
+ }
+
+ if (( (sb->totpoint-a) == bs->v2) ){
+ actspringlen= VecLenf( (bproot+bs->v1)->pos, bp->pos);
+ VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
+ Normalise(sd);
+
+ // friction stuff V2
+ VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec);
+ kd = sb->infrict * rescale_friction_to_framerate ;
+ absvel = Normalise(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;
+ Vec3PlusStVec(bp->force,+forcefactor,sd);
+ }
+ }
+ } //if spring list exists at all ?
+ }
+ else{ // this branch is not completly uptaded for friction stuff
+ /* scan for attached inner springs makes it a O(N^2) thing = bad !*/
+ /* obsolete .. but if someone wants to try the effect :) */
+ for(b=sb->totspring, bs= sb->bspring; b>0; b--, bs++) {
if (( (sb->totpoint-a) == bs->v1) ){
actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
Normalise(sd);
- // friction stuff V1
- VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec);
- kd = ob->sb_infrict * rescale_friction_to_framerate ;
- absvel = Normalise(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
+
if(bs->len > 0.0) /* check for degenerated springs */
forcefactor = (bs->len - actspringlen)/bs->len * iks;
else
forcefactor = actspringlen * iks;
-
Vec3PlusStVec(bp->force,-forcefactor,sd);
-
}
if (( (sb->totpoint-a) == bs->v2) ){
actspringlen= VecLenf( (bproot+bs->v1)->pos, bp->pos);
VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
Normalise(sd);
-
- // friction stuff V2
- VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec);
- kd = ob->sb_infrict * rescale_friction_to_framerate ;
- absvel = Normalise(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;
- Vec3PlusStVec(bp->force,+forcefactor,sd);
+ Vec3PlusStVec(bp->force,+forcefactor,sd);
}
- }
- } //if spring list exists at all ?
- }
- else{ // this branch is not completly uptaded for friction stuff
- /* scan for attached inner springs makes it a O(N^2) thing = bad !*/
- /* obsolete .. but if someone wants to try the effect :) */
- for(b=sb->totspring, bs= sb->bspring; b>0; b--, bs++) {
- if (( (sb->totpoint-a) == bs->v1) ){
- actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
- VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
- Normalise(sd);
-
-
- if(bs->len > 0.0) /* check for degenerated springs */
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- Vec3PlusStVec(bp->force,-forcefactor,sd);
- }
-
- if (( (sb->totpoint-a) == bs->v2) ){
- actspringlen= VecLenf( (bproot+bs->v1)->pos, bp->pos);
- VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
- Normalise(sd);
-
- if(bs->len > 0.0)
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- Vec3PlusStVec(bp->force,+forcefactor,sd);
- }
- }// no snap
- }//for
+ }// no snap
+ }//for
+ }// if use edges
}
}
}
@@ -417,11 +433,11 @@ static void softbody_apply_forces(Object *ob, float dtime, int mode, float *err)
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
float dx[3],dv[3];
- int a;
float timeovermass;
float maxerr = 0.0;
+ int a;
- if (ob->sb_nodemass > 0.09999f) timeovermass = dtime/ob->sb_nodemass;
+ if (sb->nodemass > 0.09999f) timeovermass = dtime/sb->nodemass;
else timeovermass = dtime/0.09999f;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
@@ -436,8 +452,8 @@ static void softbody_apply_forces(Object *ob, float dtime, int mode, float *err)
/* some nasty if's to have heun in here too */
VECCOPY(dv,bp->force);
if (mode == 1){
- VECCOPY(bp->prevvec,bp->vec);
- VECCOPY(bp->prevdv ,dv);
+ VECCOPY(bp->prevvec, bp->vec);
+ VECCOPY(bp->prevdv, dv);
}
if (mode ==2){
/* be optimistic and execute step */
@@ -488,41 +504,14 @@ static void softbody_restore_prev_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->vec,bp->prevvec);
- VECCOPY(bp->pos,bp->prevpos);
- }
-}
-
-
-/* unused */
-#if 0
-static void softbody_apply_goal(Object *ob, float dtime)
-{
-
- SoftBody *sb= ob->soft; // is supposed to be there
- BodyPoint *bp;
- float vec[3], ks;
int a;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
- ks= bp->goal*dtime;
- // this is hackish, screws up physics but stabilizes
- vec[0]= ks*(bp->origT[0]-bp->pos[0]);
- vec[1]= ks*(bp->origT[1]-bp->pos[1]);
- vec[2]= ks*(bp->origT[2]-bp->pos[2]);
-
- VECADD(bp->pos, bp->pos, vec);
-
- ks= 1.0f-ks;
- bp->vec[0]*= ks;
- bp->vec[1]*= ks;
- bp->vec[2]*= ks;
-
+ VECCOPY(bp->vec, bp->prevvec);
+ VECCOPY(bp->pos, bp->prevpos);
}
}
-#endif
+
static void softbody_apply_goalsnap(Object *ob)
{
@@ -538,6 +527,8 @@ static void softbody_apply_goalsnap(Object *ob)
}
}
+/* unused */
+#if 0
static void softbody_force_goal(Object *ob)
{
SoftBody *sb= ob->soft; // is supposed to be there
@@ -551,44 +542,67 @@ static void softbody_force_goal(Object *ob)
bp->vec[2] = bp->origE[2] - bp->origS[2];
}
}
+#endif
+/* expects full initialized softbody */
static void interpolate_exciter(Object *ob, int timescale, int time)
{
- Mesh *me= ob->data;
- //MEdge *medge= me->medge;
- int a;
+ SoftBody *sb= ob->soft;
BodyPoint *bp;
float f;
+ int a;
+
+ // note: i removed Mesh usage here, softbody should remain generic! (ton)
- if(ob->soft) {
- f = (float)time/(float)timescale;
- bp= ob->soft->bpoint;
- for(a=0; a<me->totvert; a++, bp++) {
- bp->origT[0] = bp->origS[0] + f*(bp->origE[0] - bp->origS[0]);
- bp->origT[1] = bp->origS[1] + f*(bp->origE[1] - bp->origS[1]);
- bp->origT[2] = bp->origS[2] + f*(bp->origE[2] - bp->origS[2]);
- if (bp->goal >= SOFTGOALSNAP){
- bp->vec[0] = bp->origE[0] - bp->origS[0];
- bp->vec[1] = bp->origE[1] - bp->origS[1];
- bp->vec[2] = bp->origE[2] - bp->origS[2];
- }
+ f = (float)time/(float)timescale;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ bp->origT[0] = bp->origS[0] + f*(bp->origE[0] - bp->origS[0]);
+ bp->origT[1] = bp->origS[1] + f*(bp->origE[1] - bp->origS[1]);
+ bp->origT[2] = bp->origS[2] + f*(bp->origE[2] - bp->origS[2]);
+ if (bp->goal >= SOFTGOALSNAP){
+ bp->vec[0] = bp->origE[0] - bp->origS[0];
+ bp->vec[1] = bp->origE[1] - bp->origS[1];
+ bp->vec[2] = bp->origE[2] - bp->origS[2];
}
+ }
+
+ if(ob->softflag & OB_SB_EDGES) {
/* hrms .. do springs alter their lenght ?
- if(medge) {
bs= ob->soft->bspring;
bp= ob->soft->bpoint;
- for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, medge++, bs++) {
- bs->len= VecLenf( (bp+bs->v1)->origT, (bp+bs->v2)->origT);
- }
+ for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, bs++) {
+ bs->len= VecLenf( (bp+bs->v1)->origT, (bp+bs->v2)->origT);
}
*/
- }
+ }
}
/* ************ convertors ********** */
+/* for each object type we need;
+ - xxxx_to_softbody(Object *ob) : a full (new) copy
+ - xxxx_update_softbody(Object *ob) : update refreshes current positions
+ - softbody_to_xxxx(Object *ob) : after simulation, copy vertex locations back
+*/
+
+static int object_has_edges(Object *ob)
+{
+ if(ob->type==OB_MESH) {
+ Mesh *me= ob->data;
+ if(me->medge) return 1;
+ }
+ else if(ob->type==OB_LATTICE) {
+ ;
+ }
+
+ return 0;
+}
+
+
/* copy original (new) situation in softbody, as result of matrices or deform */
+/* is assumed to enter function with ob->soft, but can be without points */
static void mesh_update_softbody(Object *ob)
{
Mesh *me= ob->data;
@@ -596,7 +610,11 @@ static void mesh_update_softbody(Object *ob)
/* MEdge *medge= me->medge; */ /*unused*/
BodyPoint *bp;
int a;
- if(ob->soft) {
+
+ /* possible after a file read... */
+ if(ob->soft->totpoint!=me->totvert) sbObjectToSoftbody(ob);
+
+ if(me->totvert) {
bp= ob->soft->bpoint;
for(a=0; a<me->totvert; a++, mvert++, bp++) {
@@ -605,30 +623,39 @@ static void mesh_update_softbody(Object *ob)
Mat4MulVecfl(ob->obmat, bp->origE);
VECCOPY(bp->origT, bp->origE);
}
- /* hrms .. do springs alter their lenght ?
- if(medge) {
- bs= ob->soft->bspring;
- bp= ob->soft->bpoint;
- for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, medge++, bs++) {
- bs->len= VecLenf( (bp+bs->v1)->origE, (bp+bs->v2)->origE);
+
+ if(ob->softflag & OB_SB_EDGES) {
+
+ /* happens when in UI edges was set */
+ if(ob->soft->bspring==NULL)
+ if(object_has_edges(ob)) sbObjectToSoftbody(ob);
+
+ /* hrms .. do springs alter their lenght ?
+ if(medge) {
+ bs= ob->soft->bspring;
+ bp= ob->soft->bpoint;
+ for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, medge++, bs++) {
+ bs->len= VecLenf( (bp+bs->v1)->origE, (bp+bs->v2)->origE);
+ }
}
+ */
}
- */
}
}
-int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target)
+static int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float *target)
/* result 0 on success, else indicates error number
-- kind of *inverse* result defintion,
-- but this way we can signal error condition to caller
-- and yes this function must not be here but in a *vertex group module*
*/
{
- int i,groupindex;
bDeformGroup *locGroup = NULL;
MDeformVert *dv;
+ int i, groupindex;
+
locGroup = get_named_vertexgroup(ob,name);
if(locGroup){
/* retrieve index for that group */
@@ -654,61 +681,65 @@ int get_scalar_from_named_vertexgroup(Object *ob, char *name, int vertID, float
/* makes totally fresh start situation */
static void mesh_to_softbody(Object *ob)
{
+ SoftBody *sb;
Mesh *me= ob->data;
MVert *mvert= me->mvert;
MEdge *medge= me->medge;
-/* MFace *mface= me->mface; */ /*unused*/
BodyPoint *bp;
BodySpring *bs;
int a;
- ob->soft= new_softbody(me->totvert, me->totedge);
- if(ob->soft) {
- bp= ob->soft->bpoint;
- for(a=me->totvert; a>0; a--, mvert++, bp++) {
- VECCOPY(bp->pos, mvert->co);
- Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords
- VECCOPY(bp->origS, bp->pos);
- VECCOPY(bp->origE, bp->pos);
- VECCOPY(bp->origT, bp->pos);
- bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0;
- bp->weight= 1.0;
- bp->goal= 0.5;
- bp->nofsprings=0;
- bp->springs=NULL;
- if (1) { /* switch to vg scalars*/
- /* get scalar values needed *per vertex* from vertex group functions,
- so we can *paint* them nicly ..
- they are normalized [0.0..1.0] so may be we need amplitude for scale
- which can be done by caller
- but still .. i'd like it to go this way
- */
- int error;
- char name[32] = "SOFTGOAL";
- float temp;
- error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
- if (!error) bp->goal = temp;
- if (bp->goal < ob->sb_mingoal) bp->goal = ob->sb_mingoal;
- if (bp->goal > ob->sb_maxgoal) bp->goal = ob->sb_maxgoal;
- /* a little ad hoc changing the goal control to be less *sharp* */
- bp->goal = (float)pow(bp->goal,4.0f);
-/* to proove the concept
-this would enable per vertex *mass painting*
- strcpy(name,"SOFTMASS");
- error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
- if (!error) bp->mass = temp * ob->rangeofmass;
-*/
-
+ /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
+ renew_softbody(ob, me->totvert, me->totedge);
+
+ /* we always make body points */
+ sb= ob->soft;
+ bp= sb->bpoint;
+ for(a=me->totvert; a>0; a--, mvert++, bp++) {
+ VECCOPY(bp->pos, mvert->co);
+ Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords
+ VECCOPY(bp->origS, bp->pos);
+ VECCOPY(bp->origE, bp->pos);
+ VECCOPY(bp->origT, bp->pos);
+ bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0;
+ bp->weight= 1.0;
+ bp->goal= 0.5;
+ bp->nofsprings=0;
+ bp->springs=NULL;
+ if (1) { /* switch to vg scalars*/
+ /* get scalar values needed *per vertex* from vertex group functions,
+ so we can *paint* them nicly ..
+ they are normalized [0.0..1.0] so may be we need amplitude for scale
+ which can be done by caller
+ but still .. i'd like it to go this way
+ */
+ int error;
+ char name[32] = "SOFTGOAL";
+ float temp;
+
+ error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
+ if (!error) bp->goal = temp;
+ if (bp->goal < sb->mingoal) bp->goal = sb->mingoal;
+ if (bp->goal > sb->maxgoal) bp->goal = sb->maxgoal;
+ /* a little ad hoc changing the goal control to be less *sharp* */
+ bp->goal = (float)pow(bp->goal,4.0f);
+ /* to proove the concept
+ this would enable per vertex *mass painting*
+ strcpy(name,"SOFTMASS");
+ error = get_scalar_from_named_vertexgroup(ob,name,me->totvert - a,&temp);
+ if (!error) bp->mass = temp * ob->rangeofmass;
+ */
- } /* switch to vg scalars */
- }
-
+ } /* switch to vg scalars */
+ }
+ /* but we only optionally add body edge springs */
+ if (ob->softflag & OB_SB_EDGES) {
if(medge) {
- bs= ob->soft->bspring;
- bp= ob->soft->bpoint;
+ bs= sb->bspring;
+ bp= sb->bpoint;
for(a=me->totedge; a>0; a--, medge++, bs++) {
bs->v1= medge->v1;
bs->v2= medge->v2;
@@ -718,44 +749,11 @@ this would enable per vertex *mass painting*
}
/* insert *diagonal* springs in quads if desired */
- if (ob->softflag & 0x02) {
- add_quad_diag_springs(ob);
-
+ if (ob->softflag & OB_SB_QUADS) {
+ add_mesh_quad_diag_springs(ob);
}
build_bps_springlist(ob); /* big mesh optimization */
-
- /* vertex colors are abused as weights here, however they're stored in faces... uhh */
- /* naah .. we don't do it any more bjornmose :-)
- if(mface && me->mcol) {
- char *mcol= (char *)me->mcol;
- for(a=me->totface; a>0; a--, mface++, mcol+=16) {
- bp= ob->soft->bpoint+mface->v1;
- if(bp->goal==0.5) {
- bp->goal= ( (float)( (mcol + 0)[1] ) )/255.0;
- }
- bp= ob->soft->bpoint+mface->v2;
- if(bp->goal==0.5) {
- bp->goal= ( (float)( (mcol + 4)[1] ) )/255.0;
- }
- bp= ob->soft->bpoint+mface->v3;
- if(bp->goal==0.5) {
- bp->goal= ( (float)( (mcol + 8)[1]) )/255.0;
- }
- if(mface->v4) {
- bp= ob->soft->bpoint+mface->v4;
- if(bp->goal==0.5) {
- bp->goal= ( (float)( (mcol + 12)[1]) )/255.0;
- }
- }
- }
- }
- */
- bp= ob->soft->bpoint;
- for(a=me->totvert; a>0; a--, bp++) {
- //printf("a %d goal %f\n", a, bp->goal);
- }
-
}
}
@@ -790,142 +788,174 @@ static void softbody_to_lattice(Object *ob)
}
-
-
-/* ************ Object level, exported functions *************** */
+/* copies softbody result back in object */
+/* only used in sbObjectStep() */
+static void softbody_to_object(Object *ob)
+{
+
+ if(ob->soft==NULL) return;
+
+ switch(ob->type) {
+ case OB_MESH:
+ softbody_to_mesh(ob);
+ break;
+ case OB_LATTICE:
+ softbody_to_lattice(ob);
+ break;
+ }
+}
/* copy original (new) situation in softbody, as result of matrices or deform */
-void object_update_softbody(Object *ob)
+/* used in sbObjectStep() and sbObjectReset() */
+/* assumes to have ob->soft, but can be entered without points */
+static void object_update_softbody(Object *ob)
{
+
switch(ob->type) {
- case OB_MESH:
- mesh_update_softbody(ob);
- break;
- case OB_LATTICE:
- //lattice_update_softbody(ob);
- break;
+ case OB_MESH:
+ mesh_update_softbody(ob);
+ break;
+ case OB_LATTICE:
+ //lattice_update_softbody(ob);
+ break;
}
+
+}
+
+
+
+/* ************ Object level, exported functions *************** */
+/* allocates and initializes general main data */
+SoftBody *sbNew(void)
+{
+ SoftBody *sb;
+
+ sb= MEM_callocN(sizeof(SoftBody), "softbody");
+
+ sb->mediafrict= 1.0;
+ sb->nodemass= 1.0;
+ sb->grav= 0.0;
+
+ sb->goalspring= 1.0;
+ sb->goalfrict= 1.0;
+ sb->mingoal= 0.0;
+ sb->maxgoal= 1.0;
+
+ sb->inspring= 1.0;
+ sb->infrict= 1.0;
+
+ return sb;
+}
+
+/* frees all */
+void sbFree(SoftBody *sb)
+{
+ free_softbody_intern(sb);
+ MEM_freeN(sb);
}
+
/* makes totally fresh start situation */
-void object_to_softbody(Object *ob,float ctime)
+void sbObjectToSoftbody(Object *ob)
{
- if(ob->soft) free_softbody(ob->soft);
- ob->soft= NULL;
-
switch(ob->type) {
case OB_MESH:
mesh_to_softbody(ob);
- ob->soft->ctime = ctime;
break;
case OB_LATTICE:
lattice_to_softbody(ob);
break;
}
+
+ if(ob->soft) ob->soft->ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
}
-/* copies softbody result back in object */
-void softbody_to_object(Object *ob)
+/* reset all motion */
+void sbObjectReset(Object *ob)
{
-
- if(ob->soft==NULL) return;
+ SoftBody *sb= ob->soft;
+ BodyPoint *bp;
+ int a;
- switch(ob->type) {
- case OB_MESH:
- softbody_to_mesh(ob);
- break;
- case OB_LATTICE:
- softbody_to_lattice(ob);
- break;
+ if(sb==NULL) return;
+ sb->ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
+
+ object_update_softbody(ob);
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ // origS is previous timestep
+ VECCOPY(bp->origS, bp->origE);
+ VECCOPY(bp->pos, bp->origE);
+ bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f;
+ // no idea about the Heun stuff! (ton)
}
}
-/* simulates one step. ctime is in frames not seconds */
-
-void object_softbody_step(Object *ob, float ctime)
+/* simulates one step. framenr is in frames */
+/* copies result back to object, displist */
+void sbObjectStep(Object *ob, float framenr)
{
+ SoftBody *sb;
float dtime;
int timescale,t;
- float forcetime;
+ float ctime, forcetime;
float err;
- /* this is a NO! NO!
- ==========================
- if(ob->soft==NULL) {
- object_to_softbody(ob);
- if(ob->soft==NULL) return;
- ob->soft->ctime= ctime;
- }
- // you can't create a soft object on the fly
- // 1. inner spings need a *default* length for crinkles/wrinkles,
- // surface area and volume preservation
- // 2. initial conditions for velocities and positions need to be defined
- // for a certain point of time .. say t0
- // 3. and since we have friction and *outer* movement
- // the history of the *outer* movements will affect where we end up
- // sooo atm going to edit mode and back ( back calls object_to_softbody(ob,1.0f)
- is the only way to create softbody data
- */
-
- /* first attempt to set initial conditions for softbodies
- rules
- 1. ODE solving is disabled / via button in 3dview header /otherways do regular softbody stuff
- 2. set SB positions to *goal*
- 3. set SB velocities to match *goal* movement
-
- */
- if (SB_ENABLE == 0){
- if(ob->soft==NULL) {
- return; /* nothing to do */
- }
- object_update_softbody(ob);
- ob->soft->ctime= ctime;
- interpolate_exciter(ob,200,200);
- softbody_force_goal(ob);
- softbody_to_object(ob);
- return; /* no dynamics wanted */
-
- }
-
- if(ob->soft==NULL) {
- /* aye no soft object created bail out here */
- printf("Softbody Zombie \n");
+ /* just to be nice we allow full init */
+ if(ob->soft==NULL) sbObjectToSoftbody(ob);
+ /* this is after reading new file, or acceptable as signal to refresh */
+ else if(ob->soft->totpoint==0) sbObjectToSoftbody(ob);
+
+ sb= ob->soft;
+
+ /* still no points? go away */
+ if(sb->totpoint==0) return;
+
+ /* checking time: */
+ ctime= bsystem_time(ob, NULL, framenr, 0.0);
+ softbody_scale_time(steptime); // translate frames/sec and lenghts unit to SI system
+ dtime= ctime - sb->ctime;
+ // dtime= ABS(dtime); no no we want to go back in time with IPOs
+ timescale = (int)(sb->rklimit * ABS(dtime));
+ // bail out for negative or for large steps
+ if(dtime<0.0 || dtime >= 9.9*G.scene->r.framelen) {
+ sbObjectReset(ob);
return;
}
- softbody_scale_time(steptime); // translate frames/sec and lenghts unit to SI system
- dtime= ctime - ob->soft->ctime;
- // dtime= ABS(dtime); no no we want to go back in time with IPOs
- timescale = (int)(ob->softtime * ABS(dtime));
- if(ABS(dtime) > 0.0) {
+ /* the simulator */
+
+ if(ABS(dtime) > 0.0) { // note: what does this mean now? (ton)
+
object_update_softbody(ob);
- if (ob->softflag & 0x04){
+
+ if (TRUE) { // RSOL1 always true now (ton)
/* special case of 2nd order Runge-Kutta type AKA Heun */
float timedone =0.0;
/* counter for emergency brake
* we don't want to lock up the system if physics fail
*/
int loops =0 ;
- SoftHeunTol = ob->softtime; // humm .. this should be calculated from sb parameters and sizes
+ SoftHeunTol = sb->rklimit; // humm .. this should be calculated from sb parameters and sizes
forcetime = dtime; /* hope for integrating in one step */
while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) )
{
if (ABS(dtime) > 3.0 ){
- printf("SB_STEPSIZE \n");
+ if(G.f & G_DEBUG) printf("SB_STEPSIZE \n");
break; // sorry but i must assume goal movement can't be interpolated any more
}
//set goals in time
interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
// do predictive euler step
- softbody_calc_forces(ob,forcetime);
- softbody_apply_forces(ob,forcetime,1, NULL);
+ softbody_calc_forces(ob, forcetime);
+ softbody_apply_forces(ob, forcetime, 1, NULL);
// crop new slope values to do averaged slope step
- softbody_calc_forces(ob,forcetime);
- softbody_apply_forces(ob,forcetime,2, &err);
+ softbody_calc_forces(ob, forcetime);
+ softbody_apply_forces(ob, forcetime, 2, &err);
softbody_apply_goalsnap(ob);
if (err > SoftHeunTol){ // error needs to be scaled to some quantity
@@ -933,24 +963,27 @@ void object_softbody_step(Object *ob, float ctime)
forcetime /= 2.0;
}
else {
-
float newtime = forcetime * 1.1f; // hope for 1.1 times better conditions in next step
+
if (err > SoftHeunTol/2.0){ // stay with this stepsize unless err really small
newtime = forcetime;
}
timedone += forcetime;
if (forcetime > 0.0)
- forcetime = MIN2(dtime - timedone,newtime);
+ forcetime = MIN2(dtime - timedone,newtime);
else
- forcetime = MAX2(dtime - timedone,newtime);
+ forcetime = MAX2(dtime - timedone,newtime);
}
loops++;
}
// move snapped to final position
- interpolate_exciter(ob,2,2);
+ interpolate_exciter(ob, 2, 2);
softbody_apply_goalsnap(ob);
- if (loops > HEUNWARNLIMIT) /* monitor high loop counts say 1000 after testing */
- printf("%d heun integration loops/frame \n",loops);
+
+ if(G.f & G_DEBUG) {
+ if (loops > HEUNWARNLIMIT) /* monitor high loop counts say 1000 after testing */
+ printf("%d heun integration loops/frame \n",loops);
+ }
}
else
/* do brute force explicit euler */
@@ -965,44 +998,42 @@ void object_softbody_step(Object *ob, float ctime)
/* the *goal* mesh must use the n*h timing too !
use *cheap* linear intepolation for that */
interpolate_exciter(ob,timescale,t);
- if (timescale > 0 )
- {
- forcetime = dtime/timescale;
-
- /* does not fit the concept sloving ODEs :) */
- /* softbody_apply_goal(ob,forcetime ); */
-
- /* explicit Euler integration */
- /* we are not controling a nuclear power plant!
- so rought *almost* physical behaviour is acceptable.
- in cases of *mild* stiffnes cranking up timscale -> decreasing stepsize *h*
- avoids instability */
- softbody_calc_forces(ob,forcetime);
- softbody_apply_forces(ob,forcetime,0, NULL);
- softbody_apply_goalsnap(ob);
-
+ if (timescale > 0 ) {
+ forcetime = dtime/timescale;
+
+ /* does not fit the concept sloving ODEs :) */
+ /* softbody_apply_goal(ob,forcetime ); */
+
+ /* explicit Euler integration */
+ /* we are not controling a nuclear power plant!
+ so rought *almost* physical behaviour is acceptable.
+ in cases of *mild* stiffnes cranking up timscale -> decreasing stepsize *h*
+ avoids instability */
+ softbody_calc_forces(ob,forcetime);
+ softbody_apply_forces(ob,forcetime,0, NULL);
+ softbody_apply_goalsnap(ob);
-// if (0){
- /* ok here comes the überhammer
- use a semi implicit euler integration to tackle *all* stiff conditions
- but i doubt the cost/benifit holds for most of the cases
- -- to be coded*/
-// }
-
+ // if (0){
+ /* ok here comes the überhammer
+ use a semi implicit euler integration to tackle *all* stiff conditions
+ but i doubt the cost/benifit holds for most of the cases
+ -- to be coded*/
+ // }
+
}
}
/* and apply to vertices */
softbody_to_object(ob);
- ob->soft->ctime= ctime;
+ sb->ctime= ctime;
} // if(ABS(dtime) > 0.0)
else {
- // rule : you have asked for the current state of the softobject
- // since dtime= ctime - ob->soft->ctime;
- // and we were not notifified about any other time changes
- // so here it is !
- softbody_to_object(ob);
+ // rule : you have asked for the current state of the softobject
+ // since dtime= ctime - ob->soft->ctime;
+ // and we were not notifified about any other time changes
+ // so here it is !
+ softbody_to_object(ob);
}
}