public void Execute(int index) { float2 position = particles[index].position; int hash = GridHashUtilities.Hash(position, radius); hashMap.Add(hash, index); }
public void Execute(int index) { float2 forcePressure = 0; float2 forceViscosity = 0; WaterParticle2D pi = particles[index]; for (int i = 0; i < cellOffset.Length; i++) { float2 position = pi.position + (float2)cellOffset[i] * particleRadius; int bucketIndex = GridHashUtilities.Hash(position, particleRadius); NativeMultiHashMapIterator <int> iterator; bool hasValue = hashMap.TryGetFirstValue(bucketIndex, out int j, out iterator); while (hasValue) { if (index == j) { hasValue = hashMap.TryGetNextValue(out j, ref iterator); continue; } WaterParticle2D pj = readOnlyParticles[j]; // particles[j]; float2 diff = pj.position - pi.position; float distanceSquared = math.lengthsq(diff); if (distanceSquared < particleRadiusSquared) { float distance = math.sqrt(distanceSquared); float radiusRatio = particleRadius - distance; float2 normalizedDir = diff / distance; forcePressure += -normalizedDir * MASS * (pi.pressure + pj.pressure) / (2f * pj.density) * SPIKY_GRAD * radiusRatio * radiusRatio; forceViscosity += VISC * MASS * (pj.velocity - pi.velocity) / pj.density * VISC_LAP * (particleRadius - distance); } hasValue = hashMap.TryGetNextValue(out j, ref iterator); } } float2 forceFravity = GRAVITY * pi.density; pi.force = forcePressure + forceViscosity + forceFravity; particles[index] = pi; }
public void Execute(int index) { WaterParticle2D pi = particles[index]; pi.density = 0; for (int i = 0; i < cellOffset.Length; i++) { float2 position = pi.position + (float2)cellOffset[i] * particleRadius; int bucketIndex = GridHashUtilities.Hash(position, particleRadius); NativeMultiHashMapIterator <int> iterator; bool hasValue = hashMap.TryGetFirstValue(bucketIndex, out int j, out iterator); while (hasValue) { WaterParticle2D pj = readOnlyParticles[j]; // particles[j]; float2 diff = pj.position - pi.position; float distanceSq = math.lengthsq(diff); if (distanceSq < particleRadiusSquared) { float ratio = particleRadius - math.sqrt(distanceSq); pi.density += MASS * POLY6 * ratio * ratio * ratio; //float squaredRatio = particleRadiusSquared - distanceSq; //pi.density += MASS * POLY6 * squaredRatio * squaredRatio * squaredRatio; } hasValue = hashMap.TryGetNextValue(out j, ref iterator); } } pi.pressure = GAS_CONST * (pi.density - REST_DENS); particles[index] = pi; }
public void Execute(int i) { WaterParticle2D p = particles[i]; p.velocity += deltaTime * p.force / p.density; float2 previousPosition = p.position; int2 prevPos = GridHashUtilities.Quantize(p.position, collisionScale); float2 step = deltaTime * p.velocity; p.position += step; float velocityMagnitude = math.length(p.velocity); if (velocityMagnitude < math.FLT_MIN_NORMAL) { particles[i] = p; return; } float2 radiusEdgePosition = p.position + (p.velocity / velocityMagnitude) * particleRadius; //find grid position int2 newPos = GridHashUtilities.Quantize(radiusEdgePosition, collisionScale); if (newPos.x < 0 || newPos.x >= sizeArray || newPos.y < 0 || newPos.y >= sizeArray) { //out of bound return; } bool movedInSameGrid = prevPos.x == newPos.x && prevPos.y == newPos.y; bool hasCollision = colArray[newPos.y * sizeArray + newPos.x] == 1; if (!movedInSameGrid && hasCollision) { //left collision if (prevPos.x > newPos.x) { p.velocity.x *= BOUND_DAMPING; p.position.x = (prevPos.x * collisionScale) + particleRadius; } //right collision else if (prevPos.x < newPos.x) { p.velocity.x *= BOUND_DAMPING; p.position.x = (newPos.x * collisionScale) - particleRadius; } //bottom collision if (prevPos.y > newPos.y) { p.velocity.y *= BOUND_DAMPING; p.position.y = (prevPos.y * collisionScale) + particleRadius; } //up collision else if (prevPos.y < newPos.y) { p.velocity.y *= BOUND_DAMPING; p.position.y = (newPos.y * collisionScale) - particleRadius; } } //test if have collision //reflect velocity on normal? //replace position //if (p.position.x - particleRadius < -VIEW_WIDTH) //{ // p.velocity.x *= BOUND_DAMPING; // p.position.x = -VIEW_WIDTH + particleRadius; //} //if (p.position.x + particleRadius > VIEW_WIDTH) //{ // p.velocity.x *= BOUND_DAMPING; // p.position.x = VIEW_WIDTH - particleRadius; //} //if (p.position.y - particleRadius < -VIEW_HEIGHT) //{ // p.velocity.y *= BOUND_DAMPING; // p.position.y = -VIEW_HEIGHT + particleRadius; //} //if (p.position.y + particleRadius > VIEW_HEIGHT) //{ // p.velocity.y *= BOUND_DAMPING; // p.position.y = VIEW_HEIGHT - particleRadius; //} particles[i] = p; }