use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method updateContacts.
private void updateContacts(boolean exceptZombie) {
for (int p = 0; p < m_proxyCount; p++) {
Proxy proxy = m_proxyBuffer[p];
int i = proxy.index;
Vec2 pos = m_positionBuffer.data[i];
proxy.tag = computeTag(m_inverseDiameter * pos.x, m_inverseDiameter * pos.y);
}
Arrays.sort(m_proxyBuffer, 0, m_proxyCount);
m_contactCount = 0;
int c_index = 0;
for (int i = 0; i < m_proxyCount; i++) {
Proxy a = m_proxyBuffer[i];
long rightTag = computeRelativeTag(a.tag, 1, 0);
for (int j = i + 1; j < m_proxyCount; j++) {
Proxy b = m_proxyBuffer[j];
if (rightTag < b.tag) {
break;
}
addContact(a.index, b.index);
}
long bottomLeftTag = computeRelativeTag(a.tag, -1, 1);
for (; c_index < m_proxyCount; c_index++) {
Proxy c = m_proxyBuffer[c_index];
if (bottomLeftTag <= c.tag) {
break;
}
}
long bottomRightTag = computeRelativeTag(a.tag, 1, 1);
for (int b_index = c_index; b_index < m_proxyCount; b_index++) {
Proxy b = m_proxyBuffer[b_index];
if (bottomRightTag < b.tag) {
break;
}
addContact(a.index, b.index);
}
}
if (exceptZombie) {
int j = m_contactCount;
for (int i = 0; i < j; i++) {
if ((m_contactBuffer[i].flags & ParticleTypeInternal.b2_zombieParticle) != 0) {
--j;
ParticleContact temp = m_contactBuffer[j];
m_contactBuffer[j] = m_contactBuffer[i];
m_contactBuffer[i] = temp;
--i;
}
}
m_contactCount = j;
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method updateBodyContacts.
private void updateBodyContacts() {
final AABB aabb = temp;
aabb.lowerBound.x = Float.MAX_VALUE;
aabb.lowerBound.y = Float.MAX_VALUE;
aabb.upperBound.x = -Float.MAX_VALUE;
aabb.upperBound.y = -Float.MAX_VALUE;
for (int i = 0; i < m_count; i++) {
Vec2 p = m_positionBuffer.data[i];
Vec2.minToOut(aabb.lowerBound, p, aabb.lowerBound);
Vec2.maxToOut(aabb.upperBound, p, aabb.upperBound);
}
aabb.lowerBound.x -= m_particleDiameter;
aabb.lowerBound.y -= m_particleDiameter;
aabb.upperBound.x += m_particleDiameter;
aabb.upperBound.y += m_particleDiameter;
m_bodyContactCount = 0;
ubccallback.system = this;
m_world.queryAABB(ubccallback, aabb);
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method addContact.
private void addContact(int a, int b) {
assert a != b;
Vec2 pa = m_positionBuffer.data[a];
Vec2 pb = m_positionBuffer.data[b];
float dx = pb.x - pa.x;
float dy = pb.y - pa.y;
float d2 = dx * dx + dy * dy;
if (d2 < m_squaredDiameter) {
if (m_contactCount >= m_contactCapacity) {
int oldCapacity = m_contactCapacity;
int newCapacity = m_contactCount != 0 ? 2 * m_contactCount : JBoxSettings.minParticleBufferCapacity;
m_contactBuffer = reallocateBuffer(ParticleContact.class, m_contactBuffer, oldCapacity, newCapacity);
m_contactCapacity = newCapacity;
}
float invD = d2 != 0 ? FXGLMath.sqrtF(1 / d2) : Float.MAX_VALUE;
ParticleContact contact = m_contactBuffer[m_contactCount];
contact.indexA = a;
contact.indexB = b;
contact.flags = m_flagsBuffer.data[a] | m_flagsBuffer.data[b];
contact.weight = 1 - d2 * invD * m_inverseDiameter;
contact.normal.x = invD * dx;
contact.normal.y = invD * dy;
m_contactCount++;
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method computeParticleCollisionEnergy.
public float computeParticleCollisionEnergy() {
float sum_v2 = 0;
for (int k = 0; k < m_contactCount; k++) {
final ParticleContact contact = m_contactBuffer[k];
int a = contact.indexA;
int b = contact.indexB;
Vec2 n = contact.normal;
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;
float vn = vx * n.x + vy * n.y;
if (vn < 0) {
sum_v2 += vn * vn;
}
}
return 0.5f * getParticleMass() * sum_v2;
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method solveSolid.
private void solveSolid(final TimeStep step) {
// applies extra repulsive force from solid particle groups
m_depthBuffer = requestParticleBuffer(m_depthBuffer);
float ejectionStrength = step.inv_dt * m_ejectionStrength;
for (int k = 0; k < m_contactCount; k++) {
final ParticleContact contact = m_contactBuffer[k];
int a = contact.indexA;
int b = contact.indexB;
if (m_groupBuffer[a] != m_groupBuffer[b]) {
float w = contact.weight;
Vec2 n = contact.normal;
float h = m_depthBuffer[a] + m_depthBuffer[b];
final Vec2 va = m_velocityBuffer.data[a];
final Vec2 vb = m_velocityBuffer.data[b];
final float inter = ejectionStrength * h * w;
final float fx = inter * n.x;
final float fy = inter * n.y;
va.x -= fx;
va.y -= fy;
vb.x += fx;
vb.y += fy;
}
}
}
Aggregations