Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/softbody.c
| Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| #include <math.h> | #include <math.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include "CLG_log.h" | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| /* types */ | /* types */ | ||||
| #include "DNA_collection_types.h" | #include "DNA_collection_types.h" | ||||
| #include "DNA_curve_types.h" | #include "DNA_curve_types.h" | ||||
| #include "DNA_lattice_types.h" | #include "DNA_lattice_types.h" | ||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| Show All 19 Lines | |||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| static CLG_LogRef LOG = {"bke.softbody"}; | |||||
| /* callbacks for errors and interrupts and some goo */ | /* callbacks for errors and interrupts and some goo */ | ||||
| static int (*SB_localInterruptCallBack)(void) = NULL; | static int (*SB_localInterruptCallBack)(void) = NULL; | ||||
| /* ********** soft body engine ******* */ | /* ********** soft body engine ******* */ | ||||
| typedef enum {SB_EDGE=1, SB_BEND=2, SB_STIFFQUAD=3, SB_HANDLE=4} type_spring; | typedef enum {SB_EDGE=1, SB_BEND=2, SB_STIFFQUAD=3, SB_HANDLE=4} type_spring; | ||||
| ▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | if (ob) { | ||||
| if (!(ob->softflag & OB_SB_GOAL)) return (0.0f); | if (!(ob->softflag & OB_SB_GOAL)) return (0.0f); | ||||
| if (sb&&bp) { | if (sb&&bp) { | ||||
| if (bp->goal < 0.0f) return (0.0f); | if (bp->goal < 0.0f) return (0.0f); | ||||
| f = sb->mingoal + bp->goal * fabsf(sb->maxgoal - sb->mingoal); | f = sb->mingoal + bp->goal * fabsf(sb->maxgoal - sb->mingoal); | ||||
| f = pow(f, 4.0f); | f = pow(f, 4.0f); | ||||
| return (f); | return (f); | ||||
| } | } | ||||
| } | } | ||||
| printf("_final_goal failed! sb or bp ==NULL\n"); | CLOG_ERROR(&LOG, "sb or bp == NULL"); | ||||
| return f; /*using crude but spot able values some times helps debuggin */ | return f; /*using crude but spot able values some times helps debuggin */ | ||||
| } | } | ||||
| static float _final_mass(Object *ob, BodyPoint *bp) | static float _final_mass(Object *ob, BodyPoint *bp) | ||||
| { | { | ||||
| if (ob) { | if (ob) { | ||||
| SoftBody *sb= ob->soft; /* is supposed to be there */ | SoftBody *sb= ob->soft; /* is supposed to be there */ | ||||
| if (sb&&bp) { | if (sb&&bp) { | ||||
| return(bp->mass*sb->nodemass); | return(bp->mass*sb->nodemass); | ||||
| } | } | ||||
| } | } | ||||
| printf("_final_mass failed! sb or bp ==NULL\n"); | CLOG_ERROR(&LOG, "sb or bp == NULL"); | ||||
| return 1.0f; | return 1.0f; | ||||
| } | } | ||||
| /* helper functions for everything is animateble jow_go_for2_5 ------*/ | /* helper functions for everything is animateble jow_go_for2_5 ------*/ | ||||
| /*+++ collider caching and dicing +++*/ | /*+++ collider caching and dicing +++*/ | ||||
| /* | /* | ||||
| * for each target object/face the axis aligned bounding box (AABB) is stored | * for each target object/face the axis aligned bounding box (AABB) is stored | ||||
| ▲ Show 20 Lines • Show All 390 Lines • ▼ Show 20 Lines | for (b=bp->nofsprings;b>0;b--) { | ||||
| notthis = bs->v2; | notthis = bs->v2; | ||||
| } | } | ||||
| else { | else { | ||||
| if (v0 == bs->v2) { | if (v0 == bs->v2) { | ||||
| bpo = sb->bpoint+bs->v1; | bpo = sb->bpoint+bs->v1; | ||||
| notthis = bs->v1; | notthis = bs->v1; | ||||
| } | } | ||||
| else { | else { | ||||
| printf("oops we should not get here - add_2nd_order_springs"); | CLOG_ERROR(&LOG, "oops we should not get here"); | ||||
| } | } | ||||
| } | } | ||||
| if (bpo) {/* so now we have a 2nd order humpdidump */ | if (bpo) {/* so now we have a 2nd order humpdidump */ | ||||
| for (c=bpo->nofsprings;c>0;c--) { | for (c=bpo->nofsprings;c>0;c--) { | ||||
| bs2 = sb->bspring + bpo->springs[c-1]; | bs2 = sb->bspring + bpo->springs[c-1]; | ||||
| if ((bs2->v1 != notthis) && (bs2->v1 > v0)) { | if ((bs2->v1 != notthis) && (bs2->v1 > v0)) { | ||||
| (*counter)++;/*hit */ | (*counter)++;/*hit */ | ||||
| if (addsprings) { | if (addsprings) { | ||||
| ▲ Show 20 Lines • Show All 339 Lines • ▼ Show 20 Lines | ob = BLI_ghashIterator_getKey (ihash); | ||||
| /* so now we have the 2 boxes overlapping */ | /* so now we have the 2 boxes overlapping */ | ||||
| /* forces actually not used */ | /* forces actually not used */ | ||||
| deflected = 2; | deflected = 2; | ||||
| } | } | ||||
| else { | else { | ||||
| /*aye that should be cached*/ | /*aye that should be cached*/ | ||||
| printf("missing cache error\n"); | CLOG_ERROR(&LOG, "missing cache error"); | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } /* if (ob->pd && ob->pd->deflect) */ | } /* if (ob->pd && ob->pd->deflect) */ | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| } | } | ||||
| } /* while () */ | } /* while () */ | ||||
| BLI_ghashIterator_free(ihash); | BLI_ghashIterator_free(ihash); | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | ob = BLI_ghashIterator_getKey (ihash); | ||||
| /* boxes don't intersect */ | /* boxes don't intersect */ | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /*aye that should be cached*/ | /*aye that should be cached*/ | ||||
| printf("missing cache error\n"); | CLOG_ERROR(&LOG, "missing cache error"); | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* use mesh*/ | /* use mesh*/ | ||||
| if (mvert) { | if (mvert) { | ||||
| while (a) { | while (a) { | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | ob = BLI_ghashIterator_getKey (ihash); | ||||
| /* boxes don't intersect */ | /* boxes don't intersect */ | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /*aye that should be cached*/ | /*aye that should be cached*/ | ||||
| printf("missing cache error\n"); | CLOG_ERROR(&LOG, "missing cache error"); | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* use mesh*/ | /* use mesh*/ | ||||
| while (a--) { | while (a--) { | ||||
| if ((aabbmax[0] < mima->minx) || | if ((aabbmax[0] < mima->minx) || | ||||
| ▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | ob = BLI_ghashIterator_getKey (ihash); | ||||
| /* boxes don't intersect */ | /* boxes don't intersect */ | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /*aye that should be cached*/ | /*aye that should be cached*/ | ||||
| printf("missing cache error\n"); | CLOG_ERROR(&LOG, "missing cache error"); | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* use mesh*/ | /* use mesh*/ | ||||
| while (a--) { | while (a--) { | ||||
| if ((aabbmax[0] < mima->minx) || | if ((aabbmax[0] < mima->minx) || | ||||
| ▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | ob = BLI_ghashIterator_getKey (ihash); | ||||
| { | { | ||||
| /* outside the padded boundbox --> collision object is too far away */ | /* outside the padded boundbox --> collision object is too far away */ | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /*aye that should be cached*/ | /*aye that should be cached*/ | ||||
| printf("missing cache error\n"); | CLOG_ERROR(&LOG, "missing cache error"); | ||||
| BLI_ghashIterator_step(ihash); | BLI_ghashIterator_step(ihash); | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* do object level stuff */ | /* do object level stuff */ | ||||
| /* need to have user control for that since it depends on model scale */ | /* need to have user control for that since it depends on model scale */ | ||||
| innerfacethickness = -ob->pd->pdef_sbift; | innerfacethickness = -ob->pd->pdef_sbift; | ||||
| outerfacethickness = ob->pd->pdef_sboft; | outerfacethickness = ob->pd->pdef_sboft; | ||||
| ▲ Show 20 Lines • Show All 192 Lines • ▼ Show 20 Lines | |||||
| #if 0 /* UNUSED */ | #if 0 /* UNUSED */ | ||||
| ia =3*bs->v2; | ia =3*bs->v2; | ||||
| ic =3*bs->v1; | ic =3*bs->v1; | ||||
| #endif | #endif | ||||
| } | } | ||||
| else { | else { | ||||
| /* TODO make this debug option */ | /* TODO make this debug option */ | ||||
| /**/ | /**/ | ||||
| printf("bodypoint <bpi> is not attached to spring <*bs> --> sb_spring_force()\n"); | CLOG_WARN(&LOG, "bodypoint <bpi> is not attached to spring <*bs>"); | ||||
| return; | return; | ||||
| } | } | ||||
| /* do bp1 <--> bp2 elastic */ | /* do bp1 <--> bp2 elastic */ | ||||
| sub_v3_v3v3(dir, bp1->pos, bp2->pos); | sub_v3_v3v3(dir, bp1->pos, bp2->pos); | ||||
| distance = normalize_v3(dir); | distance = normalize_v3(dir); | ||||
| if (bs->len < distance) | if (bs->len < distance) | ||||
| iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */ | iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */ | ||||
| Show All 38 Lines | |||||
| /* since this is definitely the most CPU consuming task here .. try to spread it */ | /* since this is definitely the most CPU consuming task here .. try to spread it */ | ||||
| /* core function _softbody_calc_forces_slice_in_a_thread */ | /* core function _softbody_calc_forces_slice_in_a_thread */ | ||||
| /* result is int to be able to flag user break */ | /* result is int to be able to flag user break */ | ||||
| static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor) | static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor) | ||||
| { | { | ||||
| float iks; | float iks; | ||||
| int bb, do_selfcollision, do_springcollision, do_aero; | int bb, do_selfcollision, do_springcollision, do_aero; | ||||
| int number_of_points_here = ilast - ifirst; | int number_of_points_here = ilast - ifirst; | ||||
| SoftBody *sb= ob->soft; /* is supposed to be there */ | SoftBody *sb = ob->soft; /* is supposed to be there */ | ||||
| BodyPoint *bp; | BodyPoint *bp; | ||||
| /* initialize */ | /* initialize */ | ||||
| if (sb) { | if (sb) { | ||||
| /* check conditions for various options */ | /* check conditions for various options */ | ||||
| /* +++ could be done on object level to squeeze out the last bits of it */ | /* +++ could be done on object level to squeeze out the last bits of it */ | ||||
| do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); | do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); | ||||
| do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL); | do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL); | ||||
| do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES)); | do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES)); | ||||
| /* --- could be done on object level to squeeze out the last bits of it */ | /* --- could be done on object level to squeeze out the last bits of it */ | ||||
| } | } | ||||
| else { | else { | ||||
| printf("Error expected a SB here\n"); | CLOG_ERROR(&LOG, "expected a SB here"); | ||||
| return (999); | return (999); | ||||
| } | } | ||||
| /* debugerin */ | /* debugerin */ | ||||
| if (sb->totpoint < ifirst) { | if (sb->totpoint < ifirst) { | ||||
| printf("Aye 998"); | printf("Aye 998"); | ||||
| return (998); | return (998); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,384 Lines • ▼ Show 20 Lines | else if (sb->solver_ID == 4) { | ||||
| /* do semi "fake" implicit euler */ | /* do semi "fake" implicit euler */ | ||||
| }/*SOLVER SELECT*/ | }/*SOLVER SELECT*/ | ||||
| else if (sb->solver_ID == 3) { | else if (sb->solver_ID == 3) { | ||||
| /* do "stupid" semi "fake" implicit euler */ | /* do "stupid" semi "fake" implicit euler */ | ||||
| //removed | //removed | ||||
| }/*SOLVER SELECT*/ | }/*SOLVER SELECT*/ | ||||
| else { | else { | ||||
| printf("softbody no valid solver ID!"); | CLOG_ERROR(&LOG, "softbody no valid solver ID!"); | ||||
| }/*SOLVER SELECT*/ | }/*SOLVER SELECT*/ | ||||
| if (sb->plastic) { apply_spring_memory(ob);} | if (sb->plastic) { apply_spring_memory(ob);} | ||||
| if (sb->solverflags & SBSO_MONITOR ) { | if (sb->solverflags & SBSO_MONITOR ) { | ||||
| sct=PIL_check_seconds_timer(); | sct=PIL_check_seconds_timer(); | ||||
| if ((sct - sst > 0.5) || (G.debug & G_DEBUG)) printf(" solver time %f sec %s\n", sct-sst, ob->id.name); | if ((sct - sst > 0.5) || (G.debug & G_DEBUG)) printf(" solver time %f sec %s\n", sct-sst, ob->id.name); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 130 Lines • Show Last 20 Lines | |||||