use of com.almasb.fxgl.physics.box2d.dynamics.Body in project FXGL by AlmasB.
the class ParticleSystem method solvePressure.
private void solvePressure(TimeStep step) {
// that means dimensionless density
for (int i = 0; i < m_count; i++) {
m_accumulationBuffer[i] = 0;
}
for (int k = 0; k < m_bodyContactCount; k++) {
ParticleBodyContact contact = m_bodyContactBuffer[k];
int a = contact.index;
float w = contact.weight;
m_accumulationBuffer[a] += w;
}
for (int k = 0; k < m_contactCount; k++) {
ParticleContact contact = m_contactBuffer[k];
int a = contact.indexA;
int b = contact.indexB;
float w = contact.weight;
m_accumulationBuffer[a] += w;
m_accumulationBuffer[b] += w;
}
// ignores powder particles
if ((m_allParticleFlags & k_noPressureFlags) != 0) {
for (int i = 0; i < m_count; i++) {
if ((m_flagsBuffer.data[i] & k_noPressureFlags) != 0) {
m_accumulationBuffer[i] = 0;
}
}
}
// calculates pressure as a linear function of density
float pressurePerWeight = m_pressureStrength * getCriticalPressure(step);
for (int i = 0; i < m_count; i++) {
float w = m_accumulationBuffer[i];
float h = pressurePerWeight * Math.max(0.0f, Math.min(w, JBoxSettings.maxParticleWeight) - JBoxSettings.minParticleWeight);
m_accumulationBuffer[i] = h;
}
// applies pressure between each particles in contact
float velocityPerPressure = step.dt / (m_density * m_particleDiameter);
for (int k = 0; k < m_bodyContactCount; k++) {
ParticleBodyContact contact = m_bodyContactBuffer[k];
int a = contact.index;
Body b = contact.body;
float w = contact.weight;
float m = contact.mass;
Vec2 n = contact.normal;
Vec2 p = m_positionBuffer.data[a];
float h = m_accumulationBuffer[a] + pressurePerWeight * w;
final Vec2 f = tempVec;
final float coef = velocityPerPressure * w * m * h;
f.x = coef * n.x;
f.y = coef * n.y;
final Vec2 velData = m_velocityBuffer.data[a];
final float particleInvMass = getParticleInvMass();
velData.x -= particleInvMass * f.x;
velData.y -= particleInvMass * f.y;
b.applyLinearImpulse(f, p, true);
}
for (int k = 0; k < m_contactCount; k++) {
ParticleContact contact = m_contactBuffer[k];
int a = contact.indexA;
int b = contact.indexB;
float w = contact.weight;
Vec2 n = contact.normal;
float h = m_accumulationBuffer[a] + m_accumulationBuffer[b];
final float fx = velocityPerPressure * w * h * n.x;
final float fy = velocityPerPressure * w * h * n.y;
final Vec2 velDataA = m_velocityBuffer.data[a];
final Vec2 velDataB = m_velocityBuffer.data[b];
velDataA.x -= fx;
velDataA.y -= fy;
velDataB.x += fx;
velDataB.y += fy;
}
}
use of com.almasb.fxgl.physics.box2d.dynamics.Body in project FXGL by AlmasB.
the class ContactSolver method init.
public void init(ContactSolverDef def) {
TimeStep step = def.step;
m_count = def.count;
if (m_positionConstraints.length < m_count) {
ContactPositionConstraint[] old = m_positionConstraints;
m_positionConstraints = new ContactPositionConstraint[Math.max(old.length * 2, m_count)];
System.arraycopy(old, 0, m_positionConstraints, 0, old.length);
for (int i = old.length; i < m_positionConstraints.length; i++) {
m_positionConstraints[i] = new ContactPositionConstraint();
}
}
if (m_velocityConstraints.length < m_count) {
ContactVelocityConstraint[] old = m_velocityConstraints;
m_velocityConstraints = new ContactVelocityConstraint[Math.max(old.length * 2, m_count)];
System.arraycopy(old, 0, m_velocityConstraints, 0, old.length);
for (int i = old.length; i < m_velocityConstraints.length; i++) {
m_velocityConstraints[i] = new ContactVelocityConstraint();
}
}
m_positions = def.positions;
m_velocities = def.velocities;
m_contacts = def.contacts;
for (int i = 0; i < m_count; ++i) {
final Contact contact = m_contacts[i];
final Fixture fixtureA = contact.m_fixtureA;
final Fixture fixtureB = contact.m_fixtureB;
final Shape shapeA = fixtureA.getShape();
final Shape shapeB = fixtureB.getShape();
final float radiusA = shapeA.getRadius();
final float radiusB = shapeB.getRadius();
final Body bodyA = fixtureA.getBody();
final Body bodyB = fixtureB.getBody();
final Manifold manifold = contact.getManifold();
int pointCount = manifold.pointCount;
assert pointCount > 0;
ContactVelocityConstraint vc = m_velocityConstraints[i];
vc.friction = contact.getFriction();
vc.restitution = contact.getRestitution();
vc.tangentSpeed = contact.getTangentSpeed();
vc.indexA = bodyA.m_islandIndex;
vc.indexB = bodyB.m_islandIndex;
vc.invMassA = bodyA.m_invMass;
vc.invMassB = bodyB.m_invMass;
vc.invIA = bodyA.m_invI;
vc.invIB = bodyB.m_invI;
vc.contactIndex = i;
vc.pointCount = pointCount;
vc.K.setZero();
vc.normalMass.setZero();
ContactPositionConstraint pc = m_positionConstraints[i];
pc.indexA = bodyA.m_islandIndex;
pc.indexB = bodyB.m_islandIndex;
pc.invMassA = bodyA.m_invMass;
pc.invMassB = bodyB.m_invMass;
pc.localCenterA.set(bodyA.m_sweep.localCenter);
pc.localCenterB.set(bodyB.m_sweep.localCenter);
pc.invIA = bodyA.m_invI;
pc.invIB = bodyB.m_invI;
pc.localNormal.set(manifold.localNormal);
pc.localPoint.set(manifold.localPoint);
pc.pointCount = pointCount;
pc.radiusA = radiusA;
pc.radiusB = radiusB;
pc.type = manifold.type;
for (int j = 0; j < pointCount; j++) {
ManifoldPoint cp = manifold.points[j];
VelocityConstraintPoint vcp = vc.points[j];
if (step.warmStarting) {
vcp.normalImpulse = step.dtRatio * cp.normalImpulse;
vcp.tangentImpulse = step.dtRatio * cp.tangentImpulse;
} else {
vcp.normalImpulse = 0;
vcp.tangentImpulse = 0;
}
vcp.rA.setZero();
vcp.rB.setZero();
vcp.normalMass = 0;
vcp.tangentMass = 0;
vcp.velocityBias = 0;
pc.localPoints[j].x = cp.localPoint.x;
pc.localPoints[j].y = cp.localPoint.y;
}
}
}
use of com.almasb.fxgl.physics.box2d.dynamics.Body in project FXGL by AlmasB.
the class PrismaticJoint method getJointSpeed.
/**
* Get the current joint translation, usually in meters.
*/
public float getJointSpeed() {
Body bA = m_bodyA;
Body bB = m_bodyB;
Vec2 temp = pool.popVec2();
Vec2 rA = pool.popVec2();
Vec2 rB = pool.popVec2();
Vec2 p1 = pool.popVec2();
Vec2 p2 = pool.popVec2();
Vec2 d = pool.popVec2();
Vec2 axis = pool.popVec2();
Vec2 temp2 = pool.popVec2();
Vec2 temp3 = pool.popVec2();
temp.set(m_localAnchorA).subLocal(bA.m_sweep.localCenter);
Rotation.mulToOutUnsafe(bA.m_xf.q, temp, rA);
temp.set(m_localAnchorB).subLocal(bB.m_sweep.localCenter);
Rotation.mulToOutUnsafe(bB.m_xf.q, temp, rB);
p1.set(bA.m_sweep.c).addLocal(rA);
p2.set(bB.m_sweep.c).addLocal(rB);
d.set(p2).subLocal(p1);
Rotation.mulToOutUnsafe(bA.m_xf.q, m_localXAxisA, axis);
Vec2 vA = bA.getLinearVelocity();
Vec2 vB = bB.getLinearVelocity();
float wA = bA.getAngularVelocity();
float wB = bB.getAngularVelocity();
Vec2.crossToOutUnsafe(wA, axis, temp);
Vec2.crossToOutUnsafe(wB, rB, temp2);
Vec2.crossToOutUnsafe(wA, rA, temp3);
temp2.addLocal(vB).subLocal(vA).subLocal(temp3);
float speed = Vec2.dot(d, temp) + Vec2.dot(axis, temp2);
pool.pushVec2(9);
return speed;
}
use of com.almasb.fxgl.physics.box2d.dynamics.Body in project FXGL by AlmasB.
the class RevoluteJoint method getJointAngle.
public float getJointAngle() {
final Body b1 = m_bodyA;
final Body b2 = m_bodyB;
return b2.m_sweep.a - b1.m_sweep.a - m_referenceAngle;
}
use of com.almasb.fxgl.physics.box2d.dynamics.Body in project FXGL by AlmasB.
the class RevoluteJoint method getJointSpeed.
public float getJointSpeed() {
final Body b1 = m_bodyA;
final Body b2 = m_bodyB;
return b2.getAngularVelocity() - b1.getAngularVelocity();
}
Aggregations