[Bf-blender-cvs] [4e1c31ca7bf] fracture_modifier: crash fix for external constraints
Martin Felke
noreply at git.blender.org
Sat Feb 17 13:42:53 CET 2018
Commit: 4e1c31ca7bf4f34a435fcafac59f9066d321b34d
Author: Martin Felke
Date: Sat Feb 17 13:42:26 2018 +0100
Branches: fracture_modifier
https://developer.blender.org/rB4e1c31ca7bf4f34a435fcafac59f9066d321b34d
crash fix for external constraints
ensure refresh of "parent" FM object on every refresh of connected objects, also ensure evaluation order in rigidbody.c / bullet (parent always after children)
===================================================================
M source/blender/blenkernel/intern/fracture.c
M source/blender/blenkernel/intern/rigidbody.c
M source/blender/modifiers/intern/MOD_fracture.c
===================================================================
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index fd8ef26a6bb..a07c1fd8771 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -2643,21 +2643,17 @@ void BKE_free_constraints(FractureModifierData *fmd)
}
}
+
+
for (mi = fmd->meshIslands.first; mi; mi = mi->next) {
if (mi->participating_constraints != NULL && mi->participating_constraint_count > 0) {
- int i = 0;
-
+ int i;
for (i = 0; i < mi->participating_constraint_count; i++)
{
RigidBodyShardCon *con = mi->participating_constraints[i];
if (con) {
- if (con->mi1 == mi) {
- con->mi1 = NULL;
- }
-
- if (con->mi2 == mi) {
- con->mi2 = NULL;
- }
+ con->mi1 = NULL;
+ con->mi2 = NULL;
}
}
@@ -2670,8 +2666,6 @@ void BKE_free_constraints(FractureModifierData *fmd)
while (fmd->meshConstraints.first) {
rbsc = fmd->meshConstraints.first;
BLI_remlink(&fmd->meshConstraints, rbsc);
- remove_participants(rbsc, rbsc->mi1);
- remove_participants(rbsc, rbsc->mi2);
if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC && fmd->modifier.scene)
{
@@ -3422,13 +3416,8 @@ void BKE_fracture_free_mesh_island(FractureModifierData *rmd, MeshIsland *mi, bo
{
RigidBodyShardCon *con = mi->participating_constraints[i];
if (con) {
- if (con->mi1 == mi) {
- con->mi1 = NULL;
- }
-
- if (con->mi2 == mi) {
- con->mi2 = NULL;
- }
+ con->mi1 = NULL;
+ con->mi2 = NULL;
}
}
@@ -3794,22 +3783,27 @@ void BKE_meshisland_constraint_create(FractureModifierData* fmd, MeshIsland *mi1
BLI_addtail(&fmd->meshConstraints, rbsc);
- /* store constraints per meshisland too, to allow breaking percentage */
- if (mi1->participating_constraints == NULL) {
- mi1->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi1");
- mi1->participating_constraint_count = 0;
- }
- mi1->participating_constraints = MEM_reallocN(mi1->participating_constraints, sizeof(RigidBodyShardCon *) * (mi1->participating_constraint_count + 1));
- mi1->participating_constraints[mi1->participating_constraint_count] = rbsc;
- mi1->participating_constraint_count++;
+ if ((mi1->object_index == -1) && (mi2->object_index == -1))
+ {
+ /* store constraints per meshisland too, to allow breaking percentage */
+ if (mi1->participating_constraints == NULL) {
+ mi1->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi1");
+ mi1->participating_constraint_count = 0;
+ }
+ mi1->participating_constraints = MEM_reallocN(mi1->participating_constraints,
+ sizeof(RigidBodyShardCon *) * (mi1->participating_constraint_count + 1));
+ mi1->participating_constraints[mi1->participating_constraint_count] = rbsc;
+ mi1->participating_constraint_count++;
- if (mi2->participating_constraints == NULL) {
- mi2->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi2");
- mi2->participating_constraint_count = 0;
+ if (mi2->participating_constraints == NULL) {
+ mi2->participating_constraints = MEM_callocN(sizeof(RigidBodyShardCon *), "part_constraints_mi2");
+ mi2->participating_constraint_count = 0;
+ }
+ mi2->participating_constraints = MEM_reallocN(mi2->participating_constraints,
+ sizeof(RigidBodyShardCon *) * (mi2->participating_constraint_count + 1));
+ mi2->participating_constraints[mi2->participating_constraint_count] = rbsc;
+ mi2->participating_constraint_count++;
}
- mi2->participating_constraints = MEM_reallocN(mi2->participating_constraints, sizeof(RigidBodyShardCon *) * (mi2->participating_constraint_count + 1));
- mi2->participating_constraints[mi2->participating_constraint_count] = rbsc;
- mi2->participating_constraint_count++;
}
void BKE_update_acceleration_map(FractureModifierData *fmd, MeshIsland* mi, Object* ob, int ctime, float acc, RigidBodyWorld *rbw)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 454f3f74e73..1024158a53e 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -44,6 +44,7 @@
#include "BLI_math.h"
#include "BLI_kdtree.h"
#include "BLI_rand.h"
+#include "BLI_sort.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -1586,6 +1587,45 @@ static int rigidbody_group_count_items(const ListBase *group, int *r_num_objects
return num_gobjects;
}
+static int object_sort_eval(const void *s1, const void *s2, void* context)
+{
+ Object **o1 = (Object**)s1;
+ Object **o2 = (Object**)s2;
+
+ FractureModifierData *fmd1 = (FractureModifierData*)modifiers_findByType(*o1, eModifierType_Fracture);
+ FractureModifierData *fmd2 = (FractureModifierData*)modifiers_findByType(*o2, eModifierType_Fracture);
+
+ if (!fmd1 || !fmd2) {
+ return 0;
+ }
+
+ if ((fmd1 && fmd1->dm_group && fmd1->use_constraint_group) &&
+ (fmd2 && fmd2->dm_group && fmd2->use_constraint_group))
+ {
+ return 0;
+ }
+
+ if ((fmd1 && !(fmd1->dm_group && fmd1->use_constraint_group)) &&
+ (fmd2 && !(fmd2->dm_group && fmd2->use_constraint_group)))
+ {
+ return 0;
+ }
+
+ if ((fmd1 && fmd1->dm_group && fmd1->use_constraint_group) &&
+ (fmd2 && !(fmd2->dm_group && fmd2->use_constraint_group)))
+ {
+ return 1;
+ }
+
+ if ((fmd1 && !(fmd1->dm_group && fmd1->use_constraint_group)) &&
+ (fmd2 && (fmd2->dm_group && fmd2->use_constraint_group)))
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
/* ************************************** */
/* Simulation Interface - Bullet */
@@ -1626,15 +1666,25 @@ void BKE_rigidbody_update_ob_array(RigidBodyWorld *rbw, bool do_bake_correction)
printf("RigidbodyCount changed: %d\n", rbw->numbodies);
- //correct map if baked, it might be shifted
+ //pre-sort rbw->objects... put such with fmd->dm_group and fmd->use_constraint_group after all without,
+ //to enforce proper eval order
+
for (go = rbw->group->gobject.first, i = 0; go; go = go->next, i++) {
if (go->ob->rigidbody_object)
{
rbw->objects[i] = go->ob;
}
+ }
+
+ BLI_qsort_r(rbw->objects, l, sizeof(Object *), object_sort_eval, NULL);
- rmd = (FractureModifierData*)modifiers_findByType(go->ob, eModifierType_Fracture);
+ //correct map if baked, it might be shifted
+ for (i = 0; i < l; i++) {
+ Object *ob = rbw->objects[i];
+ printf("%s\n", ob->id.name + 2);
+
+ rmd = (FractureModifierData*)modifiers_findByType(ob, eModifierType_Fracture);
if (rmd) {
for (mi = rmd->meshIslands.first, j = 0; mi; mi = mi->next) {
//store original position of the object in the object array, to be able to rearrange it later so it matches the baked cache
@@ -1651,11 +1701,11 @@ void BKE_rigidbody_update_ob_array(RigidBodyWorld *rbw, bool do_bake_correction)
ismapped = true;
}
- if (!ismapped && go->ob->rigidbody_object) {
- tmp_index[counter] = go->ob->rigidbody_object; /*1 object 1 index here (normal case)*/
+ if (!ismapped && ob->rigidbody_object) {
+ tmp_index[counter] = ob->rigidbody_object; /*1 object 1 index here (normal case)*/
tmp_offset[counter] = i;
- if (go->ob->rigidbody_object && !do_bake_correction)
- go->ob->rigidbody_object->meshisland_index = counter;
+ if (ob->rigidbody_object && !do_bake_correction)
+ ob->rigidbody_object->meshisland_index = counter;
counter++;
}
@@ -1887,6 +1937,8 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool
bool did_modifier = false;
float centroid[3] = {0, 0, 0};
float size[3] = {1.0f, 1.0f, 1.0f};
+ float count = BLI_listbase_count(&rbw->group->gobject);
+ int i = 0;
/* update world */
if (rebuild) {
@@ -1896,8 +1948,8 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool
rigidbody_update_sim_world(scene, rbw, rebuild);
/* update objects */
- for (go = rbw->group->gobject.first; go; go = go->next) {
- Object *ob = go->ob;
+ for (i = 0; i < count; i++) {
+ Object *ob = rbw->objects[i];
if (ob && (ob->type == OB_MESH || ob->type == OB_CURVE || ob->type == OB_SURF || ob->type == OB_FONT)) {
did_modifier = do_update_modifier(scene, ob, rbw, rebuild);
@@ -3920,7 +3972,7 @@ void BKE_rigidbody_validate_sim_shard_constraint(RigidBodyWorld *rbw, FractureMo
return;
}
- if (ELEM(NULL, rbc->mi1, rbc->mi1->rigidbody, rbc->mi2, rbc->mi2->rigidbody)) {
+ if (ELEM(NULL, rbc->mi1, rbc->mi2)) {
if (rbc->physics_constraint) {
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
RB_constraint_delete(rbc->physics_constraint);
@@ -3934,6 +3986,10 @@ void BKE_rigidbody_validate_sim_shard_constraint(RigidBodyWorld *rbw, FractureMo
return;
}
+ if (ELEM(NULL, rbc->mi1->rigidbody, rbc->mi2->rigidbody)) {
+ return;
+ }
+
if (rbc->physics_constraint) {
if (rebuild == false)
{
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index bfbd1745326..5ccd254a9ea 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -2608,8 +2608,8 @@ static void connect_meshislands(FractureModifierData *fmd, MeshIsland *mi1, Mesh
bool ok = mi1 && mi1->rigidbody;
ok = ok && mi2 && mi2->rigidbody;
ok = ok && fmd->use_constraints;
- ok = ok && (!(fmd->dm_group && fmd->use_constraint_group) ||
- (fmd->dm_group && fmd->use_constraint_group && mi1->object_index != mi2->object_index));
+ ok = ok && ((!(fmd->dm_group && fmd->use_constraint_group) && (mi1->object_index == -1) && (mi2->object_index == -1))||
+ (fmd->dm_group && fmd->use_constraint_group && (mi1->object_index != mi2->object_index)));
if (ok) {
/* search local constraint list instead of global one !!! saves lots of time */
@@ -2771,6 +2771,7 @@ static int prepareConstraintSearch(FractureModifierData *rmd, MeshIsland ***mesh
if (fmdi) {
for (mi = fmdi->meshIslands.first; mi; mi = mi->next) {
mi->object_index = j;
+ sprintf(mi->name, "%d", j);
(*mesh_islands)[i] = mi;
i++;
}
@@ -2783,7 +2784,8 @@ st
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list