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:
-rw-r--r--release/scripts/ui/properties_physics_cloth.py1
-rw-r--r--source/blender/blenkernel/BKE_collision.h13
-rw-r--r--source/blender/blenkernel/intern/collision.c261
-rw-r--r--source/blender/blenkernel/intern/effect.c2
-rw-r--r--source/blender/blenkernel/intern/implicit.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c5
10 files changed, 118 insertions, 172 deletions
diff --git a/release/scripts/ui/properties_physics_cloth.py b/release/scripts/ui/properties_physics_cloth.py
index 7a65420e172..22a83e02ba7 100644
--- a/release/scripts/ui/properties_physics_cloth.py
+++ b/release/scripts/ui/properties_physics_cloth.py
@@ -179,6 +179,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel):
sub.prop(cloth, "self_collision_quality", slider=True, text="Quality")
sub.prop(cloth, "self_min_distance", slider=True, text="Distance")
+ layout.prop(cloth, "group")
class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
bl_label = "Cloth Stiffness Scaling"
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index 689fa96ffa6..91c5eb4afee 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -49,12 +49,13 @@
#include "BLI_kdopbvh.h"
-struct Object;
-struct Scene;
struct Cloth;
-struct MFace;
-struct DerivedMesh;
struct ClothModifierData;
+struct DerivedMesh;
+struct Group;
+struct MFace;
+struct Object;
+struct Scene;
////////////////////////////////////////
// used for collisions in collision.c
@@ -139,7 +140,7 @@ void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3],
/////////////////////////////////////////////////
// used in effect.c
/////////////////////////////////////////////////
-Object **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj);
+struct Object **get_collisionobjects(struct Scene *scene, struct Object *self, struct Group *group, int *numcollobj);
typedef struct ColliderCache {
struct ColliderCache *next, *prev;
@@ -147,7 +148,7 @@ typedef struct ColliderCache {
struct CollisionModifierData *collmd;
} ColliderCache;
-struct ListBase *get_collider_cache(struct Scene *scene, Object *self);
+struct ListBase *get_collider_cache(struct Scene *scene, struct Object *self, struct Group *group);
void free_collider_cache(struct ListBase **colliders);
/////////////////////////////////////////////////
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index b024ba5f4e1..c85bd2f90b3 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -1299,188 +1299,122 @@ static int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierDa
}
#endif
-
-// return all collision objects in scene
-// collision object will exclude self
-Object **get_collisionobjects(Scene *scene, Object *self, int *numcollobj)
+static void add_collision_object(Object ***objs, int *numobj, int *maxobj, Object *ob, Object *self, int level)
{
- Base *base=NULL;
- Object **objs = NULL;
- Object *coll_ob = NULL;
- CollisionModifierData *collmd = NULL;
- int numobj = 0, maxobj = 100;
+ CollisionModifierData *cmd= NULL;
+
+ if(ob == self)
+ return;
+
+ /* only get objects with collision modifier */
+ if(ob->pd && ob->pd->deflect)
+ cmd= (CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
- objs = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
- // check all collision objects
- for ( base = scene->base.first; base; base = base->next )
- {
- /*Only proceed for mesh object in same layer */
- if(!(base->object->type==OB_MESH && (base->lay & self->lay)))
- continue;
-
- coll_ob = base->object;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+ if(cmd) {
+ /* extend array */
+ if(*numobj >= *maxobj) {
+ *maxobj *= 2;
+ *objs= MEM_reallocN(*objs, sizeof(Object*)*(*maxobj));
}
- else
- collmd = NULL;
- if ( collmd )
- {
- if(numobj >= maxobj)
- {
- // realloc
- int oldmax = maxobj;
- Object **tmp;
- maxobj *= 2;
- tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
- memcpy(tmp, objs, sizeof(Object *)*oldmax);
- MEM_freeN(objs);
- objs = tmp;
-
- }
-
- objs[numobj] = coll_ob;
- numobj++;
- }
- else
- {
- if ( coll_ob->dup_group )
- {
- GroupObject *go;
- Group *group = coll_ob->dup_group;
+ (*objs)[*numobj] = ob;
+ (*numobj)++;
+ }
- for ( go= group->gobject.first; go; go= go->next )
- {
- coll_ob = go->ob;
- collmd = NULL;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- }
- else
- collmd = NULL;
+ /* objects in dupli groups, one level only for now */
+ if(ob->dup_group && level == 0) {
+ GroupObject *go;
+ Group *group= ob->dup_group;
- if ( !collmd )
- continue;
-
- if( !collmd->bvhtree)
- continue;
+ /* add objects */
+ for(go= group->gobject.first; go; go= go->next)
+ add_collision_object(objs, numobj, maxobj, go->ob, self, level+1);
+ }
+}
- if(numobj >= maxobj)
- {
- // realloc
- int oldmax = maxobj;
- Object **tmp;
- maxobj *= 2;
- tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
- memcpy(tmp, objs, sizeof(Object *)*oldmax);
- MEM_freeN(objs);
- objs = tmp;
- }
-
- objs[numobj] = coll_ob;
- numobj++;
- }
- }
- }
+// return all collision objects in scene
+// collision object will exclude self
+Object **get_collisionobjects(Scene *scene, Object *self, Group *group, int *numcollobj)
+{
+ Base *base;
+ Object **objs;
+ GroupObject *go;
+ int numobj= 0, maxobj= 100;
+
+ objs= MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
+
+ /* gather all collision objects */
+ if(group) {
+ /* use specified group */
+ for(go= group->gobject.first; go; go= go->next)
+ add_collision_object(&objs, &numobj, &maxobj, go->ob, self, 0);
+ }
+ else {
+ /* add objects in same layer in scene */
+ for(base = scene->base.first; base; base = base->next)
+ if(base->lay & self->lay)
+ add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0);
}
- *numcollobj = numobj;
+
+ *numcollobj= numobj;
+
return objs;
}
-ListBase *get_collider_cache(Scene *scene, Object *self)
+static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, int level)
{
- Base *base=NULL;
- ListBase *objs = NULL;
- Object *coll_ob = NULL;
- CollisionModifierData *collmd = NULL;
+ CollisionModifierData *cmd= NULL;
ColliderCache *col;
-
- // check all collision objects
- for ( base = scene->base.first; base; base = base->next )
- {
- /*Only proceed for mesh object in same layer */
- if(base->object->type!=OB_MESH)
- continue;
- if(self && (base->lay & self->lay)==0)
- continue;
+ if(ob == self)
+ return;
-
- coll_ob = base->object;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- }
- else
- collmd = NULL;
-
- if ( collmd )
- {
- if(objs == NULL)
- objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
-
- col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = coll_ob;
- col->collmd = collmd;
- /* make sure collider is properly set up */
- collision_move_object(collmd, 1.0, 0.0);
- BLI_addtail(objs, col);
- }
- else if ( coll_ob->dup_group )
- {
- GroupObject *go;
- Group *group = coll_ob->dup_group;
+ if(ob->pd && ob->pd->deflect)
+ cmd =(CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
+
+ if(cmd && cmd->bvhtree) {
+ if(*objs == NULL)
+ *objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+
+ col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ /* make sure collider is properly set up */
+ collision_move_object(cmd, 1.0, 0.0);
+ BLI_addtail(*objs, col);
+ }
- for ( go= group->gobject.first; go; go= go->next )
- {
- coll_ob = go->ob;
- collmd = NULL;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- }
- else
- collmd = NULL;
+ /* objects in dupli groups, one level only for now */
+ if(ob->dup_group && level == 0) {
+ GroupObject *go;
+ Group *group= ob->dup_group;
- if ( !collmd )
- continue;
-
- if( !collmd->bvhtree)
- continue;
-
- if(objs == NULL)
- objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
-
- col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = coll_ob;
- col->collmd = collmd;
- /* make sure collider is properly set up */
- collision_move_object(collmd, 1.0, 0.0);
- BLI_addtail(objs, col);
- }
- }
+ /* add objects */
+ for(go= group->gobject.first; go; go= go->next)
+ add_collider_cache_object(objs, go->ob, self, level+1);
+ }
+}
+
+ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
+{
+ Base *base;
+ GroupObject *go;
+ ListBase *objs= NULL;
+
+ /* add object in same layer in scene */
+ if(group) {
+ for(go= group->gobject.first; go; go= go->next)
+ add_collider_cache_object(&objs, go->ob, self, 0);
+ }
+ else {
+ for(base = scene->base.first; base; base = base->next)
+ if(self && (base->lay & self->lay)==0)
+ add_collider_cache_object(&objs, base->object, self, 0);
}
+
return objs;
}
+
void free_collider_cache(ListBase **colliders)
{
if(*colliders) {
@@ -1489,6 +1423,7 @@ void free_collider_cache(ListBase **colliders)
*colliders = NULL;
}
}
+
static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
{
int i;
@@ -1574,7 +1509,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function)
bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
- collobjs = get_collisionobjects(clmd->scene, ob, &numcollobj);
+ collobjs = get_collisionobjects(clmd->scene, ob, clmd->coll_parms->group, &numcollobj);
if(!collobjs)
return 0;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 66e7f805f50..118f4885af4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -429,7 +429,7 @@ static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, Effect
return visibility;
if(!colls)
- colls = get_collider_cache(eff->scene, NULL);
+ colls = get_collider_cache(eff->scene, NULL, NULL);
if(!colls)
return visibility;
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index b4fb34d8464..c625fb28840 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1422,7 +1422,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec
/* 10x10x10 grid gives nice initial results */
HairGridVert grid[10][10][10];
HairGridVert colg[10][10][10];
- ListBase *colliders = get_collider_cache(clmd->scene, NULL);
+ ListBase *colliders = get_collider_cache(clmd->scene, NULL, NULL);
ColliderCache *col = NULL;
float gmin[3], gmax[3], density;
/* 2.0f is an experimental value that seems to give good results */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index a99a8affbd3..a8446c0009f 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3229,7 +3229,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
psys_update_effectors(sim);
if(part->type != PART_HAIR)
- sim->colliders = get_collider_cache(sim->scene, NULL);
+ sim->colliders = get_collider_cache(sim->scene, NULL, NULL);
if(part->phystype==PART_PHYS_BOIDS){
ParticleTarget *pt = psys->targets.first;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 0bce2d004e3..dd2a3143d3d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -53,6 +53,7 @@
#include "BKE_animsys.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
+#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 768fe1f2c33..356ae158692 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3065,6 +3065,7 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
psys->clmd->point_cache= psys->pointcache;
psys->clmd->ptcaches.first= psys->clmd->ptcaches.last= NULL;
+ psys->clmd->coll_parms->group= newlibadr(fd, id->lib, psys->clmd->coll_parms->group);
}
}
else {
@@ -3621,6 +3622,7 @@ static void lib_link_object(FileData *fd, Main *main)
if(clmd)
{
clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group);
+ clmd->coll_parms->group= newlibadr(fd, ob->id.lib, clmd->coll_parms->group);
}
}
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 8fa63e6acc4..bd323c5821b 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -93,6 +93,7 @@ typedef struct ClothCollSettings
int flags; /* collision flags defined in BKE_cloth.h */
short self_loop_count; /* How many iterations for the selfcollision loop */
short loop_count; /* How many iterations for the collision loop. */
+ struct Group *group; /* Only use colliders from this group of objects */
} ClothCollSettings;
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 7dcdd92a90a..19718a33265 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -430,6 +430,11 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_text(prop, "Self Collision Quality", "How many self collision iterations should be done. (higher is better quality but slower)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+ prop= RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
}
void RNA_def_cloth(BlenderRNA *brna)