[Bf-blender-cvs] [026b847bd9f] fracture_modifier: refactored acceleration map, but might still have issues
Martin Felke
noreply at git.blender.org
Fri Dec 29 01:47:04 CET 2017
Commit: 026b847bd9f830fc4cc3307f2154a8e55fa5225a
Author: Martin Felke
Date: Fri Dec 29 01:46:36 2017 +0100
Branches: fracture_modifier
https://developer.blender.org/rB026b847bd9f830fc4cc3307f2154a8e55fa5225a
refactored acceleration map, but might still have issues
also attempted to improve triggering (make exacter, but slow and error prone)
===================================================================
M intern/rigidbody/RBI_api.h
M intern/rigidbody/rb_bullet_api.cpp
M source/blender/blenkernel/BKE_fracture.h
M source/blender/blenkernel/intern/fracture.c
M source/blender/blenkernel/intern/pointcache.c
M source/blender/blenkernel/intern/rigidbody.c
===================================================================
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index da997a38f24..01d27357676 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -188,6 +188,10 @@ void RB_body_set_angular_sleep_thresh(rbRigidBody *body, float value);
void RB_body_set_sleep_thresh(rbRigidBody *body, float linear, float angular);
+/* Force and Torque */
+void RB_body_get_total_force(rbRigidBody *body, float v_out[3]);
+void RB_body_get_total_torque(rbRigidBody *body, float v_out[3]);
+
/* Linear Velocity */
void RB_body_get_linear_velocity(rbRigidBody *body, float v_out[3]);
void RB_body_set_linear_velocity(rbRigidBody *body, const float v_in[3]);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 13e884e180a..54306a1e5f8 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -721,6 +721,9 @@ struct myResultCallback : public btCollisionWorld::ClosestRayResultCallback
}
};
+#define MIN2(a, b) ((a) < (b) ? (a) : (b))
+#define MIN3(a, b, c) (MIN2(MIN2((a), (b)), (c)))
+
struct rbFilterCallback : public btOverlapFilterCallback
{
int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2, bool activate);
@@ -736,80 +739,55 @@ struct rbFilterCallback : public btOverlapFilterCallback
collides = collides && (rb0->col_groups & rb1->col_groups);
if (this->callback != NULL) {
- int result = 0;
-#if 0
- //cast ray from centroid of 1 rigidbody to another, do this only for mesh shapes (all other can use standard bbox)
+
int stype0 = rb0->body->getCollisionShape()->getShapeType();
int stype1 = rb1->body->getCollisionShape()->getShapeType();
- bool nonMeshShape0 = (stype0 != GIMPACT_SHAPE_PROXYTYPE) && (stype0 != TRIANGLE_MESH_SHAPE_PROXYTYPE);
- bool nonMeshShape1 = (stype1 != GIMPACT_SHAPE_PROXYTYPE) && (stype1 != TRIANGLE_MESH_SHAPE_PROXYTYPE);
+ bool meshShape0 = (stype0 == GIMPACT_SHAPE_PROXYTYPE) || (stype0 == TRIANGLE_MESH_SHAPE_PROXYTYPE);
+ bool meshShape1 = (stype1 == GIMPACT_SHAPE_PROXYTYPE) || (stype1 == TRIANGLE_MESH_SHAPE_PROXYTYPE);
- if ((rb0->meshIsland != NULL) ^ (rb1->meshIsland != NULL))
+ if (rb0->blenderOb != rb1->blenderOb && (meshShape0 || meshShape1))
{
btVector3 v0, v1;
- rbRigidBody* rb2 = NULL;
- bool valid = false;
+ v0 = rb0->body->getWorldTransform().getOrigin();
+ v1 = rb1->body->getWorldTransform().getOrigin();
+ float maxbound1 = MIN3(rb0->bbox->x(), rb0->bbox->y(), rb0->bbox->z());
+ float maxbound2 = MIN3(rb1->bbox->x(), rb1->bbox->y(), rb1->bbox->z());
+ float bound = maxbound1;
- if (rb0->meshIsland != NULL)
+ if (maxbound2 < maxbound1)
{
- v0 = rb0->body->getWorldTransform().getOrigin();
- v1 = rb1->body->getWorldTransform().getOrigin();
- }
- else if (rb1->meshIsland != NULL)
- {
- v0 = rb1->body->getWorldTransform().getOrigin();
- v1 = rb0->body->getWorldTransform().getOrigin();
+ bound = maxbound2;
}
myResultCallback cb(v0, v1);
rb0->world->dynamicsWorld->rayTest(v0, v1, cb);
- if (cb.m_collisionObject != NULL)
+ if (cb.m_collisionObject)
{
- rb2 = (rbRigidBody*)cb.m_collisionObject->getUserPointer();
- }
- else
- {
- valid = false;
- }
-
- if (rb0->meshIsland != NULL && rb2 != NULL)
- {
- valid = rb2->blenderOb != rb0->blenderOb;
- }
- else if (rb1->meshIsland != NULL && rb2 != NULL)
- {
- valid = rb2->blenderOb != rb1->blenderOb;
- }
-
- if (rb0->meshIsland != NULL)
- {
- valid = valid || nonMeshShape1;
- }
- else if (rb1->meshIsland != NULL)
- {
- valid = valid || nonMeshShape0;
- }
-
+ float dist_sq = (v0 - cb.m_collisionObject->getWorldTransform().getOrigin()).length2();
+ //float dist_sq2 = (v0 - v1).length2();
+ float dist_sq2 = bound * bound;
+ if (dist_sq < dist_sq2)
+ {
+ int result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland,
+ rb0->blenderOb, rb1->blenderOb, activate);
- if (valid)
- {
- result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb);
+ collides = collides && (bool)result;
+ }
+ else
+ {
+ collides = false;
+ }
}
- else
- {
- //just check for ghost flags and collision groups there
- result = this->callback(NULL, NULL, NULL, rb0->blenderOb, rb1->blenderOb);
+ else {
+ collides = false;
}
}
- else
- {
- result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb);
- }
+ else {
+ int result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland,
+ rb0->blenderOb, rb1->blenderOb, activate && (rb0->blenderOb != rb1->blenderOb));
- collides = collides && (bool)result;
-#endif
- result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb, activate);
- collides = collides && (bool)result;
+ collides = collides && (bool)result;
+ }
}
return collides;
@@ -1360,6 +1338,21 @@ void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
/* ............ */
+void RB_body_get_total_force(rbRigidBody *object, float v_out[3])
+{
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getTotalForce());
+}
+
+void RB_body_get_total_torque(rbRigidBody *object, float v_out[3])
+{
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getTotalTorque());
+}
+
+
void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
{
btRigidBody *body = object->body;
diff --git a/source/blender/blenkernel/BKE_fracture.h b/source/blender/blenkernel/BKE_fracture.h
index 82f1b9031b4..a1f0b009b9e 100644
--- a/source/blender/blenkernel/BKE_fracture.h
+++ b/source/blender/blenkernel/BKE_fracture.h
@@ -126,5 +126,6 @@ short BKE_fracture_collect_materials(struct Object* o, struct Object* ob, int ma
void BKE_bm_mesh_hflag_flush_vert(struct BMesh *bm, const char hflag);
void BKE_meshisland_constraint_create(struct FractureModifierData* fmd, struct MeshIsland *mi1, struct MeshIsland *mi2, int con_type, float thresh);
+void BKE_update_acceleration_map(struct FractureModifierData *fmd, struct MeshIsland* mi, struct Object* ob, int ctime, float acc);
#endif /* BKE_FRACTURE_H */
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index 85fe91270c6..751ea619f35 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -3647,3 +3647,59 @@ void BKE_meshisland_constraint_create(FractureModifierData* fmd, MeshIsland *mi1
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)
+{
+ const int acc_defgrp_index = defgroup_name_index(ob, fmd->acceleration_defgrp_name);
+ DerivedMesh *dm = fmd->visible_mesh_cached;
+ MDeformVert *dvert = NULL, *dv = NULL;
+ MDeformWeight *dw = NULL;
+ float weight = 0.0f, denom;
+ int i = 0, w = 0;
+ int totvert = dm->getNumVerts(dm);
+
+ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+
+ if (dvert == NULL)
+ {
+ dvert = CustomData_add_layer(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC,
+ NULL, totvert);
+ }
+
+ //calculate weight from force...
+ denom = fmd->max_acceleration - fmd->min_acceleration;
+
+ //sanity check
+ if (denom == 0.0f)
+ denom = 1.0f;
+
+ //if (mi->acc_sequence)
+ {
+ weight = (acc - fmd->min_acceleration) / denom;
+
+ if (ctime == mi->start_frame)
+ weight = 0.0f;
+
+ for (i = 0; i < mi->vertex_count; i++)
+ {
+ dv = dvert + mi->vertex_indices[i];
+ if (dv) {
+ if (dv->dw == NULL && acc_defgrp_index >= 0) {
+ defvert_add_index_notest(dv, acc_defgrp_index, 0.0f);
+ }
+
+ for (dw = dv->dw, w = 0; w < dv->totweight; dw++, w++)
+ {
+ if (dw->def_nr == acc_defgrp_index) {
+
+ if (weight >= 0.0f && weight <= 1.0f) {
+ dw->weight = weight;
+ }
+
+ dw->weight *= fmd->acceleration_fade;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 4841fa1444d..14c481105fe 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1324,6 +1324,37 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int cfra
{
if ((!fmd || fmd->fracture_mode != MOD_FRACTURE_DYNAMIC) && rbo->type == RBO_TYPE_ACTIVE)
{
+ MeshIsland *mi = NULL;
+
+ if (fmd && fmd->acceleration_defgrp_name[0])
+ {
+ mi = find_meshisland(fmd, rbo->meshisland_index);
+ if (cfra >= mi->start_frame && cfra <= mi->frame_count) {
+ float lastvel = 0.0f;
+ float vel = 0.0f;
+ float linvel[3] = {0.0f, 0.0f, 0.0f};
+ float angvel[3] = {0.0f, 0.0f, 0.0f};
+ float acc = 0.0f;
+
+ //rough framewise estimate of total force
+ if (mi->rigidbody->physics_object)
+ {
+ RB_body_get_linear_velocity(mi->rigidbody->physics_object, linvel);
+ RB_body_get_angular_velocity(mi->rigidbody->physics_object, angvel);
+ vel = len_v3(linvel) + len_v3(angvel);
+ }
+
+ if (cfra >= mi->start_frame + 1)
+ {
+ lastvel = mi->acc_sequence[cfra - mi->start_frame - 1];
+ }
+
+ acc = fabsf(vel - lastvel);
+
+ mi->acc_sequence[cfra - mi->start_frame] = acc;
+ BKE_update_acceleration_map(fmd, mi, ob, cfra, acc);
+ }
+ }
#ifdef WITH_BULLET
RB_body_get_position(rbo->physics_object, rbo->pos);
@@ -1336,7 +1367,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int cfra
{
//MeshIsland *mi = BLI_findlink(&fmd->meshIslands, rbo->meshisland_index);
MeshIsland *mi = find_meshisland(fmd, rbo->meshisland_index);
- int frame = (int)floor(cfra);
+ int frame = cfra;
// if (!mi)
// return 0;
@@ -1399,6 +143
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list