[Bf-blender-cvs] [dce5561] fracture_modifier: allow multiple dynamic destruction with extra particles or verts
Martin Felke
noreply at git.blender.org
Tue Mar 29 15:24:54 CEST 2016
Commit: dce55610df79921da11d699de947f3627d8be9be
Author: Martin Felke
Date: Tue Mar 29 15:24:13 2016 +0200
Branches: fracture_modifier
https://developer.blender.org/rBdce55610df79921da11d699de947f3627d8be9be
allow multiple dynamic destruction with extra particles or verts
this should allow triggered dynamic destruction with different colliders at different times. Note: WIP and crashes often in relation with undo
===================================================================
M source/blender/modifiers/intern/MOD_fracture.c
===================================================================
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 8111474..03f44e2 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -88,6 +88,8 @@
static DerivedMesh* do_prefractured(FractureModifierData *fmd, Object *ob, DerivedMesh *derivedData);
static void do_prehalving(FractureModifierData *fmd, Object* ob, DerivedMesh* derivedData);
static Shard* copy_shard(Shard *s);
+static void arrange_shard(FractureModifierData *fmd, ShardID id, bool do_verts, float cent[]);
+static Shard* find_shard(ListBase *shards, ShardID id);
//TODO XXX Make BKE
static FracMesh* copy_fracmesh(FracMesh* fm)
@@ -978,8 +980,14 @@ static DerivedMesh *get_group_dm(FractureModifierData *fmd, DerivedMesh *dm, Obj
return dm;
}
+static bool in_bbox(float p[3], float min[3], float max[3])
+{
+ return (p[0] > min[0]) && (p[0] < max[0]) && (p[1] > min[1]) && (p[1] < max[1]) && (p[2] > min[2]) && (p[2] < max[2]);
+}
+
//XXX MOve to BKE_Fracture.h / fracture.c, prefracture stuff should be a function called from op, or in dynamic case from Rigidbody system callback
-static void points_from_verts(Object **ob, int totobj, FracPointCloud *points, float mat[4][4], float thresh, FractureModifierData *emd, DerivedMesh *dm, Object *obj)
+static void points_from_verts(Object **ob, int totobj, FracPointCloud *points, float mat[4][4], float thresh, FractureModifierData *emd, DerivedMesh *dm, Object *obj,
+ ShardID id)
{
int v, o, pt = points->totpoints;
float co[3];
@@ -1004,7 +1012,6 @@ static void points_from_verts(Object **ob, int totobj, FracPointCloud *points, f
for (v = 0; v < d->getNumVerts(d); v++) {
if (BLI_frand() < thresh) {
- points->points = MEM_reallocN((*points).points, (pt + 1) * sizeof(FracPoint));
copy_v3_v3(co, vert[v].co);
@@ -1014,8 +1021,30 @@ static void points_from_verts(Object **ob, int totobj, FracPointCloud *points, f
mul_m4_v3(imat, co);
}
- copy_v3_v3(points->points[pt].co, co);
- pt++;
+ if (id > 0)
+ {
+ Shard *sh;
+ float min[3], max[3], cent[3];
+ arrange_shard(emd, id, false, cent);
+ sh = find_shard(&emd->frac_mesh->shard_map, id);
+ if (sh)
+ {
+ add_v3_v3v3(min, sh->min, cent);
+ add_v3_v3v3(max, sh->max, cent);
+ if (in_bbox(co, min, max))
+ {
+ points->points = MEM_reallocN(points->points, (pt + 1) * sizeof(FracPoint));
+ copy_v3_v3(points->points[pt].co, co);
+ pt++;
+ }
+ }
+ }
+ else
+ {
+ points->points = MEM_reallocN(points->points, (pt + 1) * sizeof(FracPoint));
+ copy_v3_v3(points->points[pt].co, co);
+ pt++;
+ }
}
}
}
@@ -1025,7 +1054,7 @@ static void points_from_verts(Object **ob, int totobj, FracPointCloud *points, f
}
static void points_from_particles(Object **ob, int totobj, Scene *scene, FracPointCloud *points, float mat[4][4],
- float thresh, FractureModifierData *fmd)
+ float thresh, FractureModifierData *fmd, ShardID id)
{
int o, p, pt = points->totpoints;
ParticleSystemModifierData *psmd;
@@ -1066,14 +1095,33 @@ static void points_from_particles(Object **ob, int totobj, Scene *scene, FracPoi
psys_get_particle_state(&sim, p, &birth, 1);
}
- points->points = MEM_reallocN(points->points, (pt + 1) * sizeof(FracPoint));
copy_v3_v3(co, birth.co);
-
-
mul_m4_v3(imat, co);
- copy_v3_v3(points->points[pt].co, co);
- pt++;
+ if (id > 0)
+ {
+ Shard *sh;
+ float min[3], max[3], cent[3];
+ arrange_shard(fmd, id, false, cent);
+ sh = find_shard(&fmd->frac_mesh->shard_map, id);
+ if (sh)
+ {
+ add_v3_v3v3(min, sh->min, cent);
+ add_v3_v3v3(max, sh->max, cent);
+ if (in_bbox(co, min, max))
+ {
+ points->points = MEM_reallocN(points->points, (pt + 1) * sizeof(FracPoint));
+ copy_v3_v3(points->points[pt].co, co);
+ pt++;
+ }
+ }
+ }
+ else
+ {
+ points->points = MEM_reallocN(points->points, (pt + 1) * sizeof(FracPoint));
+ copy_v3_v3(points->points[pt].co, co);
+ pt++;
+ }
}
}
}
@@ -1156,11 +1204,11 @@ static FracPointCloud get_points_global(FractureModifierData *emd, Object *ob, D
}
if (emd->point_source & (MOD_FRACTURE_OWN_PARTICLES | MOD_FRACTURE_EXTRA_PARTICLES)) {
- points_from_particles(go, totgroup, scene, &points, ob->obmat, thresh, emd);
+ points_from_particles(go, totgroup, scene, &points, ob->obmat, thresh, emd, id);
}
if (emd->point_source & (MOD_FRACTURE_OWN_VERTS | MOD_FRACTURE_EXTRA_VERTS)) {
- points_from_verts(go, totgroup, &points, ob->obmat, thresh, emd, fracmesh, ob);
+ points_from_verts(go, totgroup, &points, ob->obmat, thresh, emd, fracmesh, ob, id);
}
if (emd->point_source & MOD_FRACTURE_GREASEPENCIL && !emd->use_greasepencil_edges) {
@@ -1171,10 +1219,16 @@ static FracPointCloud get_points_global(FractureModifierData *emd, Object *ob, D
/* local settings, apply per shard!!! Or globally too first. */
if (emd->point_source & MOD_FRACTURE_UNIFORM)
{
+ float cent[3], bmin[3], bmax[3];
int count = emd->shard_count;
INIT_MINMAX(min, max);
if (!BKE_get_shard_minmax(emd->frac_mesh, id, min, max, fracmesh))
return points; //id 0 should be entire mesh
+
+ arrange_shard(emd, id, false, cent);
+ add_v3_v3v3(bmax, max, cent);
+ add_v3_v3v3(bmin, min, cent);
+
printf("min, max: (%f %f %f), (%f %f %f)\n", min[0], min[1], min[2], max[0], max[1], max[2]);
if (emd->frac_algorithm == MOD_FRACTURE_BISECT_FAST || emd->frac_algorithm == MOD_FRACTURE_BISECT_FAST_FILL ||
@@ -1189,13 +1243,26 @@ static FracPointCloud get_points_global(FractureModifierData *emd, Object *ob, D
BLI_srandom(emd->point_seed);
for (i = 0; i < count; ++i) {
if (BLI_frand() < thresh) {
- float *co;
- points.points = MEM_reallocN(points.points, sizeof(FracPoint) * (points.totpoints + 1));
- co = points.points[points.totpoints].co;
+ float co[3];
co[0] = min[0] + (max[0] - min[0]) * BLI_frand();
co[1] = min[1] + (max[1] - min[1]) * BLI_frand();
co[2] = min[2] + (max[2] - min[2]) * BLI_frand();
- points.totpoints++;
+
+ if (id > 0)
+ {
+ if (in_bbox(co, bmin, bmax))
+ {
+ points.points = MEM_reallocN(points.points, sizeof(FracPoint) * (points.totpoints + 1));
+ copy_v3_v3(points.points[points.totpoints].co, co);
+ points.totpoints++;
+ }
+ }
+ else
+ {
+ points.points = MEM_reallocN(points.points, sizeof(FracPoint) * (points.totpoints + 1));
+ copy_v3_v3(points.points[points.totpoints].co, co);
+ points.totpoints++;
+ }
}
}
}
@@ -1384,6 +1451,72 @@ static void cleanup_splinters(FractureModifierData *fmd, float mat[4][4], Shard
}
}
+static Shard* find_shard(ListBase *shards, ShardID id)
+{
+ Shard *s = shards->first;
+ while (s)
+ {
+ if (s->shard_id == id)
+ {
+ return s;
+ }
+ s = s->next;
+ }
+
+ return NULL;
+}
+
+static void arrange_shard(FractureModifierData *fmd, ShardID id, bool do_verts, float cent[3])
+{
+ if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC)
+ {
+ zero_v3(cent);
+ bool found = false;
+ Shard *sh = find_shard(&fmd->frac_mesh->shard_map, id);
+ ShardSequence *seq = fmd->current_shard_entry;
+ while (seq->prev && sh)
+ {
+ Shard *par = find_shard(&seq->prev->frac_mesh->shard_map, sh->parent_id);
+ if (par)
+ {
+ add_v3_v3(cent, par->centroid);
+ found = true;
+ }
+
+ seq = seq->prev;
+ }
+
+ if (found && do_verts)
+ {
+ add_v3_v3(sh->centroid, cent);
+ add_v3_v3(sh->min, cent);
+ add_v3_v3(sh->max, cent);
+
+ int i = 0;
+ for (i = 0; i < sh->totvert; i++)
+ {
+ add_v3_v3(sh->mvert[i].co, cent);
+ }
+ }
+ }
+}
+
+static void cleanup_arrange_shard(FractureModifierData *fmd, Shard* sh, float cent[3])
+{
+ if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC && sh)
+ {
+ sub_v3_v3(sh->centroid, cent);
+ sub_v3_v3(sh->min, cent);
+ sub_v3_v3(sh->max, cent);
+
+ int i = 0;
+ for (i = 0; i < sh->totvert; i++)
+ {
+ sub_v3_v3(sh->mvert[i].co, cent);
+ }
+ }
+}
+
//this is the main fracture function, outsource to BKE, so op or rb system can call it
static void do_fracture(FractureModifierData *fmd, ShardID id, Object *obj, DerivedMesh *dm)
{
@@ -1398,10 +1531,13 @@ static void do_fracture(FractureModifierData *fmd, ShardID id, Object *obj, Deri
short mat_index = 0;
float mat[4][4];
Shard *s = NULL;
+ float cent[3];
/*splinters... just global axises and a length, for rotation rotate the object */
s = do_splinters(fmd, points, &mat, id, dm);
+ arrange_shard(fmd, id, true, cent);
+
mat_index = do_materials(fmd, obj);
mat_index = mat_index > 0 ? mat_index - 1 : mat_index;
@@ -1435,6 +1571,9 @@ static void do_fracture(FractureModifierData *fmd, ShardID id, Object *obj, Deri
BKE_fracture_shard_by_planes(fmd, obj, mat_index, mat);
}
+ cleanup_arrange_shard(fmd, s, cent);
+
+
/* job has been cancelled, throw away all data */
if (fmd->frac_mesh->cancel == 1)
{
@@ -1453,7 +1592,9 @@ static void do_fracture(FractureModifierData *fmd, ShardID id, Object *obj, Deri
fmd->shards_to_islands = temp;
if (!s)
+ {
cleanup_splinters(fmd, mat, s, dm);
+ }
fmd->reset_shards = false;
}
MEM_freeN(points.points);
@@ -3079,6 +3220,8 @@ void set_rigidbody_type(FractureModifierData *fmd, Shard *s, MeshIsland *mi)
{
mi->rigidbody->flag |= RBO_FLAG_KINEMATIC;
}
+
+ mi->rigidbody->flag |= RBO_FLAG_NEEDS_VALIDATE;
}
}
}
@@ -4115,33 +4258,52 @@ static void do_modifier(FractureModifierData *fmd, Object *ob, DerivedMesh *dm)
* should not have a visible effect in general */
int count = 0; //BLI_listbase_count(&fmd->fracture_ids);
+ int totpoint = 0;
+ FractureID *fid = fmd->fracture_ids.first;
+
+ while(fid) {
+ FracPointCloud points;
+ points = get_points_global(fmd, ob, dm, fid->shardID);
+ totpoint += points.totpoints;
+ MEM_freeN(points.poi
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list