[Bf-blender-cvs] [45dbc3d] fracture_modifier: attempt to make compounds a bit more predictable, they should work now when colliding with passive objects too
Martin Felke
noreply at git.blender.org
Sat Mar 26 16:07:34 CET 2016
Commit: 45dbc3d19c8b35acd06cc53159db1531d156f3b1
Author: Martin Felke
Date: Sat Mar 26 16:07:04 2016 +0100
Branches: fracture_modifier
https://developer.blender.org/rB45dbc3d19c8b35acd06cc53159db1531d156f3b1
attempt to make compounds a bit more predictable, they should work now when colliding with passive objects too
===================================================================
M extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
M extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
M extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
M extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
M intern/rigidbody/RBI_api.h
M intern/rigidbody/rb_bullet_api.cpp
M source/blender/blenkernel/intern/rigidbody.c
===================================================================
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
index 7eaf035..a846cf7 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.cpp
@@ -7,6 +7,32 @@
#include "BulletDynamics/Dynamics/btFractureDynamicsWorld.h"
+class btConnectionSortPredicate
+{
+ public:
+
+ bool operator() ( const btConnection& lhs, const btConnection& rhs ) const
+ {
+ btVector3 locLhsA = lhs.m_parent->getWorldTransform().inverse() * lhs.m_obA->getWorldTransform().getOrigin();
+ btVector3 locLhsB = lhs.m_parent->getWorldTransform().inverse() * lhs.m_obB->getWorldTransform().getOrigin();
+
+ btVector3 locRhsA = rhs.m_parent->getWorldTransform().inverse() * rhs.m_obA->getWorldTransform().getOrigin();
+ btVector3 locRhsB = rhs.m_parent->getWorldTransform().inverse() * rhs.m_obB->getWorldTransform().getOrigin();
+
+ btVector3 locLhs = (locLhsA + locLhsB) * 0.5f;
+ btVector3 locRhs = (locRhsA + locRhsB) * 0.5f;
+
+ //lhs.parent should match rhs.parent... same object
+ btScalar dLhs = lhs.m_parent->getWorldTransform().getOrigin().distance(locLhs);
+ btScalar dRhs = rhs.m_parent->getWorldTransform().getOrigin().distance(locRhs);
+ //btTransform id = btTransform::getIdentity();
+ //btScalar dLhs = id.getOrigin().distance(locLhs);
+ //btScalar dRhs = id.getOrigin().distance(locRhs);
+
+ return dLhs < dRhs;
+ }
+};
+
void btFractureBody::recomputeConnectivity(btCollisionWorld* world)
{
@@ -58,8 +84,6 @@ void btFractureBody::recomputeConnectivity(btCollisionWorld* world)
}
}
}
-
-
}
void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1)
@@ -99,6 +123,10 @@ void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1
tmp.m_childShape0 = obA->getCollisionShape();
tmp.m_childShape1 = obB->getCollisionShape();
tmp.m_strength = con->getBreakingImpulseThreshold();
+ tmp.m_obA = obA;
+ tmp.m_obB = obB;
+ tmp.m_parent = this;
+ tmp.m_id = i;
m_connections.push_back(tmp);
}
@@ -107,6 +135,7 @@ void btFractureBody::recomputeConnectivityByConstraints(btCollisionWorld *world1
}
}
+ m_connections.quickSort(btConnectionSortPredicate());
//build a connection map
m_connection_map->clear();
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
index 6e785e4..92c5bd4 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureBody.h
@@ -32,6 +32,12 @@ struct btConnection
int m_childIndex0;
int m_childIndex1;
btScalar m_strength;
+ //btVector3 m_location; //this must be local to the "Parent" compound
+ //better calc this "live" from the objects themselves, so also keep ob pointers here
+ btCollisionObject* m_obA;
+ btCollisionObject* m_obB;
+ btCollisionObject* m_parent;
+ btScalar m_id;
};
struct btPropagationParameter
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
index a58e003..87fadaa 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
@@ -867,6 +867,7 @@ void btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj)
#include <stdio.h>
+#if 0
void btFractureDynamicsWorld::propagateDamage(btFractureBody *body, btScalar *impulse, int connection_index,
bool* needsBreakingCheck, const btVector3& direction, int* depth)
{
@@ -958,6 +959,7 @@ void btFractureDynamicsWorld::breakNeighborhood(btFractureBody *body, int connec
}
}
}
+#endif
void btFractureDynamicsWorld::fractureCallback( )
{
@@ -1176,7 +1178,7 @@ void btFractureDynamicsWorld::fractureCallback( )
needsBreakingCheck = true;
sFracturePairs[i].m_fracObj->m_connections.remove(connection);
- breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index0);
+ // breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index0);
}
}
}
@@ -1198,7 +1200,7 @@ void btFractureDynamicsWorld::fractureCallback( )
needsBreakingCheck = true;
sFracturePairs[i].m_fracObj->m_connections.remove(connection);
- breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index1);
+ // breakNeighborhood(sFracturePairs[i].m_fracObj, pt.m_index1);
}
}
}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
index 5df2a19..9f62404 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.h
@@ -24,8 +24,6 @@ class btFractureDynamicsWorld : public btDiscreteDynamicsWorld
{
btFractureBody* addNewBody(const btTransform& oldTransform, btScalar* masses, btCompoundShape* oldCompound, btPropagationParameter ¶m);
- void breakDisconnectedParts( btFractureBody* fracObj);
-
bool m_addBroadPhaseHandle;
public:
@@ -75,6 +73,8 @@ public:
void breakNeighborhood(btFractureBody *body, int connection_index);
+ void breakDisconnectedParts( btFractureBody* fracObj);
+
virtual void updateAabbs();
};
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 3499d85..765397f 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -141,7 +141,7 @@ void RB_world_convex_sweep_test(
/* Create new RigidBody instance */
rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4], bool use_compounds, float dampening, float factor,
- float min_impulse, float stability_factor);
+ float min_impulse, float stability_factor, const float bbox[3]);
/* Delete the given RigidBody instance */
void RB_body_delete(rbRigidBody *body);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 265ec4f..2e29995 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -148,6 +148,7 @@ struct rbRigidBody {
int linear_index;
void *meshIsland;
void *blenderOb;
+ btVector3 *bbox;
rbDynamicsWorld *world;
};
@@ -189,12 +190,111 @@ class TickDiscreteDynamicsWorld : public btFractureDynamicsWorld
virtual void debugDrawWorld(draw_string str_callback);
};
+btScalar connection_dist(btFractureBody *fbody, int index, btVector3 impact)
+{
+ btConnection& con = fbody->m_connections[index];
+ btVector3 con_posA = fbody->getWorldTransform().inverse() * con.m_obA->getWorldTransform().getOrigin();
+ btVector3 con_posB = fbody->getWorldTransform().inverse() * con.m_obB->getWorldTransform().getOrigin();
+ btVector3 con_pos = (con_posA + con_posB) * 0.5f;
+
+ return impact.distance(con_pos);
+}
+
+//KDTree needed here, we need a range search of which points are closer than distance x to the impact point
+int connection_binary_search(btFractureBody *fbody, btVector3 impact, btScalar range)
+{
+ int mid, low = 0, high = fbody->m_connections.size();
+
+ while (low <= high) {
+ mid = (low + high)/2;
+
+ if (mid == high-1)
+ return mid;
+
+ btScalar dist = connection_dist(fbody, mid, impact);
+ btScalar dist1 = connection_dist(fbody, mid+1, impact);
+
+ if (dist < range && range <= dist1)
+ {
+ return mid;
+ }
+
+ if (dist >= range)
+ high= mid - 1;
+ else if (dist < range)
+ low= mid + 1;
+ else
+ return mid;
+ }
+
+ return low;
+}
+
+bool weakenCompound(const btCollisionObject *body, btScalar force, btVector3 impact, btFractureDynamicsWorld *world)
+{
+ //just weaken strengths of this obA and obB according to force !
+ if (body->getInternalType() & CUSTOM_FRACTURE_TYPE && force > 0.0f)
+ {
+ btFractureBody *fbody = (btFractureBody*)body;
+ int size = fbody->m_connections.size();
+ bool needs_break = false;
+
+ if (size == 0)
+ return false;
+
+ btVector3 *bbox = ((rbRigidBody*)fbody->getUserPointer())->bbox;
+ btScalar dim = (*bbox)[bbox->maxAxis()] * 2;
+
+ //stop at this limit, distances are sorted... so no closer object will come later
+ //int mid = connection_binary_search(fbody, impact, dim * (1.0f - fbody->m_propagationParameter.m_stability_factor));
+ for (int i = 0; i < size; i++)
+ {
+ btVector3 imp = fbody->getWorldTransform().inverse() * impact;
+ btScalar dist = connection_dist(fbody, i, imp);
+ btConnection& con = fbody->m_connections[i];
+ btScalar lforce = force; //* (1.0f - fbody->m_propagationParameter.m_stability_factor);
+ if (dist > 0.0f)
+ lforce = lforce / dist; // the closer, the higher the force
+
+ if (lforce > fbody->m_propagationParameter.m_minimum_impulse)
+ {
+ if (con.m_strength > 0.0f)
+ {
+ con.m_strength -= lforce;
+ //printf("Damaged connection %d %d with %f\n", fbody->m_connections[i].m_childIndex0,
+ // fbody->m_connections[i].m_childIndex1, force);
+
+ if (con.m_strength <= 0)
+ {
+ con.m_strength = 0;
+ needs_break = true;
+ }
+ }
+ }
+
+ btScalar pdist = connection_dist(fbody, i, fbody->getWorldTransform().getOrigin());
+ if (pdist > (dim * (1.0f - fbody->m_propagationParameter.m_stability_factor)))
+ {
+ break;
+ }
+ }
+
+ if (needs_break)
+ world->breakDisconnectedParts(fbody);
+
+ return needs_break;
+ }
+
+ return false;
+}
+
void tickCallback(btDynamicsWorld *world, btScalar timeStep)
{
btFractureDynamicsWorld *fworld = (btFractureDynamicsWorld*)world;
fworld->updateBodies();
TickDiscreteDynamicsWorld* tworld = (TickDiscreteDynamicsWorld*)world;
+ bool broken = false;
int numManifolds = world->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
@@ -216,12 +316,21 @@ void tickCallback(btDynamicsWorld *world, btScalar timeStep)
//TickDiscreteDynamicsWorld* tworld = (TickDiscreteDynamicsWorld*)world;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list