First of all the surface, the particle and the constraint parts should remain unchanged. These are essential parts.
One can create model structure on simple way.
See the variables
// Surfaces (n pieces depends terrain)
private float[][] S = new float[65535][6];
// 0 = point1X
// 1 = point1Y
// 2 = point2X
// 3 = point2Y
// 4 = surface normal X
// 5 = surface normal Y
// Particles (7 pieces)
private float[][] P = new float[7][14];
// 0 = is active
// 1 = current position X
// 2 = current position Y
// 3 = previous position X
// 4 = previous position Y
// 5 = effective force X
// 6 = effective force Y
// 7 = particle radius
// other auxiliary variables
// 8 = tempX
// 9 = tempY
// 10 = closestPointX
// 11 = closestPointY
// 12 = correctionX
// 13 = correctionY
// Constraints (18 pieces)
private float[][] C = new float[18][4];
// 0 = index1
// 1 = index2
// 2 = restlength
// 3 = stiffness
If you create a surface just give 2 points. Be careful, the normal of surface determines a half plane. A surface is effective if the the particle is on the same side of this half plane. Particles and constraints should be above the surfaces.
If you create a particle just give a particle number, x and y coordinates and a radius. Every particle is active by default. In the given code the first particle not active, so collision detection skip it.
If you create a constraint just give a constraint number and particles number, between these particles the constraint is situated. At last the stiffness value.
particleCreate(0, -65, -30, 1.15f);
particleCreate(1, 0, -30, 0.5f); P[1][0] = 0;
particleCreate(2, 65, -30, 1.15f);
particleCreate(3, 65, -70, 0.85f);
particleCreate(4, 30, -100, 1.15f);
particleCreate(5, -30, -100, 1.15f);
particleCreate(6, -65, -70, 0.85f);
constraintCreate(0, 0, 1, 0.25f);
constraintCreate(1, 1, 2, 0.25f);
constraintCreate(2, 2, 3, 0.25f);
constraintCreate(3, 3, 4, 0.25f);
constraintCreate(4, 4, 5, 0.25f);
constraintCreate(5, 5, 6, 0.25f);
constraintCreate(6, 6, 0, 0.25f);
constraintCreate(7, 0, 3, 0.15f);
constraintCreate(8, 0, 4, 0.15f);
constraintCreate(9, 0, 5, 0.15f);
constraintCreate(10, 1, 3, 0.15f);
constraintCreate(11, 1, 4, 0.15f);
constraintCreate(12, 1, 5, 0.15f);
constraintCreate(13, 1, 6, 0.15f);
constraintCreate(14, 2, 4, 0.15f);
constraintCreate(15, 2, 5, 0.15f);
constraintCreate(16, 2, 6, 0.15f);
constraintCreate(17, 3, 6, 0.15f);
One engine step is fulfilled the following way. Go through all particles and constraints with particleVerlet() and constraintResolve() procedure.
Finally check particles and surfaces collision. If there are a lot of surface then collision detection is very time consuming. It worths to perform some space partitioning procedure.
int delta = (int) (System.currentTimeMillis() - lastLoopTime);
lastLoopTime = System.currentTimeMillis();
for (k = 0; k < delta / 15; k++)
{
// timestep
for (i = 0; i < 7; i++) // particles (7)
particleVerlet(i);
for (i = 0; i < 18; i++) // constraints (18)
constraintResolve(i);
for (j = 0; j < surfaceCount; j++) // surfaces (surfaceCount)
for (i = 0; i < 7; i++) // particles (7)
particleCheckCollision(j, i);
}
One thing is missing. The forces.
Forces must take effect parallel with vector which indicate form point 0 to point 2.
private void HandleKeyEvent()
{
float dist, vX, vY;
dist = (float)distance(P[0][1], P[0][2], P[2][1], P[2][2]);
vX = (P[2][1] - P[0][1]) / dist;
vY = (P[2][2] - P[0][2]) / dist;
if (K[KeyEvent.VK_UP])
{
P[0][5] = vX * 2.75f;
P[0][6] = vY * 2.75f;
P[2][5] = vX * 2.75f;
P[2][6] = vY * 2.75f;
};
if (K[KeyEvent.VK_DOWN])
{
{
P[0][5] = vX * -1.75f;
P[0][6] = vY * -1.75f;
P[2][5] = vX * -1.75f;
P[2][6] = vY * -1.75f;
}
};
if (! K[KeyEvent.VK_DOWN] && ! K[KeyEvent.VK_UP])
{
P[0][5] = 0;
P[0][6] = 0;
P[2][5] = 0;
P[2][6] = 0;
};
}