[Bf-blender-cvs] [a2e1051] fracture_modifier: some improvement for dynamic fracture, it now takes location and size of impact object into account with "Limit Impact"
Martin Felke
noreply at git.blender.org
Sun Sep 25 21:38:33 CEST 2016
Commit: a2e105186f0016f98c881aad40396b537908f94a
Author: Martin Felke
Date: Sun Sep 25 21:38:06 2016 +0200
Branches: fracture_modifier
https://developer.blender.org/rBa2e105186f0016f98c881aad40396b537908f94a
some improvement for dynamic fracture, it now takes location and size of impact object into account with "Limit Impact"
===================================================================
M source/blender/blenkernel/intern/rigidbody.c
M source/blender/modifiers/intern/MOD_fracture.c
===================================================================
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index a4d0f50..7dd87ea 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -2030,13 +2030,29 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
return check_colgroup_ghost(ob1, ob2);
}
-static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc[3], Object* collider)
+static bool contains(float loc[3], Object* collider, float point[3], Object* ob, bool limit)
+{
+ float size[3];
+ BKE_object_dimensions_get(collider, size);
+
+ if ((fabsf(loc[0] - point[0]) < size[0]) &&
+ (fabsf(loc[1] - point[1]) < size[1]) &&
+ (fabsf(loc[2] - point[2]) < size[2]))
+ {
+ if (limit && (collider == ob)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+static Shard* findShard(FractureModifierData *fmd, int id)
{
- FractureID *fid;
- float size = 0.1f;
Shard *t = fmd->frac_mesh->shard_map.first;
Shard *s = NULL;
- float dim[3];
while (t)
{
@@ -2049,6 +2065,17 @@ static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc
t = t->next;
}
+ return s;
+}
+
+static bool check_shard_size(FractureModifierData *fmd, int id)
+{
+ FractureID *fid;
+ float size = 0.1f;
+ Shard *s = NULL;
+
+ s = findShard(fmd, id);
+
if (s == NULL)
{
return false;
@@ -2071,15 +2098,6 @@ static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc
}
}
- if (collider)
- {
- //simple calc, take just dimensions here.... will be refined later
- BKE_object_dimensions_get(collider, dim);
-
- copy_v3_v3(s->impact_loc, impact_loc);
- copy_v3_v3(s->impact_size, dim);
- }
-
printf("FRACTURE : %d\n", id);
return true;
@@ -2088,7 +2106,7 @@ static bool check_shard_size(FractureModifierData *fmd, int id, float impact_loc
static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
{
int linear_index1, linear_index2;
- Object* ob1, *ob2;
+ Object* ob1 = NULL, *ob2 = NULL;
int ob_index1, ob_index2;
FractureModifierData *fmd1, *fmd2;
float force;
@@ -2118,14 +2136,25 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
ob1 = rbw->objects[ob_index1];
fmd1 = (FractureModifierData*)modifiers_findByType(ob1, eModifierType_Fracture);
- if (fmd1 && fmd1->fracture_mode == MOD_FRACTURE_DYNAMIC) {
- if (force > fmd1->dynamic_force) {
- if (fmd1->current_shard_entry && fmd1->current_shard_entry->is_new)
+ if (fmd1 && fmd1->fracture_mode == MOD_FRACTURE_DYNAMIC)
+ {
+ if (fmd1->current_shard_entry && fmd1->current_shard_entry->is_new)
+ {
+ int id = rbw->cache_index_map[linear_index1]->meshisland_index;
+ Shard *s = findShard(fmd1, id);
+
+ if (force > fmd1->dynamic_force || (s && ob2 && (fmd1->limit_impact &&
+ contains(cp->contact_pos_world_onA, ob2, s->centroid, ob1, fmd1->limit_impact))))
{
+ if (s) {
+ float size[3];
+ BKE_object_dimensions_get(ob2, size);
+ copy_v3_v3(s->impact_loc, cp->contact_pos_world_onA);
+ copy_v3_v3(s->impact_size, size);
+ }
/*only fracture on new entries, this is necessary because after loading a file
*the pointcache thinks it is empty and a fracture is attempted ! */
- int id = rbw->cache_index_map[linear_index1]->meshisland_index;
- if(check_shard_size(fmd1, id, cp->contact_pos_world_onA, ob2))
+ if (check_shard_size(fmd1, id))
{
FractureID* fid1 = MEM_mallocN(sizeof(FractureID), "contact_callback_fractureid1");
fid1->shardID = rbw->cache_index_map[linear_index1]->meshisland_index;
@@ -2143,12 +2172,24 @@ static void check_fracture(rbContactPoint* cp, RigidBodyWorld *rbw)
//ob2 = rbw->objects[ob_index2];
fmd2 = (FractureModifierData*)modifiers_findByType(ob2, eModifierType_Fracture);
- if (fmd2 && fmd2->fracture_mode == MOD_FRACTURE_DYNAMIC) {
- if (force > fmd2->dynamic_force){
- if (fmd2->current_shard_entry && fmd2->current_shard_entry->is_new)
+ if (fmd2 && fmd2->fracture_mode == MOD_FRACTURE_DYNAMIC)
+ {
+ if (fmd2->current_shard_entry && fmd2->current_shard_entry->is_new)
+ {
+ int id = rbw->cache_index_map[linear_index1]->meshisland_index;
+ Shard *s = findShard(fmd2, id);
+
+ if (force > fmd2->dynamic_force || (ob1 && s && (fmd2->limit_impact &&
+ contains(cp->contact_pos_world_onB, ob1, s->centroid, ob2, fmd2->limit_impact))))
{
- int id = rbw->cache_index_map[linear_index2]->meshisland_index;
- if(check_shard_size(fmd2, id, cp->contact_pos_world_onB, ob1))
+ if (s) {
+ float size[3];
+ BKE_object_dimensions_get(ob1, size);
+ copy_v3_v3(s->impact_loc, cp->contact_pos_world_onB);
+ copy_v3_v3(s->impact_size, size);
+ }
+
+ if (check_shard_size(fmd2, id))
{
FractureID* fid2 = MEM_mallocN(sizeof(FractureID), "contact_callback_fractureid2");
fid2->shardID = id;
diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 22db6a4..b6819ec 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -1167,6 +1167,64 @@ static FracPointCloud get_points_global(FractureModifierData *emd, Object *ob, D
add_v3_v3v3(bmax, max, cent);
add_v3_v3v3(bmin, min, cent);
+ //first impact only, so shard has id 0
+ if (emd->fracture_mode == MOD_FRACTURE_DYNAMIC && emd->limit_impact && id == 0) {
+ //shrink pointcloud container around impact point, to a size
+ Shard *s = BKE_shard_by_id(emd->frac_mesh, 0, fracmesh);
+ if (s != NULL) {
+ float size[3], nmin[3], nmax[3], loc[3], imat[4][4], tmin[3], tmax[3], quat[4];
+ print_v3("Impact Loc\n", s->impact_loc);
+ print_v3("Impact Size\n", s->impact_size);
+
+ //invert_m4_m4(imat, ob->obmat);
+ //mul_v3_m4v3(loc, imat, s->impact_loc);
+ //mat4_to_quat(quat, imat);
+ //sub_v3_v3v3(loc, s->impact_loc, ob->loc);
+ //mul_qt_v3(quat, loc);
+ copy_v3_v3(loc, s->impact_loc);
+ mul_v3_v3fl(size, s->impact_size, 0.5f);
+ sub_v3_v3v3(nmin, loc, size);
+ add_v3_v3v3(nmax, loc, size);
+
+ copy_v3_v3(tmin, min);
+ copy_v3_v3(tmax, max);
+
+ /*mat4_to_quat(quat, ob->obmat);
+ mul_qt_v3(quat, tmin);
+ mul_qt_v3(quat, tmax);
+ add_v3_v3(tmin, ob->loc);
+ add_v3_v3(tmax, ob->loc);*/
+
+ //clamp
+ if (fabsf(tmin[0]) < fabsf(nmin[0])) {
+ nmin[0] = tmin[0];
+ }
+
+ if (fabsf(tmin[1]) < fabsf(nmin[1])) {
+ nmin[1] = tmin[1];
+ }
+
+ if (fabsf(tmin[2]) < fabsf(nmin[2])) {
+ nmin[2] = tmin[2];
+ }
+
+ if (fabsf(tmax[0]) < fabsf(nmax[0])) {
+ nmax[0] = tmax[0];
+ }
+
+ if (fabsf(tmax[1]) < fabsf(nmax[1])) {
+ nmax[1] = tmax[1];
+ }
+
+ if (fabsf(tmax[2]) < fabsf(nmax[2])) {
+ nmax[2] = tmax[2];
+ }
+
+ copy_v3_v3(max, nmax);
+ copy_v3_v3(min, nmin);
+ }
+ }
+
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 ||
@@ -3098,6 +3156,8 @@ static MeshIsland* find_meshisland(ListBase* meshIslands, int id)
return NULL;
}
+
+#if 0
static bool contains(float loc[3], float size[3], float point[3])
{
if ((fabsf(loc[0] - point[0]) < size[0]) &&
@@ -3140,6 +3200,7 @@ void set_rigidbody_type(FractureModifierData *fmd, Shard *s, MeshIsland *mi)
}
}
}
+#endif
static void do_island_from_shard(FractureModifierData *fmd, Object *ob, Shard* s, DerivedMesh *orig_dm,
int i, int thresh_defgrp_index, int ground_defgrp_index, int vertstart)
@@ -3287,10 +3348,10 @@ static void do_island_from_shard(FractureModifierData *fmd, Object *ob, Shard* s
mi->rigidbody->flag = par->rigidbody->flag;
}
- if (fmd->limit_impact)
+ /*if (fmd->limit_impact)
{
set_rigidbody_type(fmd, s, mi);
- }
+ }*/
}
}
@@ -4128,6 +4189,8 @@ static Shard* copy_shard(Shard *s)
t->raw_volume = s->raw_volume;
t->shard_id = s->shard_id;
t->parent_id = s->parent_id;
+ copy_v3_v3(t->impact_loc, s->impact_loc);
+ copy_v3_v3(t->impact_size, s->impact_size);
return t;
}
More information about the Bf-blender-cvs
mailing list