use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleGroup method updateStatistics.
public void updateStatistics() {
if (m_timestamp != m_system.m_timestamp) {
float m = m_system.getParticleMass();
m_mass = 0;
m_center.setZero();
m_linearVelocity.setZero();
for (int i = m_firstIndex; i < m_lastIndex; i++) {
m_mass += m;
Vec2 pos = m_system.m_positionBuffer.data[i];
m_center.x += m * pos.x;
m_center.y += m * pos.y;
Vec2 vel = m_system.m_velocityBuffer.data[i];
m_linearVelocity.x += m * vel.x;
m_linearVelocity.y += m * vel.y;
}
if (m_mass > 0) {
m_center.x *= 1 / m_mass;
m_center.y *= 1 / m_mass;
m_linearVelocity.x *= 1 / m_mass;
m_linearVelocity.y *= 1 / m_mass;
}
m_inertia = 0;
m_angularVelocity = 0;
for (int i = m_firstIndex; i < m_lastIndex; i++) {
Vec2 pos = m_system.m_positionBuffer.data[i];
Vec2 vel = m_system.m_velocityBuffer.data[i];
float px = pos.x - m_center.x;
float py = pos.y - m_center.y;
float vx = vel.x - m_linearVelocity.x;
float vy = vel.y - m_linearVelocity.y;
m_inertia += m * (px * px + py * py);
m_angularVelocity += m * (px * vy - py * vx);
}
if (m_inertia > 0) {
m_angularVelocity *= 1 / m_inertia;
}
m_timestamp = m_system.m_timestamp;
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method solveSpring.
private void solveSpring(final TimeStep step) {
float springStrength = step.inv_dt * m_springStrength;
for (int k = 0; k < m_pairCount; k++) {
final Pair pair = m_pairBuffer[k];
if ((pair.flags & ParticleTypeInternal.b2_springParticle) != 0) {
int a = pair.indexA;
int b = pair.indexB;
final Vec2 pa = m_positionBuffer.data[a];
final Vec2 pb = m_positionBuffer.data[b];
final float dx = pb.x - pa.x;
final float dy = pb.y - pa.y;
float r0 = pair.distance;
float r1 = FXGLMath.sqrtF(dx * dx + dy * dy);
if (r1 == 0)
r1 = Float.MAX_VALUE;
float strength = springStrength * pair.strength;
final float fx = strength * (r0 - r1) / r1 * dx;
final float fy = strength * (r0 - r1) / r1 * dy;
final Vec2 va = m_velocityBuffer.data[a];
final Vec2 vb = m_velocityBuffer.data[b];
va.x -= fx;
va.y -= fy;
vb.x += fx;
vb.y += fy;
}
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method queryAABB.
public void queryAABB(ParticleQueryCallback callback, final AABB aabb) {
if (m_proxyCount == 0) {
return;
}
final float lowerBoundX = aabb.lowerBound.x;
final float lowerBoundY = aabb.lowerBound.y;
final float upperBoundX = aabb.upperBound.x;
final float upperBoundY = aabb.upperBound.y;
int firstProxy = lowerBound(m_proxyBuffer, m_proxyCount, computeTag(m_inverseDiameter * lowerBoundX, m_inverseDiameter * lowerBoundY));
int lastProxy = upperBound(m_proxyBuffer, m_proxyCount, computeTag(m_inverseDiameter * upperBoundX, m_inverseDiameter * upperBoundY));
for (int proxy = firstProxy; proxy < lastProxy; ++proxy) {
int i = m_proxyBuffer[proxy].index;
final Vec2 p = m_positionBuffer.data[i];
if (lowerBoundX < p.x && p.x < upperBoundX && lowerBoundY < p.y && p.y < upperBoundY && !callback.reportParticle(i)) {
break;
}
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method raycast.
public void raycast(ParticleRaycastCallback callback, final Vec2 point1, final Vec2 point2) {
if (m_proxyCount == 0) {
return;
}
int firstProxy = lowerBound(m_proxyBuffer, m_proxyCount, computeTag(m_inverseDiameter * Math.min(point1.x, point2.x) - 1, m_inverseDiameter * Math.min(point1.y, point2.y) - 1));
int lastProxy = upperBound(m_proxyBuffer, m_proxyCount, computeTag(m_inverseDiameter * Math.max(point1.x, point2.x) + 1, m_inverseDiameter * Math.max(point1.y, point2.y) + 1));
float fraction = 1;
// solving the following equation:
// ((1-t)*point1+t*point2-position)^2=diameter^2
// where t is a potential fraction
final float vx = point2.x - point1.x;
final float vy = point2.y - point1.y;
float v2 = vx * vx + vy * vy;
if (v2 == 0)
v2 = Float.MAX_VALUE;
for (int proxy = firstProxy; proxy < lastProxy; ++proxy) {
int i = m_proxyBuffer[proxy].index;
final Vec2 posI = m_positionBuffer.data[i];
final float px = point1.x - posI.x;
final float py = point1.y - posI.y;
float pv = px * vx + py * vy;
float p2 = px * px + py * py;
float determinant = pv * pv - v2 * (p2 - m_squaredDiameter);
if (determinant >= 0) {
float sqrtDeterminant = FXGLMath.sqrtF(determinant);
// find a solution between 0 and fraction
float t = (-pv - sqrtDeterminant) / v2;
if (t > fraction) {
continue;
}
if (t < 0) {
t = (-pv + sqrtDeterminant) / v2;
if (t < 0 || t > fraction) {
continue;
}
}
final Vec2 n = tempVec;
tempVec.x = px + t * vx;
tempVec.y = py + t * vy;
n.getLengthAndNormalize();
final Vec2 point = tempVec2;
point.x = point1.x + t * vx;
point.y = point1.y + t * vy;
float f = callback.reportParticle(i, point, n, t);
fraction = Math.min(fraction, f);
if (fraction <= 0) {
break;
}
}
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method solveViscous.
@SuppressWarnings("PMD.UnusedFormalParameter")
private void solveViscous(final TimeStep step) {
float viscousStrength = m_viscousStrength;
for (int k = 0; k < m_bodyContactCount; k++) {
final ParticleBodyContact contact = m_bodyContactBuffer[k];
int a = contact.index;
if ((m_flagsBuffer.data[a] & ParticleTypeInternal.b2_viscousParticle) != 0) {
Body b = contact.body;
float w = contact.weight;
float m = contact.mass;
Vec2 p = m_positionBuffer.data[a];
final Vec2 va = m_velocityBuffer.data[a];
final float tempX = p.x - b.m_sweep.c.x;
final float tempY = p.y - b.m_sweep.c.y;
final float vx = -b.getAngularVelocity() * tempY + b.getLinearVelocity().x - va.x;
final float vy = b.getAngularVelocity() * tempX + b.getLinearVelocity().y - va.y;
final Vec2 f = tempVec;
final float pInvMass = getParticleInvMass();
f.x = viscousStrength * m * w * vx;
f.y = viscousStrength * m * w * vy;
va.x += pInvMass * f.x;
va.y += pInvMass * f.y;
f.x = -f.x;
f.y = -f.y;
b.applyLinearImpulse(f, p, true);
}
}
for (int k = 0; k < m_contactCount; k++) {
final ParticleContact contact = m_contactBuffer[k];
if ((contact.flags & ParticleTypeInternal.b2_viscousParticle) != 0) {
int a = contact.indexA;
int b = contact.indexB;
float w = contact.weight;
final Vec2 va = m_velocityBuffer.data[a];
final Vec2 vb = m_velocityBuffer.data[b];
final float vx = vb.x - va.x;
final float vy = vb.y - va.y;
final float fx = viscousStrength * w * vx;
final float fy = viscousStrength * w * vy;
va.x += fx;
va.y += fy;
vb.x -= fx;
vb.y -= fy;
}
}
}
Aggregations