Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp')
-rw-r--r--extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp324
1 files changed, 324 insertions, 0 deletions
diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp
new file mode 100644
index 00000000000..e3603ccec67
--- /dev/null
+++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "ContactConstraint.h"
+#include "Dynamics/RigidBody.h"
+#include "SimdVector3.h"
+#include "JacobianEntry.h"
+#include "ContactSolverInfo.h"
+#include "GEN_minmax.h"
+
+#define ASSERT2 assert
+
+
+static SimdScalar ContactThreshold = -10.0f;
+
+float useGlobalSettingContacts = false;//true;
+
+SimdScalar contactDamping = 0.9f;
+SimdScalar contactTau = .2f;//0.02f;//*0.02f;
+
+
+
+SimdScalar restitutionCurve(SimdScalar rel_vel, SimdScalar restitution)
+{
+ return restitution;
+// return restitution * GEN_min(1.0f, rel_vel / ContactThreshold);
+}
+
+void applyFrictionInContactPointOld(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ const SimdVector3& normal,float normalImpulse,
+ const ContactSolverInfo& solverInfo)
+{
+
+
+ if (normalImpulse>0.f)
+ {
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ SimdScalar rel_vel = normal.dot(vel);
+
+#define PER_CONTACT_FRICTION
+#ifdef PER_CONTACT_FRICTION
+ SimdVector3 lat_vel = vel - normal * rel_vel;
+ SimdScalar lat_rel_vel = lat_vel.length();
+
+ if (lat_rel_vel > SIMD_EPSILON)
+ {
+ lat_vel /= lat_rel_vel;
+ SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel);
+ SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel);
+ SimdScalar frictionMaxImpulse = lat_rel_vel /
+ (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+ SimdScalar frictionImpulse = (normalImpulse) * solverInfo.m_friction;
+ GEN_set_min(frictionImpulse,frictionMaxImpulse );
+
+ body1.applyImpulse(lat_vel * -frictionImpulse, rel_pos1);
+ body2.applyImpulse(lat_vel * frictionImpulse, rel_pos2);
+
+ }
+#endif
+ }
+}
+
+
+//bilateral constraint between two dynamic objects
+void resolveSingleBilateral(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,SimdScalar& impulse ,float timeStep)
+{
+ float normalLenSqr = normal.length2();
+ ASSERT2(fabs(normalLenSqr) < 1.1f);
+ if (normalLenSqr > 1.1f)
+ {
+ impulse = 0.f;
+ return;
+ }
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ SimdScalar rel_vel;
+
+ /*
+
+ JacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
+ body2.getCenterOfMassTransform().getBasis().transpose(),
+ rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(),
+ body2.getInvInertiaDiagLocal(),body2.getInvMass());
+
+ SimdScalar jacDiagAB = jac.getDiagonal();
+ SimdScalar jacDiagABInv = 1.f / jacDiagAB;
+
+ SimdScalar rel_vel = jac.getRelativeVelocity(
+ body1.getLinearVelocity(),
+ body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(),
+ body2.getLinearVelocity(),
+ body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity());
+ float a;
+ a=jacDiagABInv;
+
+ */
+ rel_vel = normal.dot(vel);
+
+
+
+
+ /*int color = 255+255*256;
+
+ DrawRasterizerLine(pos1,pos1+normal,color);
+*/
+
+
+ SimdScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass());
+
+ float contactDamping = 0.9f;
+ impulse = - contactDamping * rel_vel * massTerm;//jacDiagABInv;
+
+ //SimdScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv;
+ //impulse = velocityImpulse;
+
+}
+
+
+
+
+
+//velocity + friction
+//response between two dynamic objects with friction
+float resolveSingleCollision(RigidBody& body1, const SimdVector3& pos1,
+ RigidBody& body2, const SimdVector3& pos2,
+ SimdScalar depth, const SimdVector3& normal,
+ const ContactSolverInfo& solverInfo
+ )
+{
+
+ float normalLenSqr = normal.length2();
+ ASSERT2(fabs(normalLenSqr) < 1.1f);
+ if (normalLenSqr > 1.1f)
+ return 0.f;
+
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+ SimdScalar rel_vel;
+ rel_vel = normal.dot(vel);
+
+// if (rel_vel< 0.f)//-SIMD_EPSILON)
+// {
+ SimdScalar rest = restitutionCurve(rel_vel, solverInfo.m_restitution);
+
+ SimdScalar timeCorrection = 1.f;///timeStep;
+ float damping = solverInfo.m_damping ;
+ float tau = solverInfo.m_tau;
+
+ if (useGlobalSettingContacts)
+ {
+ damping = contactDamping;
+ tau = contactTau;
+ }
+
+ if (depth < 0.f)
+ return 0.f;//bdepth = 0.f;
+
+ SimdScalar penetrationImpulse = (depth*tau*timeCorrection);// * massTerm;//jacDiagABInv
+
+ SimdScalar velocityImpulse = -(1.0f + rest) * damping * rel_vel;
+
+ SimdScalar impulse = penetrationImpulse + velocityImpulse;
+ SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(normal);
+ SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(normal);
+ impulse /=
+ (body1.getInvMass() + body2.getInvMass() + normal.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+
+ if (impulse > 0.f)
+ {
+
+ body1.applyImpulse(normal*(impulse), rel_pos1);
+ body2.applyImpulse(-normal*(impulse), rel_pos2);
+ } else
+ {
+ impulse = 0.f;
+ }
+
+ return impulse;//velocityImpulse;//impulse;
+
+}
+
+
+
+//velocity + friction
+//response between two dynamic objects with friction
+float resolveSingleCollisionWithFriction(
+
+ RigidBody& body1,
+ const SimdVector3& pos1,
+ RigidBody& body2,
+ const SimdVector3& pos2,
+ SimdScalar depth,
+ const SimdVector3& normal,
+
+ const ContactSolverInfo& solverInfo
+ )
+{
+ float normalLenSqr = normal.length2();
+ ASSERT2(fabs(normalLenSqr) < 1.1f);
+ if (normalLenSqr > 1.1f)
+ return 0.f;
+
+ SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
+ SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ JacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
+ body2.getCenterOfMassTransform().getBasis().transpose(),
+ rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(),
+ body2.getInvInertiaDiagLocal(),body2.getInvMass());
+
+ SimdScalar jacDiagAB = jac.getDiagonal();
+ SimdScalar jacDiagABInv = 1.f / jacDiagAB;
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+SimdScalar rel_vel;
+ /* rel_vel = jac.getRelativeVelocity(
+ body1.getLinearVelocity(),
+ body1.getTransform().getBasis().transpose() * body1.getAngularVelocity(),
+ body2.getLinearVelocity(),
+ body2.getTransform().getBasis().transpose() * body2.getAngularVelocity());
+*/
+ rel_vel = normal.dot(vel);
+
+// if (rel_vel< 0.f)//-SIMD_EPSILON)
+// {
+ SimdScalar rest = restitutionCurve(rel_vel, solverInfo.m_restitution);
+// SimdScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass());
+
+ SimdScalar timeCorrection = 0.5f / solverInfo.m_timeStep ;
+
+ float damping = solverInfo.m_damping ;
+ float tau = solverInfo.m_tau;
+
+ if (useGlobalSettingContacts)
+ {
+ damping = contactDamping;
+ tau = contactTau;
+ }
+ SimdScalar penetrationImpulse = (depth* tau *timeCorrection) * jacDiagABInv;
+
+ if (penetrationImpulse < 0.f)
+ penetrationImpulse = 0.f;
+
+
+
+ SimdScalar velocityImpulse = -(1.0f + rest) * damping * rel_vel * jacDiagABInv;
+
+ SimdScalar friction_impulse = 0.f;
+
+ if (velocityImpulse <= 0.f)
+ velocityImpulse = 0.f;
+
+// SimdScalar impulse = penetrationImpulse + velocityImpulse;
+ //if (impulse > 0.f)
+ {
+// SimdVector3 impulse_vector = normal * impulse;
+ body1.applyImpulse(normal*(velocityImpulse+penetrationImpulse), rel_pos1);
+
+ body2.applyImpulse(-normal*(velocityImpulse+penetrationImpulse), rel_pos2);
+
+ //friction
+
+ {
+
+ SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+ SimdVector3 vel = vel1 - vel2;
+
+ rel_vel = normal.dot(vel);
+
+#define PER_CONTACT_FRICTION
+#ifdef PER_CONTACT_FRICTION
+ SimdVector3 lat_vel = vel - normal * rel_vel;
+ SimdScalar lat_rel_vel = lat_vel.length();
+
+ if (lat_rel_vel > SIMD_EPSILON)
+ {
+ lat_vel /= lat_rel_vel;
+ SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel);
+ SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel);
+ friction_impulse = lat_rel_vel /
+ (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+ SimdScalar normal_impulse = (penetrationImpulse+
+ velocityImpulse) * solverInfo.m_friction;
+ GEN_set_min(friction_impulse, normal_impulse);
+
+ body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1);
+ body2.applyImpulse(lat_vel * friction_impulse, rel_pos2);
+
+ }
+#endif
+ }
+ }
+ return velocityImpulse + friction_impulse;
+}