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:
authorAlexander Gavrilov <angavrilov@gmail.com>2016-07-31 11:56:44 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-07-31 11:57:19 +0300
commit64d4d6b134d5b36c43aa55e09ad92d8593a18269 (patch)
tree16f92a4f942ecb8d527093840a079889a1b10c08 /source/blender/blenkernel/intern/softbody.c
parent710ab5be36cda9cba547502d5327f400f15935bc (diff)
Support limiting collisions by group for softbody and particles
This feature is extremely useful for layering multiple cloth objects, and there is no reason there shouldn't be the same kind of feature for softbody.
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r--source/blender/blenkernel/intern/softbody.c152
1 files changed, 102 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 8fec817d694..7aa899dcf2a 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,100 @@ 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 */
+ base = base->next;
+ 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 */
+ base = base->next;
+ continue;
+ }
- }/* mesh && layer*/
- base = base->next;
- } /* while (base) */
+ ccd_update_deflector_hash_single(hash, ob);
+ }
+ }
+ }
}
@@ -934,22 +976,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 +2249,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 +2313,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 +3524,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;
}