diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-11-27 01:09:57 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-11-27 01:09:57 +0300 |
commit | 7da56f4a9ba0bdd0cdcd40b8ca6e69d776d26abe (patch) | |
tree | 663c13aae5606937571ac1e7a4c77ca2866e75dd /source/blender/blenkernel/intern/softbody.c | |
parent | 121dab1bcd9467bd8e11d0a82e83a1621758fd8e (diff) | |
parent | 770291b9ea1ec03d98b6bae4fd2a2d3f0091be41 (diff) |
Particles
=========
Merge of the famous particle patch by Janne Karhu, a full rewrite
of the Blender particle system. This includes:
- Emitter, Hair and Reactor particle types.
- Newtonian, Keyed and Boids physics.
- Various particle visualisation and rendering types.
- Vertex group and texture control for various properties.
- Interpolated child particles from parents.
- Hair editing with combing, growing, cutting, .. .
- Explode modifier.
- Harmonic, Magnetic fields, and multiple falloff types.
.. and lots of other things, some more info is here:
http://wiki.blender.org/index.php/BlenderDev/Particles_Rewrite
http://wiki.blender.org/index.php/BlenderDev/Particles_Rewrite_Doc
The new particle system cannot be backwards compatible. Old particle
systems are being converted to the new system, but will require
tweaking to get them looking the same as before.
Point Cache
===========
The new system to replace manual baking, based on automatic caching
on disk. This is currently used by softbodies and the particle system.
See the Cache API section on:
http://wiki.blender.org/index.php/BlenderDev/PhysicsSprint
Documentation
=============
These new features still need good docs for the release logs, help
for this is appreciated.
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 453 |
1 files changed, 293 insertions, 160 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 36d114cf023..bd9d1cb75ca 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -61,9 +61,11 @@ variables on the UI for now #include "DNA_curve_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" /* here is the softbody struct */ +#include "DNA_particle_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "DNA_lattice_types.h" #include "DNA_scene_types.h" @@ -75,9 +77,12 @@ variables on the UI for now #include "BKE_global.h" #include "BKE_key.h" #include "BKE_object.h" +#include "BKE_particle.h" #include "BKE_softbody.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" +#include "BKE_pointcache.h" +#include "BKE_modifier.h" #include "BIF_editdeform.h" #include "BIF_graphics.h" @@ -90,18 +95,6 @@ static int (*SB_localInterruptCallBack)(void) = NULL; /* ********** soft body engine ******* */ - -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 */ - int nofsprings; int *springs; - float choke; - float colball; - short flag; - char octantflag; -} BodyPoint; - typedef struct BodySpring { int v1, v2; float len, strength, cf; @@ -480,21 +473,31 @@ void ccd_build_deflector_hache(Object *vertexowner,GHash *hash) while (base) { /*Only proceed for mesh object in same layer */ if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) { + int particles=0; ob= base->object; - if((vertexowner) && (ob == vertexowner)){ - /* if vertexowner is given we don't want to check collision with owner object */ - base = base->next; - continue; + if((vertexowner) && (ob == vertexowner)) { + if(vertexowner->soft->particles){ + particles=1; + } + else { + /* if vertexowner is given we don't want to check collision with owner object */ + base = base->next; + continue; + } } /*+++ only with deflecting set */ if(ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == 0) { DerivedMesh *dm= NULL; - - if(ob->softflag & OB_SB_COLLFINAL) { /* so maybe someone wants overkill to collide with subsurfed */ - dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); - } else { - dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); + + if(particles) { + dm = psys_get_modifier(ob,psys_get_current(ob))->dm; + } + else { + if(ob->softflag & OB_SB_COLLFINAL) /* so maybe someone wants overkill to collide with subsurfed */ + dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); + else + dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); } if(dm){ @@ -852,10 +855,11 @@ static void renew_softbody(Object *ob, int totpoint, int totspring) { SoftBody *sb; int i; - + short softflag; if(ob->soft==NULL) ob->soft= sbNew(); else free_softbody_intern(ob->soft); sb= ob->soft; + softflag=ob->softflag; if(totpoint) { sb->totpoint= totpoint; @@ -869,8 +873,8 @@ static void renew_softbody(Object *ob, int totpoint, int totspring) for (i=0; i<totpoint; i++) { BodyPoint *bp = &sb->bpoint[i]; - if(ob->softflag & OB_SB_GOAL) { - bp->goal= ob->soft->defgoal; + if(softflag & OB_SB_GOAL) { + bp->goal= sb->defgoal; } else { bp->goal= 0.0f; @@ -900,7 +904,6 @@ static void free_softbody_baked(SoftBody *sb) sb->keys= NULL; sb->totkey= 0; - } static void free_scratch(SoftBody *sb) { @@ -1203,9 +1206,9 @@ int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_ Crossf(d_nvect, edge2, edge1); Normalize(d_nvect); if ( - LineIntersectsTriangle(nv1, nv2, face_v1, face_v2, face_v3, &t) || - LineIntersectsTriangle(nv2, nv3, face_v1, face_v2, face_v3, &t) || - LineIntersectsTriangle(nv3, nv1, face_v1, face_v2, face_v3, &t) ){ + LineIntersectsTriangle(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) || + LineIntersectsTriangle(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) || + LineIntersectsTriangle(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) ){ Vec3PlusStVec(force,-1.0f,d_nvect); *damp=ob->pd->pdef_sbdamp; deflected = 2; @@ -1217,9 +1220,9 @@ int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_ Crossf(d_nvect, edge2, edge1); Normalize(d_nvect); if ( - LineIntersectsTriangle(nv1, nv3, face_v1, face_v2, face_v3, &t) || - LineIntersectsTriangle(nv3, nv4, face_v1, face_v2, face_v3, &t) || - LineIntersectsTriangle(nv4, nv1, face_v1, face_v2, face_v3, &t) ){ + LineIntersectsTriangle(nv1, nv3, face_v1, face_v2, face_v3, &t, NULL) || + LineIntersectsTriangle(nv3, nv4, face_v1, face_v2, face_v3, &t, NULL) || + LineIntersectsTriangle(nv4, nv1, face_v1, face_v2, face_v3, &t, NULL) ){ Vec3PlusStVec(force,-1.0f,d_nvect); *damp=ob->pd->pdef_sbdamp; deflected = 2; @@ -1402,7 +1405,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp Crossf(d_nvect, edge2, edge1); Normalize(d_nvect); - if ( LineIntersectsTriangle(edge_v1, edge_v2, nv1, nv2, nv3, &t)){ + if ( LineIntersectsTriangle(edge_v1, edge_v2, nv1, nv2, nv3, &t, NULL)){ float v1[3],v2[3]; float intrusiondepth,i1,i2; VECSUB(v1, edge_v1, nv2); @@ -1421,7 +1424,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp Crossf(d_nvect, edge2, edge1); Normalize(d_nvect); - if (LineIntersectsTriangle( edge_v1, edge_v2,nv1, nv3, nv4, &t)){ + if (LineIntersectsTriangle( edge_v1, edge_v2,nv1, nv3, nv4, &t, NULL)){ float v1[3],v2[3]; float intrusiondepth,i1,i2; VECSUB(v1, edge_v1, nv4); @@ -1550,7 +1553,7 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float * Object *ob= NULL; GHash *hash; GHashIterator *ihash; - float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3], + float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3]={0.0,0.0,0.0}, vv1[3], vv2[3], vv3[3], vv4[3], coledge[3], mindistedge = 1000.0f, outerforceaccu[3],innerforceaccu[3], facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz, @@ -2953,6 +2956,103 @@ static void curve_surf_to_softbody(Object *ob) } +static void springs_from_particles(Object *ob) +{ + ParticleSystem *psys; + ParticleSystemModifierData *psmd=0; + ParticleData *pa=0; + HairKey *key=0; + SoftBody *sb; + BodyPoint *bp; + BodySpring *bs; + int a,k; + float hairmat[4][4]; + + psys= ob->soft->particles; + sb= ob->soft; + if(ob && sb && psys) { + psmd = psys_get_modifier(ob, psys); + + bp= sb->bpoint; + for(a=0, pa=psys->particles; a<psys->totpart; a++, pa++) { + for(k=0, key=pa->hair; k<pa->totkey; k++, bp++, key++) { + VECCOPY(bp->origS, key->co); + + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + + Mat4MulVecfl(hairmat, bp->origS); + } + } + + for(a=0, bs=sb->bspring; a<sb->totspring; a++, bs++) + bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS); + } +} + +static void particles_to_softbody(Object *ob) +{ + SoftBody *sb; + BodyPoint *bp; + BodySpring *bs; + ParticleData *pa; + HairKey *key; + ParticleSystem *psys= ob->soft->particles; + float goalfac; + int a, k, curpoint; + int totpoint= psys_count_keys(psys); + int totedge= totpoint-psys->totpart; + + /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */ + renew_softbody(ob, totpoint, totedge); + + psys->particles->bpi = 0; + for(a=1, pa=psys->particles+1; a<psys->totpart; a++, pa++) + pa->bpi = (pa-1)->bpi + pa->totkey; + + /* we always make body points */ + sb= ob->soft; + bp= sb->bpoint; + bs= sb->bspring; + goalfac= ABS(sb->maxgoal - sb->mingoal); + + if((ob->softflag & OB_SB_GOAL)) { + for(a=0, pa=psys->particles; a<psys->totpart; a++, pa++) { + for(k=0, key=pa->hair; k<pa->totkey; k++,bp++,key++) { + if(k) { + bp->goal= key->weight; + bp->goal= sb->mingoal + bp->goal*goalfac; + bp->goal= (float)pow(bp->goal, 4.0f); + } + else{ + /* hair roots are allways fixed fully to goal */ + bp->goal= 1.0f; + } + } + } + } + + bp= sb->bpoint; + curpoint=0; + for(a=0, pa=psys->particles; a<psys->totpart; a++, curpoint++, pa++) { + for(k=0; k<pa->totkey-1; k++,bs++,curpoint++) { + bs->v1=curpoint; + bs->v2=curpoint+1; + bs->strength= 1.0; + bs->order=1; + } + } + + build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */ + /* insert *other second order* springs if desired */ + if(sb->secondspring > 0.0000001f) { + add_2nd_order_springs(ob,sb->secondspring*10.0); /* exploits the the first run of build_bps_springlist(ob);*/ + build_bps_springlist(ob); /* yes we need to do it again*/ + } + springs_from_particles(ob); /* write the 'rest'-lenght of the springs */ + if(ob->softflag & OB_SB_SELF) + calculate_collision_balls(ob); +} + /* copies softbody result back in object */ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, int local) { @@ -2969,117 +3069,94 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, } } -/* return 1 if succesfully baked and applied step */ -static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3], int numVerts) +void softbody_clear_cache(Object *ob, float framenr) { - SoftBody *sb= ob->soft; - SBVertex *key0, *key1, *key2, *key3; - BodyPoint *bp; - float data[4], sfra, efra, cfra, dfra, fac; /* start, end, current, delta */ - int ofs1, a; - - /* precondition check */ - if(sb==NULL || sb->keys==NULL || sb->totkey==0) return 0; - /* so we got keys, but no bodypoints... even without simul we need it for the bake */ - if(sb->bpoint==NULL) sb->bpoint= MEM_callocN( sb->totpoint*sizeof(BodyPoint), "bodypoint"); - - /* convert cfra time to system time */ - sfra= (float)sb->sfra; - cfra= bsystem_time(ob, framenr, 0.0); - efra= (float)sb->efra; - dfra= (float)sb->interval; + SoftBody *sb = ob->soft; + ModifierData *md = ob->modifiers.first; + int stack_index = -1; + int a; - /* offset in keys array */ - ofs1= (int)floor( (cfra-sfra)/dfra ); + if(sb==NULL) return; - if(ofs1 < 0) { - key0=key1=key2=key3= *sb->keys; - } - else if(ofs1 >= sb->totkey-1) { - key0=key1=key2=key3= *(sb->keys+sb->totkey-1); - } + if(sb->particles) + stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles)); else { - key1= *(sb->keys+ofs1); - key2= *(sb->keys+ofs1+1); - - if(ofs1>0) key0= *(sb->keys+ofs1-1); - else key0= key1; - - if(ofs1<sb->totkey-2) key3= *(sb->keys+ofs1+2); - else key3= key2; - } - - sb->ctime= cfra; /* needed? */ - - /* timing */ - fac= ((cfra-sfra)/dfra) - (float)ofs1; - CLAMP(fac, 0.0, 1.0); - set_four_ipo(fac, data, KEY_BSPLINE); - if (key0&&key1&&key2&&key3) // may be null because we SHIFT_ESCAPED - for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++, key0++, key1++, key2++, key3++) { - bp->pos[0]= data[0]*key0->vec[0] + data[1]*key1->vec[0] + data[2]*key2->vec[0] + data[3]*key3->vec[0]; - bp->pos[1]= data[0]*key0->vec[1] + data[1]*key1->vec[1] + data[2]*key2->vec[1] + data[3]*key3->vec[1]; - bp->pos[2]= data[0]*key0->vec[2] + data[1]*key1->vec[2] + data[2]*key2->vec[2] + data[3]*key3->vec[2]; + for(a=0; md; md=md->next, a++) { + if(md->type == eModifierType_Softbody) { + stack_index = a; + break; + } + } } - - softbody_to_object(ob, vertexCos, numVerts, sb->local); - - return 1; -} -/* only gets called after succesfully doing softbody_step */ -/* already checked for OB_SB_BAKE flag */ -static void softbody_baked_add(Object *ob, float framenr) + BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_ALL, framenr, stack_index); +} +static void softbody_write_cache(Object *ob, float framenr) { - SoftBody *sb= ob->soft; - SBVertex *key; + FILE *fp = NULL; + SoftBody *sb = ob->soft; BodyPoint *bp; - float sfra, efra, cfra, dfra, fac1; /* start, end, current, delta */ - int ofs1, a; - - /* convert cfra time to system time */ - sfra= (float)sb->sfra; - fac1= ob->sf; ob->sf= 0.0f; /* disable startframe */ - cfra= bsystem_time(ob, framenr, 0.0); - ob->sf= fac1; - efra= (float)sb->efra; - dfra= (float)sb->interval; - - if(sb->totkey==0) { - if(sb->sfra >= sb->efra) return; /* safety, UI or py setting allows */ - if(sb->interval<1) sb->interval= 1; /* just be sure */ - - sb->totkey= 1 + (int)(ceil( (efra-sfra)/dfra ) ); - sb->keys= MEM_callocN( sizeof(void *)*sb->totkey, "sb keys"); + ModifierData *md = ob->modifiers.first; + int stack_index = -1; + int a; + + if(sb->totpoint == 0) return; + + if(sb->particles) + stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles)); + else { + for(a=0; md; md=md->next, a++) { + if(md->type == eModifierType_Softbody) { + stack_index = a; + break; + } + } } + + fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); + if(!fp) return; + + for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) + fwrite(&bp->pos, sizeof(float), 3, fp); - /* inverse matrix might not be uptodate... */ - Mat4Invert(ob->imat, ob->obmat); - - /* now find out if we have to store a key */ - - /* offset in keys array */ - if(cfra>=(efra)) { - ofs1= sb->totkey-1; - fac1= 0.0; - } + fclose(fp); +} +static int softbody_read_cache(Object *ob, float framenr) +{ + FILE *fp = NULL; + SoftBody *sb = ob->soft; + BodyPoint *bp; + ModifierData *md = ob->modifiers.first; + int stack_index = -1; + int a, ret = 1; + + if(sb->totpoint == 0) return 0; + + if(sb->particles) + stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles)); else { - ofs1= (int)floor( (cfra-sfra)/dfra ); - fac1= ((cfra-sfra)/dfra) - (float)ofs1; - } - if( fac1 < 1.0/dfra ) { - - key= *(sb->keys+ofs1); - if(key == NULL) { - *(sb->keys+ofs1)= key= MEM_mallocN(sb->totpoint*sizeof(SBVertex), "softbody key"); - - for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++, key++) { - VECCOPY(key->vec, bp->pos); - if(sb->local) - Mat4MulVecfl(ob->imat, key->vec); + for(a=0; md; md=md->next, a++) { + if(md->type == eModifierType_Softbody) { + stack_index = a; + break; } } } + + fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index); + if(!fp) + ret = 0; + else { + for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) + if(fread(&bp->pos, sizeof(float), 3, fp) != 3) { + ret = 0; + break; + } + + fclose(fp); + } + + return ret; } /* +++ ************ maintaining scratch *************** */ void sb_new_scratch(SoftBody *sb) @@ -3175,15 +3252,14 @@ void sbSetInterruptCallBack(int (*f)(void)) /* simulates one step. framenr is in frames */ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts) { + ParticleSystemModifierData *psmd=0; + ParticleData *pa=0; SoftBody *sb; + HairKey *key= NULL; BodyPoint *bp; int a; float dtime,ctime,forcetime,err; - - /* baking works with global time */ - if(!(ob->softflag & OB_SB_BAKEDO) ) - if(softbody_baked_step(ob, framenr, vertexCos, numVerts) ) return; - + float hairmat[4][4]; /* This part only sets goals and springs, based on original mesh/curve/lattice data. Copying coordinates happens in next chunk by setting softbody flag OB_SB_RESET */ @@ -3194,7 +3270,13 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts (numVerts!=ob->soft->totpoint) || /* should never happen, just to be safe */ ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) /* happens when in UI edges was set */ { - switch(ob->type) { + if(ob->soft && ob->soft->bpoint) /* don't clear on file load */ + softbody_clear_cache(ob, framenr); + + if(ob->soft->particles){ + particles_to_softbody(ob); + } + else switch(ob->type) { case OB_MESH: mesh_to_softbody(ob); break; @@ -3220,6 +3302,10 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts /* still no points? go away */ if(sb->totpoint==0) return; + if(sb->particles){ + psmd=psys_get_modifier(ob,sb->particles); + pa=sb->particles->particles; + } /* checking time: */ @@ -3231,17 +3317,45 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts dtime= ctime - sb->ctime; } + if(softbody_read_cache(ob, framenr)) { + if(sb->particles==0) + softbody_to_object(ob, vertexCos, numVerts, sb->local); + sb->ctime = ctime; + return; + } + /* the simulator */ /* update the vertex locations */ if (dtime!=0.0) { + if(sb->particles) { + pa=sb->particles->particles; + key = pa->hair; + + psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); + } + for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) { /* store where goals are now */ VECCOPY(bp->origS, bp->origE); /* copy the position of the goals at desired end time */ - VECCOPY(bp->origE, vertexCos[a]); - /* vertexCos came from local world, go global */ - Mat4MulVecfl(ob->obmat, bp->origE); + if(sb->particles) { + if(key == pa->hair + pa->totkey) { + pa++; + key = pa->hair; + + psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); + } + VECCOPY(bp->origE, key->co); + Mat4MulVecfl(hairmat,bp->origE); + + key++; + } + else{ + VECCOPY(bp->origE, vertexCos[a]); + /* vertexCos came from local world, go global */ + Mat4MulVecfl(ob->obmat, bp->origE); + } /* just to be save give bp->origT a defined value will be calulated in interpolate_exciter()*/ VECCOPY(bp->origT, bp->origE); @@ -3253,9 +3367,29 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts (dtime>=9.9*G.scene->r.framelen) /* too far forward in time --> goals won't be accurate enough */ ) { + if(sb->particles) { + pa=sb->particles->particles; + key = pa->hair; + + psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); + } + for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) { - VECCOPY(bp->pos, vertexCos[a]); - Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/ + if(sb->particles) { + if(key == pa->hair + pa->totkey) { + pa++; + key = pa->hair; + + psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); + } + VECCOPY(bp->pos, key->co); + Mat4MulVecfl(hairmat, bp->pos); + key++; + } + else { + VECCOPY(bp->pos, vertexCos[a]); + 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); @@ -3283,23 +3417,22 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts sb_new_scratch(sb); /* make a new */ sb->scratch->needstobuildcollider=1; - - /* copy some info to scratch */ - switch(ob->type) { - case OB_MESH: - if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob); - break; - case OB_LATTICE: - break; - case OB_CURVE: - case OB_SURF: - break; - default: - break; + if((sb->particles)==0) { + /* copy some info to scratch */ + switch(ob->type) { + case OB_MESH: + if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob); + break; + case OB_LATTICE: + break; + case OB_CURVE: + case OB_SURF: + break; + default: + break; + } } - - ob->softflag &= ~OB_SB_RESET; } else if(dtime>0.0) { @@ -3411,10 +3544,10 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts } } - softbody_to_object(ob, vertexCos, numVerts, 0); + if(sb->particles==0) + softbody_to_object(ob, vertexCos, numVerts, 0); sb->ctime= ctime; - - if(ob->softflag & OB_SB_BAKEDO) softbody_baked_add(ob, framenr); + softbody_write_cache(ob, framenr); } |