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:
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r--source/blender/blenkernel/intern/softbody.c150
1 files changed, 100 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index d1c7b240b94..7f5c8af2686 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -63,6 +63,7 @@ variables on the UI for now
#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_group_types.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -496,59 +497,98 @@ static void ccd_mesh_free(ccd_Mesh *ccdm)
}
}
-static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *hash)
+static void ccd_build_deflector_hash_single(GHash *hash, Object *ob)
+{
+ /* only with deflecting set */
+ if (ob->pd && ob->pd->deflect) {
+ void **val_p;
+ if (!BLI_ghash_ensure_p(hash, ob, &val_p)) {
+ ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
+ *val_p = ccdmesh;
+ }
+ }
+}
+
+/**
+ * \note group overrides scene when not NULL.
+ */
+static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
{
- Base *base= scene->base.first;
Object *ob;
if (!hash) return;
- while (base) {
- /*Only proceed for mesh object in same layer */
- if (base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
- ob= base->object;
- if ((vertexowner) && (ob == vertexowner)) {
- /* if vertexowner is given we don't want to check collision with owner object */
- base = base->next;
+
+ if (group) {
+ /* Explicit collision group */
+ for (GroupObject *go = group->gobject.first; go; go = go->next) {
+ ob = go->ob;
+
+ if (ob == vertexowner || ob->type != OB_MESH)
continue;
- }
- /*+++ only with deflecting set */
- if (ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == NULL) {
- ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
- BLI_ghash_insert(hash, ob, ccdmesh);
- }/*--- only with deflecting set */
+ ccd_build_deflector_hash_single(hash, ob);
+ }
+ }
+ else {
+ for (Base *base = scene->base.first; base; base = base->next) {
+ /*Only proceed for mesh object in same layer */
+ if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
+ ob= base->object;
+ if ((vertexowner) && (ob == vertexowner)) {
+ /* if vertexowner is given we don't want to check collision with owner object */
+ continue;
+ }
+
+ ccd_build_deflector_hash_single(hash, ob);
+ }
+ }
+ }
+}
- }/* mesh && layer*/
- base = base->next;
- } /* while (base) */
+static void ccd_update_deflector_hash_single(GHash *hash, Object *ob)
+{
+ if (ob->pd && ob->pd->deflect) {
+ ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
+ if (ccdmesh) {
+ ccd_mesh_update(ob, ccdmesh);
+ }
+ }
}
-static void ccd_update_deflector_hash(Scene *scene, Object *vertexowner, GHash *hash)
+/**
+ * \note group overrides scene when not NULL.
+ */
+static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
{
- Base *base= scene->base.first;
Object *ob;
if ((!hash) || (!vertexowner)) return;
- while (base) {
- /*Only proceed for mesh object in same layer */
- if (base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
- ob= base->object;
- if (ob == vertexowner) {
- /* if vertexowner is given we don't want to check collision with owner object */
- base = base->next;
+
+ if (group) {
+ /* Explicit collision group */
+ for (GroupObject *go = group->gobject.first; go; go = go->next) {
+ ob = go->ob;
+
+ if (ob == vertexowner || ob->type != OB_MESH)
continue;
- }
- /*+++ only with deflecting set */
- if (ob->pd && ob->pd->deflect) {
- ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
- if (ccdmesh)
- ccd_mesh_update(ob, ccdmesh);
- }/*--- only with deflecting set */
+ ccd_update_deflector_hash_single(hash, ob);
+ }
+ }
+ else {
+ for (Base *base = scene->base.first; base; base = base->next) {
+ /*Only proceed for mesh object in same layer */
+ if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
+ ob= base->object;
+ if (ob == vertexowner) {
+ /* if vertexowner is given we don't want to check collision with owner object */
+ continue;
+ }
- }/* mesh && layer*/
- base = base->next;
- } /* while (base) */
+ ccd_update_deflector_hash_single(hash, ob);
+ }
+ }
+ }
}
@@ -934,22 +974,32 @@ static void free_softbody_intern(SoftBody *sb)
/* +++ dependency information functions*/
-static int are_there_deflectors(Scene *scene, unsigned int layer)
+/**
+ * \note group overrides scene when not NULL.
+ */
+static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
{
- Base *base;
-
- for (base = scene->base.first; base; base= base->next) {
- if ( (base->lay & layer) && base->object->pd) {
- if (base->object->pd->deflect)
+ if (group) {
+ for (GroupObject *go = group->gobject.first; go; go = go->next) {
+ if (go->ob->pd && go->ob->pd->deflect)
return 1;
}
}
+ else {
+ for (Base *base = scene->base.first; base; base= base->next) {
+ if ( (base->lay & layer) && base->object->pd) {
+ if (base->object->pd->deflect)
+ return 1;
+ }
+ }
+ }
+
return 0;
}
-static int query_external_colliders(Scene *scene, Object *me)
+static int query_external_colliders(Scene *scene, Group *group, Object *me)
{
- return(are_there_deflectors(scene, me->lay));
+ return(are_there_deflectors(scene, group, me->lay));
}
/* --- dependency information functions*/
@@ -2197,7 +2247,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
/* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */
/* check conditions for various options */
- do_deflector= query_external_colliders(scene, ob);
+ do_deflector= query_external_colliders(scene, sb->collision_group, ob);
/* do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); */ /* UNUSED */
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2261,7 +2311,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
/* check conditions for various options */
- do_deflector= query_external_colliders(scene, ob);
+ do_deflector= query_external_colliders(scene, sb->collision_group, ob);
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_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -3472,11 +3522,11 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
*/
if (dtime < 0 || dtime > 10.5f) return;
- ccd_update_deflector_hash(scene, ob, sb->scratch->colliderhash);
+ ccd_update_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
if (sb->scratch->needstobuildcollider) {
- if (query_external_colliders(scene, ob)) {
- ccd_build_deflector_hash(scene, ob, sb->scratch->colliderhash);
+ if (query_external_colliders(scene, sb->collision_group, ob)) {
+ ccd_build_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
}
sb->scratch->needstobuildcollider=0;
}