use of com.bulletphysics.linearmath.Transform in project bdx by GoranM.
the class Point2PointConstraint method solveConstraint.
@Override
public void solveConstraint(float timeStep) {
Stack stack = Stack.enter();
Vector3f tmp = stack.allocVector3f();
Vector3f tmp2 = stack.allocVector3f();
Vector3f tmpVec = stack.allocVector3f();
Transform centerOfMassA = rbA.getCenterOfMassTransform(stack.allocTransform());
Transform centerOfMassB = rbB.getCenterOfMassTransform(stack.allocTransform());
Vector3f pivotAInW = stack.alloc(pivotInA);
centerOfMassA.transform(pivotAInW);
Vector3f pivotBInW = stack.alloc(pivotInB);
centerOfMassB.transform(pivotBInW);
Vector3f normal = stack.allocVector3f();
normal.set(0f, 0f, 0f);
for (int i = 0; i < 3; i++) {
VectorUtil.setCoord(normal, i, 1f);
float jacDiagABInv = 1f / jac[i].getDiagonal();
Vector3f rel_pos1 = stack.allocVector3f();
rel_pos1.sub(pivotAInW, rbA.getCenterOfMassPosition(tmpVec));
Vector3f rel_pos2 = stack.allocVector3f();
rel_pos2.sub(pivotBInW, rbB.getCenterOfMassPosition(tmpVec));
// this jacobian entry could be re-used for all iterations
Vector3f vel1 = rbA.getVelocityInLocalPoint(rel_pos1, stack.allocVector3f());
Vector3f vel2 = rbB.getVelocityInLocalPoint(rel_pos2, stack.allocVector3f());
Vector3f vel = stack.allocVector3f();
vel.sub(vel1, vel2);
float rel_vel;
rel_vel = normal.dot(vel);
/*
//velocity error (first order error)
btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
m_rbB.getLinearVelocity(),angvelB);
*/
// positional error (zeroth order error)
tmp.sub(pivotAInW, pivotBInW);
//this is the error projected on the normal
float depth = -tmp.dot(normal);
float impulse = depth * setting.tau / timeStep * jacDiagABInv - setting.damping * rel_vel * jacDiagABInv;
float impulseClamp = setting.impulseClamp;
if (impulseClamp > 0f) {
if (impulse < -impulseClamp) {
impulse = -impulseClamp;
}
if (impulse > impulseClamp) {
impulse = impulseClamp;
}
}
appliedImpulse += impulse;
Vector3f impulse_vector = stack.allocVector3f();
impulse_vector.scale(impulse, normal);
tmp.sub(pivotAInW, rbA.getCenterOfMassPosition(tmpVec));
rbA.applyImpulse(impulse_vector, tmp);
tmp.negate(impulse_vector);
tmp2.sub(pivotBInW, rbB.getCenterOfMassPosition(tmpVec));
rbB.applyImpulse(tmp, tmp2);
VectorUtil.setCoord(normal, i, 0f);
}
stack.leave();
}
use of com.bulletphysics.linearmath.Transform in project bdx by GoranM.
the class Point2PointConstraint method buildJacobian.
@Override
public void buildJacobian() {
appliedImpulse = 0f;
Stack stack = Stack.enter();
Vector3f normal = stack.allocVector3f();
normal.set(0f, 0f, 0f);
Matrix3f tmpMat1 = stack.allocMatrix3f();
Matrix3f tmpMat2 = stack.allocMatrix3f();
Vector3f tmp1 = stack.allocVector3f();
Vector3f tmp2 = stack.allocVector3f();
Vector3f tmpVec = stack.allocVector3f();
Transform centerOfMassA = rbA.getCenterOfMassTransform(stack.allocTransform());
Transform centerOfMassB = rbB.getCenterOfMassTransform(stack.allocTransform());
for (int i = 0; i < 3; i++) {
VectorUtil.setCoord(normal, i, 1f);
tmpMat1.transpose(centerOfMassA.basis);
tmpMat2.transpose(centerOfMassB.basis);
tmp1.set(pivotInA);
centerOfMassA.transform(tmp1);
tmp1.sub(rbA.getCenterOfMassPosition(tmpVec));
tmp2.set(pivotInB);
centerOfMassB.transform(tmp2);
tmp2.sub(rbB.getCenterOfMassPosition(tmpVec));
jac[i].init(tmpMat1, tmpMat2, tmp1, tmp2, normal, rbA.getInvInertiaDiagLocal(stack.allocVector3f()), rbA.getInvMass(), rbB.getInvInertiaDiagLocal(stack.allocVector3f()), rbB.getInvMass());
VectorUtil.setCoord(normal, i, 0f);
}
stack.leave();
}
use of com.bulletphysics.linearmath.Transform in project bdx by GoranM.
the class SequentialImpulseConstraintSolver method solveGroupCacheFriendlySetup.
public float solveGroupCacheFriendlySetup(ObjectArrayList<CollisionObject> bodies, int numBodies, ObjectArrayList<PersistentManifold> manifoldPtr, int manifold_offset, int numManifolds, ObjectArrayList<TypedConstraint> constraints, int constraints_offset, int numConstraints, ContactSolverInfo infoGlobal, IDebugDraw debugDrawer) /*,btStackAlloc* stackAlloc*/
{
BulletStats.pushProfile("solveGroupCacheFriendlySetup");
Stack stack = Stack.enter();
int sp = stack.getSp();
try {
if ((numConstraints + numManifolds) == 0) {
// printf("empty\n");
return 0f;
}
PersistentManifold manifold = null;
CollisionObject colObj0 = null, colObj1 = null;
//btRigidBody* rb0=0,*rb1=0;
// //#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
//
// BEGIN_PROFILE("refreshManifolds");
//
// int i;
//
//
//
// for (i=0;i<numManifolds;i++)
// {
// manifold = manifoldPtr[i];
// rb1 = (btRigidBody*)manifold->getBody1();
// rb0 = (btRigidBody*)manifold->getBody0();
//
// manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
//
// }
//
// END_PROFILE("refreshManifolds");
// //#endif //FORCE_REFESH_CONTACT_MANIFOLDS
Transform tmpTrans = stack.allocTransform();
//int sizeofSB = sizeof(btSolverBody);
//int sizeofSC = sizeof(btSolverConstraint);
//if (1)
{
//if m_stackAlloc, try to pack bodies/constraints to speed up solving
// btBlock* sablock;
// sablock = stackAlloc->beginBlock();
// int memsize = 16;
// unsigned char* stackMemory = stackAlloc->allocate(memsize);
// todo: use stack allocator for this temp memory
//int minReservation = numManifolds * 2;
//m_tmpSolverBodyPool.reserve(minReservation);
//don't convert all bodies, only the one we need so solver the constraints
/*
{
for (int i=0;i<numBodies;i++)
{
btRigidBody* rb = btRigidBody::upcast(bodies[i]);
if (rb && (rb->getIslandTag() >= 0))
{
btAssert(rb->getCompanionId() < 0);
int solverBodyId = m_tmpSolverBodyPool.size();
btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
initSolverBody(&solverBody,rb);
rb->setCompanionId(solverBodyId);
}
}
}
*/
//m_tmpSolverConstraintPool.reserve(minReservation);
//m_tmpSolverFrictionConstraintPool.reserve(minReservation);
{
int i;
Vector3f rel_pos1 = stack.allocVector3f();
Vector3f rel_pos2 = stack.allocVector3f();
Vector3f pos1 = stack.allocVector3f();
Vector3f pos2 = stack.allocVector3f();
Vector3f vel = stack.allocVector3f();
Vector3f torqueAxis0 = stack.allocVector3f();
Vector3f torqueAxis1 = stack.allocVector3f();
Vector3f vel1 = stack.allocVector3f();
Vector3f vel2 = stack.allocVector3f();
Vector3f frictionDir1 = stack.allocVector3f();
Vector3f frictionDir2 = stack.allocVector3f();
Vector3f vec = stack.allocVector3f();
Matrix3f tmpMat = stack.allocMatrix3f();
for (i = 0; i < numManifolds; i++) {
manifold = manifoldPtr.getQuick(manifold_offset + i);
colObj0 = (CollisionObject) manifold.getBody0();
colObj1 = (CollisionObject) manifold.getBody1();
int solverBodyIdA = -1;
int solverBodyIdB = -1;
if (manifold.getNumContacts() != 0) {
if (colObj0.getIslandTag() >= 0) {
if (colObj0.getCompanionId() >= 0) {
// body has already been converted
solverBodyIdA = colObj0.getCompanionId();
} else {
solverBodyIdA = tmpSolverBodyPool.size();
SolverBody solverBody = bodiesPool.get();
tmpSolverBodyPool.add(solverBody);
initSolverBody(solverBody, colObj0);
colObj0.setCompanionId(solverBodyIdA);
}
} else {
// create a static body
solverBodyIdA = tmpSolverBodyPool.size();
SolverBody solverBody = bodiesPool.get();
tmpSolverBodyPool.add(solverBody);
initSolverBody(solverBody, colObj0);
}
if (colObj1.getIslandTag() >= 0) {
if (colObj1.getCompanionId() >= 0) {
solverBodyIdB = colObj1.getCompanionId();
} else {
solverBodyIdB = tmpSolverBodyPool.size();
SolverBody solverBody = bodiesPool.get();
tmpSolverBodyPool.add(solverBody);
initSolverBody(solverBody, colObj1);
colObj1.setCompanionId(solverBodyIdB);
}
} else {
// create a static body
solverBodyIdB = tmpSolverBodyPool.size();
SolverBody solverBody = bodiesPool.get();
tmpSolverBodyPool.add(solverBody);
initSolverBody(solverBody, colObj1);
}
}
float relaxation;
for (int j = 0; j < manifold.getNumContacts(); j++) {
ManifoldPoint cp = manifold.getContactPoint(j);
if (cp.getDistance() <= 0f) {
cp.getPositionWorldOnA(pos1);
cp.getPositionWorldOnB(pos2);
rel_pos1.sub(pos1, colObj0.getWorldTransform(tmpTrans).origin);
rel_pos2.sub(pos2, colObj1.getWorldTransform(tmpTrans).origin);
relaxation = 1f;
float rel_vel;
int frictionIndex = tmpSolverConstraintPool.size();
{
SolverConstraint solverConstraint = constraintsPool.get();
tmpSolverConstraintPool.add(solverConstraint);
RigidBody rb0 = RigidBody.upcast(colObj0);
RigidBody rb1 = RigidBody.upcast(colObj1);
solverConstraint.solverBodyIdA = solverBodyIdA;
solverConstraint.solverBodyIdB = solverBodyIdB;
solverConstraint.constraintType = SolverConstraintType.SOLVER_CONTACT_1D;
solverConstraint.originalContactPoint = cp;
torqueAxis0.cross(rel_pos1, cp.normalWorldOnB);
if (rb0 != null) {
solverConstraint.angularComponentA.set(torqueAxis0);
rb0.getInvInertiaTensorWorld(tmpMat).transform(solverConstraint.angularComponentA);
} else {
solverConstraint.angularComponentA.set(0f, 0f, 0f);
}
torqueAxis1.cross(rel_pos2, cp.normalWorldOnB);
if (rb1 != null) {
solverConstraint.angularComponentB.set(torqueAxis1);
rb1.getInvInertiaTensorWorld(tmpMat).transform(solverConstraint.angularComponentB);
} else {
solverConstraint.angularComponentB.set(0f, 0f, 0f);
}
{
//#ifdef COMPUTE_IMPULSE_DENOM
//btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
//btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
//#else
float denom0 = 0f;
float denom1 = 0f;
if (rb0 != null) {
vec.cross(solverConstraint.angularComponentA, rel_pos1);
denom0 = rb0.getInvMass() + cp.normalWorldOnB.dot(vec);
}
if (rb1 != null) {
vec.cross(solverConstraint.angularComponentB, rel_pos2);
denom1 = rb1.getInvMass() + cp.normalWorldOnB.dot(vec);
}
//#endif //COMPUTE_IMPULSE_DENOM
float denom = relaxation / (denom0 + denom1);
solverConstraint.jacDiagABInv = denom;
}
solverConstraint.contactNormal.set(cp.normalWorldOnB);
solverConstraint.relpos1CrossNormal.cross(rel_pos1, cp.normalWorldOnB);
solverConstraint.relpos2CrossNormal.cross(rel_pos2, cp.normalWorldOnB);
if (rb0 != null) {
rb0.getVelocityInLocalPoint(rel_pos1, vel1);
} else {
vel1.set(0f, 0f, 0f);
}
if (rb1 != null) {
rb1.getVelocityInLocalPoint(rel_pos2, vel2);
} else {
vel2.set(0f, 0f, 0f);
}
vel.sub(vel1, vel2);
rel_vel = cp.normalWorldOnB.dot(vel);
solverConstraint.penetration = Math.min(cp.getDistance() + infoGlobal.linearSlop, 0f);
//solverConstraint.m_penetration = cp.getDistance();
solverConstraint.friction = cp.combinedFriction;
solverConstraint.restitution = restitutionCurve(rel_vel, cp.combinedRestitution);
if (solverConstraint.restitution <= 0f) {
solverConstraint.restitution = 0f;
}
float penVel = -solverConstraint.penetration / infoGlobal.timeStep;
if (solverConstraint.restitution > penVel) {
solverConstraint.penetration = 0f;
}
Vector3f tmp = stack.allocVector3f();
// warm starting (or zero if disabled)
if ((infoGlobal.solverMode & SolverMode.SOLVER_USE_WARMSTARTING) != 0) {
solverConstraint.appliedImpulse = cp.appliedImpulse * infoGlobal.warmstartingFactor;
if (rb0 != null) {
tmp.scale(rb0.getInvMass(), solverConstraint.contactNormal);
tmpSolverBodyPool.getQuick(solverConstraint.solverBodyIdA).internalApplyImpulse(tmp, solverConstraint.angularComponentA, solverConstraint.appliedImpulse);
}
if (rb1 != null) {
tmp.scale(rb1.getInvMass(), solverConstraint.contactNormal);
tmpSolverBodyPool.getQuick(solverConstraint.solverBodyIdB).internalApplyImpulse(tmp, solverConstraint.angularComponentB, -solverConstraint.appliedImpulse);
}
} else {
solverConstraint.appliedImpulse = 0f;
}
solverConstraint.appliedPushImpulse = 0f;
solverConstraint.frictionIndex = tmpSolverFrictionConstraintPool.size();
if (!cp.lateralFrictionInitialized) {
cp.lateralFrictionDir1.scale(rel_vel, cp.normalWorldOnB);
cp.lateralFrictionDir1.sub(vel, cp.lateralFrictionDir1);
float lat_rel_vel = cp.lateralFrictionDir1.lengthSquared();
if (//0.0f)
lat_rel_vel > BulletGlobals.FLT_EPSILON) {
cp.lateralFrictionDir1.scale(1f / (float) Math.sqrt(lat_rel_vel));
addFrictionConstraint(cp.lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
cp.lateralFrictionDir2.cross(cp.lateralFrictionDir1, cp.normalWorldOnB);
//??
cp.lateralFrictionDir2.normalize();
addFrictionConstraint(cp.lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
} else {
// re-calculate friction direction every frame, todo: check if this is really needed
TransformUtil.planeSpace1(cp.normalWorldOnB, cp.lateralFrictionDir1, cp.lateralFrictionDir2);
addFrictionConstraint(cp.lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
addFrictionConstraint(cp.lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
}
cp.lateralFrictionInitialized = true;
} else {
addFrictionConstraint(cp.lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
addFrictionConstraint(cp.lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
}
{
SolverConstraint frictionConstraint1 = tmpSolverFrictionConstraintPool.getQuick(solverConstraint.frictionIndex);
if ((infoGlobal.solverMode & SolverMode.SOLVER_USE_WARMSTARTING) != 0) {
frictionConstraint1.appliedImpulse = cp.appliedImpulseLateral1 * infoGlobal.warmstartingFactor;
if (rb0 != null) {
tmp.scale(rb0.getInvMass(), frictionConstraint1.contactNormal);
tmpSolverBodyPool.getQuick(solverConstraint.solverBodyIdA).internalApplyImpulse(tmp, frictionConstraint1.angularComponentA, frictionConstraint1.appliedImpulse);
}
if (rb1 != null) {
tmp.scale(rb1.getInvMass(), frictionConstraint1.contactNormal);
tmpSolverBodyPool.getQuick(solverConstraint.solverBodyIdB).internalApplyImpulse(tmp, frictionConstraint1.angularComponentB, -frictionConstraint1.appliedImpulse);
}
} else {
frictionConstraint1.appliedImpulse = 0f;
}
}
{
SolverConstraint frictionConstraint2 = tmpSolverFrictionConstraintPool.getQuick(solverConstraint.frictionIndex + 1);
if ((infoGlobal.solverMode & SolverMode.SOLVER_USE_WARMSTARTING) != 0) {
frictionConstraint2.appliedImpulse = cp.appliedImpulseLateral2 * infoGlobal.warmstartingFactor;
if (rb0 != null) {
tmp.scale(rb0.getInvMass(), frictionConstraint2.contactNormal);
tmpSolverBodyPool.getQuick(solverConstraint.solverBodyIdA).internalApplyImpulse(tmp, frictionConstraint2.angularComponentA, frictionConstraint2.appliedImpulse);
}
if (rb1 != null) {
tmp.scale(rb1.getInvMass(), frictionConstraint2.contactNormal);
tmpSolverBodyPool.getQuick(solverConstraint.solverBodyIdB).internalApplyImpulse(tmp, frictionConstraint2.angularComponentB, -frictionConstraint2.appliedImpulse);
}
} else {
frictionConstraint2.appliedImpulse = 0f;
}
}
}
}
}
}
}
}
// TODO: btContactSolverInfo info = infoGlobal;
{
int j;
for (j = 0; j < numConstraints; j++) {
TypedConstraint constraint = constraints.getQuick(constraints_offset + j);
constraint.buildJacobian();
}
}
int numConstraintPool = tmpSolverConstraintPool.size();
int numFrictionPool = tmpSolverFrictionConstraintPool.size();
// todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
MiscUtil.resize(orderTmpConstraintPool, numConstraintPool, 0);
MiscUtil.resize(orderFrictionConstraintPool, numFrictionPool, 0);
{
int i;
for (i = 0; i < numConstraintPool; i++) {
orderTmpConstraintPool.set(i, i);
}
for (i = 0; i < numFrictionPool; i++) {
orderFrictionConstraintPool.set(i, i);
}
}
return 0f;
} finally {
stack.leave(sp);
BulletStats.popProfile();
}
}
use of com.bulletphysics.linearmath.Transform in project bdx by GoranM.
the class SliderConstraint method getAncorInA.
// access for PE Solver
public Vector3f getAncorInA(Vector3f out) {
Stack stack = Stack.enter();
Transform tmpTrans = stack.allocTransform();
Vector3f ancorInA = out;
ancorInA.scaleAdd((lowerLinLimit + upperLinLimit) * 0.5f, sliderAxis, realPivotAInW);
rbA.getCenterOfMassTransform(tmpTrans);
tmpTrans.inverse();
tmpTrans.transform(ancorInA);
stack.leave();
return ancorInA;
}
use of com.bulletphysics.linearmath.Transform in project bdx by GoranM.
the class SliderConstraint method calculateTransforms.
// shared code used by ODE solver
public void calculateTransforms() {
Stack stack = Stack.enter();
Transform tmpTrans = stack.allocTransform();
if (useLinearReferenceFrameA) {
calculatedTransformA.mul(rbA.getCenterOfMassTransform(tmpTrans), frameInA);
calculatedTransformB.mul(rbB.getCenterOfMassTransform(tmpTrans), frameInB);
} else {
calculatedTransformA.mul(rbB.getCenterOfMassTransform(tmpTrans), frameInB);
calculatedTransformB.mul(rbA.getCenterOfMassTransform(tmpTrans), frameInA);
}
realPivotAInW.set(calculatedTransformA.origin);
realPivotBInW.set(calculatedTransformB.origin);
// along X
calculatedTransformA.basis.getColumn(0, sliderAxis);
delta.sub(realPivotBInW, realPivotAInW);
projPivotInW.scaleAdd(sliderAxis.dot(delta), sliderAxis, realPivotAInW);
Vector3f normalWorld = stack.allocVector3f();
// linear part
for (int i = 0; i < 3; i++) {
calculatedTransformA.basis.getColumn(i, normalWorld);
VectorUtil.setCoord(depth, i, delta.dot(normalWorld));
}
stack.leave();
}
Aggregations