use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method solve.
public void solve(TimeStep step) {
++m_timestamp;
if (m_count == 0) {
return;
}
m_allParticleFlags = 0;
for (int i = 0; i < m_count; i++) {
m_allParticleFlags |= m_flagsBuffer.data[i];
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_zombieParticle) != 0) {
solveZombie();
}
if (m_count == 0) {
return;
}
m_allGroupFlags = 0;
for (ParticleGroup group = m_groupList; group != null; group = group.getNext()) {
m_allGroupFlags |= group.m_groupFlags;
}
final float gravityx = step.dt * m_gravityScale * m_world.getGravity().x;
final float gravityy = step.dt * m_gravityScale * m_world.getGravity().y;
float criticalVelocytySquared = getCriticalVelocitySquared(step);
for (int i = 0; i < m_count; i++) {
Vec2 v = m_velocityBuffer.data[i];
v.x += gravityx;
v.y += gravityy;
float v2 = v.x * v.x + v.y * v.y;
if (v2 > criticalVelocytySquared) {
float a = v2 == 0 ? Float.MAX_VALUE : FXGLMath.sqrtF(criticalVelocytySquared / v2);
v.x *= a;
v.y *= a;
}
}
solveCollision(step);
if ((m_allGroupFlags & ParticleGroupType.b2_rigidParticleGroup) != 0) {
solveRigid(step);
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_wallParticle) != 0) {
solveWall(step);
}
for (int i = 0; i < m_count; i++) {
Vec2 pos = m_positionBuffer.data[i];
Vec2 vel = m_velocityBuffer.data[i];
pos.x += step.dt * vel.x;
pos.y += step.dt * vel.y;
}
updateBodyContacts();
updateContacts(false);
if ((m_allParticleFlags & ParticleTypeInternal.b2_viscousParticle) != 0) {
solveViscous(step);
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_powderParticle) != 0) {
solvePowder(step);
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_tensileParticle) != 0) {
solveTensile(step);
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_elasticParticle) != 0) {
solveElastic(step);
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_springParticle) != 0) {
solveSpring(step);
}
if ((m_allGroupFlags & ParticleGroupType.b2_solidParticleGroup) != 0) {
solveSolid(step);
}
if ((m_allParticleFlags & ParticleTypeInternal.b2_colorMixingParticle) != 0) {
solveColorMixing(step);
}
solvePressure(step);
solveDamping(step);
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method solveRigid.
private void solveRigid(final TimeStep step) {
for (ParticleGroup group = m_groupList; group != null; group = group.getNext()) {
if ((group.m_groupFlags & ParticleGroupType.b2_rigidParticleGroup) != 0) {
group.updateStatistics();
Vec2 temp = tempVec;
Vec2 cross = tempVec2;
Rotation rotation = tempRotation;
rotation.set(step.dt * group.m_angularVelocity);
Rotation.mulToOutUnsafe(rotation, group.m_center, cross);
temp.set(group.m_linearVelocity).mulLocal(step.dt).addLocal(group.m_center).subLocal(cross);
tempXf.p.set(temp);
tempXf.q.set(rotation);
Transform.mulToOut(tempXf, group.m_transform, group.m_transform);
final Transform velocityTransform = tempXf2;
velocityTransform.p.x = step.inv_dt * tempXf.p.x;
velocityTransform.p.y = step.inv_dt * tempXf.p.y;
velocityTransform.q.s = step.inv_dt * tempXf.q.s;
velocityTransform.q.c = step.inv_dt * (tempXf.q.c - 1);
for (int i = group.m_firstIndex; i < group.m_lastIndex; i++) {
Transform.mulToOutUnsafe(velocityTransform, m_positionBuffer.data[i], m_velocityBuffer.data[i]);
}
}
}
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method createParticleGroup.
@SuppressWarnings("PMD.DontUseFloatTypeForLoopIndices")
public ParticleGroup createParticleGroup(ParticleGroupDef groupDef) {
float stride = getParticleStride();
final Transform identity = tempTransform;
identity.setIdentity();
Transform transform = tempTransform2;
transform.setIdentity();
int firstIndex = m_count;
if (groupDef.getShape() != null) {
final ParticleDef particleDef = tempParticleDef;
particleDef.setTypeFlags(groupDef.getTypeFlags());
particleDef.color = groupDef.getColor();
particleDef.setUserData(groupDef.getUserData());
Shape shape = groupDef.getShape();
transform.set(groupDef.getPosition(), groupDef.getAngle());
AABB aabb = temp;
int childCount = shape.getChildCount();
for (int childIndex = 0; childIndex < childCount; childIndex++) {
if (childIndex == 0) {
shape.computeAABB(aabb, identity, childIndex);
} else {
AABB childAABB = temp2;
shape.computeAABB(childAABB, identity, childIndex);
aabb.combine(childAABB);
}
}
final float upperBoundY = aabb.upperBound.y;
final float upperBoundX = aabb.upperBound.x;
for (float y = FXGLMath.floor(aabb.lowerBound.y / stride) * stride; y < upperBoundY; y += stride) {
for (float x = FXGLMath.floor(aabb.lowerBound.x / stride) * stride; x < upperBoundX; x += stride) {
Vec2 p = tempVec;
p.x = x;
p.y = y;
if (shape.containsPoint(identity, p)) {
Transform.mulToOut(transform, p, p);
particleDef.position.x = p.x;
particleDef.position.y = p.y;
p.subLocal(groupDef.getPosition());
Vec2.crossToOutUnsafe(groupDef.getAngularVelocity(), p, particleDef.velocity);
particleDef.velocity.addLocal(groupDef.getLinearVelocity());
createParticle(particleDef);
}
}
}
}
int lastIndex = m_count;
ParticleGroup group = new ParticleGroup();
group.m_system = this;
group.m_firstIndex = firstIndex;
group.m_lastIndex = lastIndex;
group.m_groupFlags = groupDef.getGroupFlags();
group.m_strength = groupDef.getStrength();
group.m_userData = groupDef.getUserData();
group.m_transform.set(transform);
group.m_destroyAutomatically = groupDef.isDestroyAutomatically();
group.m_prev = null;
group.m_next = m_groupList;
if (m_groupList != null) {
m_groupList.m_prev = group;
}
m_groupList = group;
++m_groupCount;
for (int i = firstIndex; i < lastIndex; i++) {
m_groupBuffer[i] = group;
}
updateContacts(true);
if ((groupDef.getTypeFlags() & k_pairFlags) != 0) {
for (int k = 0; k < m_contactCount; k++) {
ParticleContact contact = m_contactBuffer[k];
int a = contact.indexA;
int b = contact.indexB;
if (a > b) {
int temp = a;
a = b;
b = temp;
}
if (firstIndex <= a && b < lastIndex) {
if (m_pairCount >= m_pairCapacity) {
int oldCapacity = m_pairCapacity;
int newCapacity = m_pairCount != 0 ? 2 * m_pairCount : JBoxSettings.minParticleBufferCapacity;
m_pairBuffer = reallocateBuffer(Pair.class, m_pairBuffer, oldCapacity, newCapacity);
m_pairCapacity = newCapacity;
}
Pair pair = m_pairBuffer[m_pairCount];
pair.indexA = a;
pair.indexB = b;
pair.flags = contact.flags;
pair.strength = groupDef.getStrength();
pair.distance = m_positionBuffer.data[a].distanceF(m_positionBuffer.data[b]);
m_pairCount++;
}
}
}
if ((groupDef.getTypeFlags() & k_triadFlags) != 0) {
VoronoiDiagram diagram = new VoronoiDiagram(lastIndex - firstIndex);
for (int i = firstIndex; i < lastIndex; i++) {
diagram.addGenerator(m_positionBuffer.data[i], i);
}
diagram.generate(stride / 2);
createParticleGroupCallback.system = this;
createParticleGroupCallback.def = groupDef;
createParticleGroupCallback.firstIndex = firstIndex;
diagram.getNodes(createParticleGroupCallback);
}
if ((groupDef.getGroupFlags() & ParticleGroupType.b2_solidParticleGroup) != 0) {
computeDepthForGroup(group);
}
return group;
}
use of com.almasb.fxgl.core.math.Vec2 in project FXGL by AlmasB.
the class ParticleSystem method solveTensile.
private void solveTensile(final TimeStep step) {
m_accumulation2Buffer = requestParticleBuffer(Vec2.class, m_accumulation2Buffer);
for (int i = 0; i < m_count; i++) {
m_accumulationBuffer[i] = 0;
m_accumulation2Buffer[i].setZero();
}
for (int k = 0; k < m_contactCount; k++) {
final ParticleContact contact = m_contactBuffer[k];
if ((contact.flags & ParticleTypeInternal.b2_tensileParticle) != 0) {
int a = contact.indexA;
int b = contact.indexB;
float w = contact.weight;
Vec2 n = contact.normal;
m_accumulationBuffer[a] += w;
m_accumulationBuffer[b] += w;
final Vec2 a2A = m_accumulation2Buffer[a];
final Vec2 a2B = m_accumulation2Buffer[b];
final float inter = (1 - w) * w;
a2A.x -= inter * n.x;
a2A.y -= inter * n.y;
a2B.x += inter * n.x;
a2B.y += inter * n.y;
}
}
float strengthA = m_surfaceTensionStrengthA * getCriticalVelocity(step);
float strengthB = m_surfaceTensionStrengthB * getCriticalVelocity(step);
for (int k = 0; k < m_contactCount; k++) {
final ParticleContact contact = m_contactBuffer[k];
if ((contact.flags & ParticleTypeInternal.b2_tensileParticle) != 0) {
int a = contact.indexA;
int b = contact.indexB;
float w = contact.weight;
Vec2 n = contact.normal;
final Vec2 a2A = m_accumulation2Buffer[a];
final Vec2 a2B = m_accumulation2Buffer[b];
float h = m_accumulationBuffer[a] + m_accumulationBuffer[b];
final float sx = a2B.x - a2A.x;
final float sy = a2B.y - a2A.y;
float fn = (strengthA * (h - 2) + strengthB * (sx * n.x + sy * n.y)) * w;
final float fx = fn * n.x;
final float fy = fn * n.y;
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 solveCollision.
private void solveCollision(TimeStep step) {
final AABB aabb = temp;
final Vec2 lowerBound = aabb.lowerBound;
final Vec2 upperBound = aabb.upperBound;
lowerBound.x = Float.MAX_VALUE;
lowerBound.y = Float.MAX_VALUE;
upperBound.x = -Float.MAX_VALUE;
upperBound.y = -Float.MAX_VALUE;
for (int i = 0; i < m_count; i++) {
final Vec2 v = m_velocityBuffer.data[i];
final Vec2 p1 = m_positionBuffer.data[i];
final float p1x = p1.x;
final float p1y = p1.y;
final float p2x = p1x + step.dt * v.x;
final float p2y = p1y + step.dt * v.y;
final float bx = p1x < p2x ? p1x : p2x;
final float by = p1y < p2y ? p1y : p2y;
lowerBound.x = lowerBound.x < bx ? lowerBound.x : bx;
lowerBound.y = lowerBound.y < by ? lowerBound.y : by;
final float b1x = p1x > p2x ? p1x : p2x;
final float b1y = p1y > p2y ? p1y : p2y;
upperBound.x = upperBound.x > b1x ? upperBound.x : b1x;
upperBound.y = upperBound.y > b1y ? upperBound.y : b1y;
}
sccallback.step = step;
sccallback.system = this;
m_world.queryAABB(sccallback, aabb);
}
Aggregations