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