Commit: cd6e18db8ae9be5340b1397ba8c88d0c03cf3458
Author: Martin Felke
Date:   Mon Mar 6 19:24:55 2017 +0100
Branches: fracture_modifier
https://developer.blender.org/rBcd6e18db8ae9be5340b1397ba8c88d0c03cf3458

added handlers which are triggered after freeing shards and before rebuilding 
constraints

this is supposed to keep externally loaded data in place when changing over to 
dynamic fracture, the handler triggers a python script which populates the 
meshislands and another to populate the constraints via the FM python API.
Additionally a couple of minor fixes for dynamic fracturing.

===================================================================

M       extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
M       source/blender/blenkernel/intern/rigidbody.c
M       source/blender/blenlib/BLI_callbacks.h
M       source/blender/modifiers/intern/MOD_fracture.c
M       source/blender/python/intern/bpy_app_handlers.c

===================================================================

diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h 
b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
index ef2a29202f..beb6eb3964 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
@@ -80,6 +80,11 @@ class btUnionFind
 
                void unite(int p, int q)
                {
+                       if (p == -1 && q == -1) {
+                               //error case... should not happen but happens ?
+                               return;
+                       }
+
                        int i = find(p), j = find(q);
                        if (i == j) 
                                return;
diff --git a/source/blender/blenkernel/intern/rigidbody.c 
b/source/blender/blenkernel/intern/rigidbody.c
index ce0f7192de..3a3eb6ab68 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1774,7 +1774,7 @@ static void 
rigidbody_create_shard_physics_constraint(FractureModifierData* fmd,
                return;
        }
 
-       if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL)
+       if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL || fmd->fracture_mode 
== MOD_FRACTURE_DYNAMIC)
        {
                mul_v3_m4v3(loc, ob->obmat, rbc->pos);
                mat4_to_quat(rot, ob->obmat);
@@ -1845,7 +1845,7 @@ static void 
rigidbody_create_shard_physics_constraint(FractureModifierData* fmd,
                        case RBC_TYPE_6DOF_SPRING:
                                rbc->physics_constraint = 
RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
 
-                               if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL)
+                               if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL 
|| fmd->fracture_mode == MOD_FRACTURE_DYNAMIC)
                                {
                                        if ((rbc->plastic_angle < 0.0f) && 
(rbc->plastic_dist < 0.0f))
                                        {
@@ -1970,6 +1970,11 @@ void 
BKE_rigidbody_validate_sim_shard_constraint(RigidBodyWorld *rbw, FractureMo
                return;
        }
 
+       if (rbc->mi1 == rbc->mi2) {
+               //owch, this happened... better check for sanity  here
+               return;
+       }
+
        if (rbc->physics_constraint) {
                if (rebuild == false)
                {
@@ -2298,12 +2303,28 @@ static bool check_shard_size(FractureModifierData *fmd, 
int id)
        return true;
 }
 
-static bool check_constraints(FractureModifierData *fmd, MeshIsland *mi) {
+static bool check_constraints(FractureModifierData *fmd, MeshIsland *mi, 
RigidBodyWorld *rbw) {
        //count broken constraints
        RigidBodyShardCon *con;
+       GroupObject* go;
        int i = 0, broken = 0;
        float percentage;
 
+       if (rbw && rbw->constraints) {
+               //delete outer constraints here, to be sure
+               for (go = rbw->constraints->gobject.first; go; go = go->next) {
+                       RigidBodyCon *rbc = go->ob->rigidbody_constraint;
+                       FractureModifierData *fmd1 = 
(FractureModifierData*)modifiers_findByType(rbc->ob1, eModifierType_Fracture);
+                       FractureModifierData *fmd2 = 
(FractureModifierData*)modifiers_findByType(rbc->ob2, eModifierType_Fracture);
+
+                       if ((rbc && rbc->physics_constraint && rbw && 
rbw->physics_world) && ((fmd1 == fmd) || (fmd2 == fmd))) {
+                               RB_dworld_remove_constraint(rbw->physics_world, 
rbc->physics_constraint);
+                               RB_constraint_delete(rbc->physics_constraint);
+                               rbc->physics_constraint = NULL;
+                       }
+               }
+       }
+
        if (mi->participating_constraint_count == 0) {
                return true;
        }
@@ -2384,16 +2405,16 @@ static void check_fracture(rbContactPoint* cp, 
RigidBodyWorld *rbw, Object *obA,
                                //printf("FORCE1:%f\n",force);
                                bool canbreak = (force > fmd1->dynamic_force) 
|| ((fmd1->limit_impact || obB) && can_break(ob2, ob1, fmd1->limit_impact));
 
-                               if (canbreak && check_constraints(fmd1, mi))
+                               if (canbreak && check_constraints(fmd1, mi, 
rbw))
                                {
                                        if (s) {
-                                               float size[3];
+                                               float size[3] =  {1.0f, 1.0f, 
1.0f};
 
-                                               if (ob1 == ob2 || 
(ob2->rigidbody_object && ob1->rigidbody_object->type == RBO_TYPE_PASSIVE)) {
+                                               if (ob1 == ob2 || (ob2 && 
ob2->rigidbody_object && ob1->rigidbody_object->type == RBO_TYPE_PASSIVE)) {
                                                        //todo calculate 
shard...
                                                        size[0] = size[1] = 
size[2] = -1.0f;
                                                }
-                                               else {
+                                               else if (ob2) {
                                                        
BKE_object_dimensions_get(ob2, size);
                                                }
 
@@ -2439,15 +2460,15 @@ static void check_fracture(rbContactPoint* cp, 
RigidBodyWorld *rbw, Object *obA,
                                //printf("FORCE2:%f\n",force);
                                bool canbreak = (force > fmd2->dynamic_force) 
|| ((fmd2->limit_impact || obA) && can_break(ob1, ob2, fmd2->limit_impact));
 
-                               if (canbreak && check_constraints(fmd2, mi))
+                               if (canbreak && check_constraints(fmd2, mi, 
rbw))
                                {
                                        if (s) {
-                                               float size[3];
+                                               float size[3] = {1.0f, 1.0f, 
1.0f};
 
-                                               if (ob1 == ob2 || 
(ob1->rigidbody_object && ob1->rigidbody_object->type == RBO_TYPE_PASSIVE)) {
+                                               if (ob1 == ob2 || (ob1 && 
ob1->rigidbody_object && ob1->rigidbody_object->type == RBO_TYPE_PASSIVE)) {
                                                        size[0] = size[1] = 
size[2] = -1.0f;
                                                }
-                                               else {
+                                               else if (ob1) {
                                                        
BKE_object_dimensions_get(ob1, size);
                                                }
                                                copy_v3_v3(s->impact_loc, 
cp->contact_pos_world_onB);
@@ -4022,7 +4043,7 @@ static bool do_update_modifier(Scene* scene, Object* ob, 
RigidBodyWorld *rbw, bo
                                
RB_constraint_set_enabled(rbsc->physics_constraint, rbsc->flag & 
RBC_FLAG_ENABLED);
                                rbsc->flag |= RBC_FLAG_NEEDS_VALIDATE;
 
-                               if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL 
&& rbsc->type == RBC_TYPE_6DOF_SPRING)
+                               if ((fmd->fracture_mode == 
MOD_FRACTURE_EXTERNAL || fmd->fracture_mode == MOD_FRACTURE_DYNAMIC) && 
rbsc->type == RBC_TYPE_6DOF_SPRING)
                                {
                                        if (rbsc->plastic_angle >= 0.0f || 
rbsc->plastic_dist >= 0.0f)
                                        {
@@ -4049,7 +4070,7 @@ static bool do_update_modifier(Scene* scene, Object* ob, 
RigidBodyWorld *rbw, bo
                                rbsc->mi2->rigidbody->flag & 
RBO_FLAG_KINEMATIC_REBUILD) {
                                /* World has been rebuilt so rebuild constraint 
*/
                                
BKE_rigidbody_validate_sim_shard_constraint(rbw, fmd, ob, rbsc, true);
-                               BKE_rigidbody_start_dist_angle(rbsc, 
fmd->fracture_mode == MOD_FRACTURE_EXTERNAL);
+                               BKE_rigidbody_start_dist_angle(rbsc, 
fmd->fracture_mode == MOD_FRACTURE_EXTERNAL || fmd->fracture_mode == 
MOD_FRACTURE_DYNAMIC);
                                //TODO ensure evaluation on transform change too
                        }
 
@@ -4064,7 +4085,7 @@ static bool do_update_modifier(Scene* scene, Object* ob, 
RigidBodyWorld *rbw, bo
                                handle_regular_breaking(fmd, ob, rbw, rbsc, 
max_con_mass, rebuild);
                        }
 
-                       if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL && 
(rbsc->flag & RBC_FLAG_USE_BREAKING) && !rebuild)
+                       if ((fmd->fracture_mode == MOD_FRACTURE_EXTERNAL || 
fmd->fracture_mode == MOD_FRACTURE_DYNAMIC) && (rbsc->flag & 
RBC_FLAG_USE_BREAKING) && !rebuild)
                        {
                                handle_plastic_breaking(rbsc, rbw, laststeps, 
lastscale);
                        }
@@ -4366,7 +4387,7 @@ static bool do_sync_modifier(ModifierData *md, Object 
*ob, RigidBodyWorld *rbw,
                        {
                                int frame = (int)ctime;
 
-                               if (BKE_lookup_mesh_state(fmd, frame, true));
+                               if (BKE_lookup_mesh_state(fmd, frame, true))
                                {
                                        BKE_rigidbody_update_ob_array(rbw, 
false);
                                }
@@ -4708,6 +4729,13 @@ static void resetDynamic(RigidBodyWorld *rbw, bool 
do_reset_always)
                                {
                                        const ModifierTypeInfo *mti = 
modifierType_getInfo(md->type);
 
+                                       /*if (md == (ModifierData*)fmd)
+                                       {
+                                               BLI_mutex_unlock(&reset_lock);
+                                               found = true;
+                                               break;
+                                       }*/
+
                                        if (!found)
                                        {
                                                if (mti->deformVerts && 
(md->mode & (eModifierMode_Realtime | eModifierMode_Render)))
diff --git a/source/blender/blenlib/BLI_callbacks.h 
b/source/blender/blenlib/BLI_callbacks.h
index c51c3e6db4..c11d7e6f7f 100644
--- a/source/blender/blenlib/BLI_callbacks.h
+++ b/source/blender/blenlib/BLI_callbacks.h
@@ -55,6 +55,8 @@ typedef enum {
        BLI_CB_EVT_GAME_POST,
        BLI_CB_EVT_VERSION_UPDATE,
        BLI_CB_EVT_BULLET_TICK,
+       BLI_CB_EVT_FRACTURE_REFRESH,
+       BLI_CB_EVT_FRACTURE_CONSTRAINT_REFRESH,
        BLI_CB_EVT_TOT
 } eCbEvent;
 
diff --git a/source/blender/modifiers/intern/MOD_fracture.c 
b/source/blender/modifiers/intern/MOD_fracture.c
index 5dbf67bcf0..e2c412ae2b 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -32,6 +32,7 @@
 //#include "BLI_string_utf8.h"
 #include "MEM_guardedalloc.h"
 
+#include "BLI_callbacks.h"
 #include "BLI_edgehash.h"
 #include "BLI_ghash.h"
 #include "BLI_kdtree.h"
@@ -3733,7 +3734,17 @@ static void do_refresh_constraints(FractureModifierData 
*fmd, Object *ob)
        start = PIL_check_seconds_timer();
 
        if (fmd->use_constraints) {
-               create_constraints(fmd, ob); /* check for actually creating the 
constraints inside*/
+               int count = 0;
+
+               /* fire a callback which can then load external constraint data 
right NOW */
+               BLI_callback_exec(G.main, &ob->id, 
BLI_CB_EVT_FRACTURE_CONSTRAINT_REFRESH);
+
+               /*if we loaded constraints, dont create other ones now */
+               count = BLI_listbase_count(&fmd->meshConstraints);
+
+               if (count == 0 || fmd->dynamic_new_constraints != 
MOD_FRACTURE_NO_DYNAMIC_CONSTRAINTS) {
+                       create_constraints(fmd, ob); /* check for actually 
creating the constraints inside*/
+               }
        }
        fmd->refresh_constraints = false;
 
@@ -3888,7 +3899,7 @@ static void do_island_index_map(FractureModifierData *fmd)
 }
 
 
-static DerivedMesh *doSimulate(FractureModifierData *fmd, Object *ob, 
DerivedMesh *dm, DerivedMesh *orig_dm)
+static DerivedMesh *doSimulate(FractureModifierData *fmd, Object *ob, 
DerivedMesh *dm, DerivedMesh *orig_dm, char names [][66], int count)
 {
        bool exploOK = false; /* doFracture */
 
@@ -3900,8 +3911,7 @@ static DerivedMesh *doSimulate(FractureModifierData *fmd, 
Object *ob, DerivedMes
                        //(fmd->refresh_constraints && fmd->execute_threaded && 
fmd->frac_mesh && fmd->frac_mesh->running == 0))
                {
                        DerivedMesh *old_cached = NULL;
-
-                       if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC) {
+                       if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC && 
fmd->visible_mesh_cached) {
                                //keep a copy around for fade value setting
                                old_cached = 
CDDM_copy(fmd->visible_mesh_cached);
                        }
@@ -3922,6 +3932,18 @@ static DerivedMesh *doSimulate(FractureModifierData 
*fmd, Object *ob, DerivedMes
 
                        if (fmd->refresh) {
                                do_refresh(fmd, ob, dm, orig_dm, old_cached);
+
+                               if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC 
&& names)
+                               {
+                                       MeshIsland *mi;
+                                       int i = 0;
+                                       for (mi = fmd->meshIslands.first; mi; 
mi = mi->next) {
+                                               if (i < count) {
+                                                       BLI_snprintf(mi->name, 
sizeof(names[i]), "%s", names[i]);
+                                               }
+                                               i++;
+                                       }
+                               }
                        

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to