protected override void OnUpdatePlugin(SolverData solverData, int particleIndex) { var seed = solverData.GetRandomSeed(particleIndex); for (int i = 0, l = m_TouchPointsCount; i < l; ++i) { var pt = m_TouchPoints[i]; pt.w = 0; var worldPosition = (Vector4)solverData.GetPosition(particleIndex); worldPosition.w = 0; var d = pt - worldPosition; var len = d.magnitude; if (len < radius) { solverData.AddForce(particleIndex, (d / len) * acceleration.Evaluate(seed, len / radius), ForceMode.Acceleration); } } }
protected override void OnUpdatePlugin(SolverData solverData, int particleIndex, int neighborIndex) { // Get fluid IDs var particleFluid = solverData.GetFluid(particleIndex).GetFluidID(); var neighborFluid = solverData.GetFluid(neighborIndex).GetFluidID(); var particleIsA = particleFluid == m_FluidAID; if ((m_MixingFluidsAreTheSame || particleFluid != neighborFluid) && // Fluids are not the same, unless A and B are the same (particleIsA || particleFluid == m_FluidBID) && // First fluid is A or B (neighborFluid == m_FluidAID || neighborFluid == m_FluidBID)) // Second fluid is A or B { var position = solverData.GetPosition(particleIndex); var neighborPosition = solverData.GetPosition(neighborIndex); // Make sure the particles are actually close if ((position - neighborPosition).sqrMagnitude > m_MixingDistanceSq) { return; } var velocity = solverData.GetVelocity(particleIndex); var invMass = 1.0f / solverData.GetMass(particleIndex); var emitC = false; // Despawn the current particle, unless Fluid C is null and the particle is from Fluid A if (m_FluidCID != 0 || !particleIsA) { emitC = true; solverData.SetLifetime(particleIndex, 0.0f); } // Emit a particle. We don't emit from the neighbor position, that gets handled in the opposite pair // We handle actual emission on the main thread. if (m_FluidDID == 0 || particleIsA) { if (emitC) { // Set the system to Fluid C m_MixerData[particleIndex].emitVelocity.w = 1; } else { m_MixerData[particleIndex].emitVelocity.w = 0; } } else { // Set the system to Fluid D m_MixerData[particleIndex].emitVelocity.w = 2; } // Set emit position and velocity. These must be manually integrated since they won't be applied until after the solver has run. // The below is a standard Euler explicit integrator. var acceleration = m_Gravity + solverData.GetForce(particleIndex) * invMass; for (var iter = 0; iter < m_TimeStep.solverIterations; ++iter) { var t = (m_TimeStep.dtIter) * acceleration; // Ignore very large velocity changes if (Vector3.Dot(t, t) > (FluvioSettings.kMaxSqrVelocityChange * m_SimulationScale)) { t *= 0; } velocity += t; } var distSq = m_MixerData[particleIndex].emitPosition.w; var id = m_MixerData[particleIndex].emitVelocity.w; m_MixerData[particleIndex].emitVelocity = velocity; m_MixerData[particleIndex].emitPosition = position + velocity * m_TimeStep.deltaTime; m_MixerData[particleIndex].emitPosition.w = distSq; m_MixerData[particleIndex].emitVelocity.w = id; } }
protected override void OnUpdatePlugin(SolverData solverData, int particleIndex, int neighborIndex) { // Get fluid IDs var particleFluid = solverData.GetFluid(particleIndex).GetFluidID(); var neighborFluid = solverData.GetFluid(neighborIndex).GetFluidID(); var particleIsA = particleFluid == m_FluidAID; if ((m_MixingFluidsAreTheSame || particleFluid != neighborFluid) && // Fluids are not the same, unless A and B are the same (particleIsA || particleFluid == m_FluidBID) && // First fluid is A or B (neighborFluid == m_FluidAID || neighborFluid == m_FluidBID)) // Second fluid is A or B { var position = solverData.GetPosition(particleIndex); var neighborPosition = solverData.GetPosition(neighborIndex); // Make sure the particles are actually close if ((position - neighborPosition).sqrMagnitude > m_MixingDistanceSq) return; var velocity = solverData.GetVelocity(particleIndex); var invMass = 1.0f/solverData.GetMass(particleIndex); var emitC = false; // Despawn the current particle, unless Fluid C is null and the particle is from Fluid A if (m_FluidCID != 0 || !particleIsA) { emitC = true; solverData.SetLifetime(particleIndex, -1); } // Emit a particle. We don't emit from the neighbor position, that gets handled in the opposite pair // We handle actual emission on the main thread. if (m_FluidDID == 0 || particleIsA) { if (emitC) { // Set the system to Fluid C m_ParticleSystems[particleIndex] = 1; } else { m_ParticleSystems[particleIndex] = 0; } } else { // Set the system to Fluid D m_ParticleSystems[particleIndex] = 2; } // Set emit position and velocity. These must be manually integrated since they won't be applied until after the solver has run. // The below is a standard Euler explicit integrator. var acceleration = m_Gravity + solverData.GetForce(particleIndex)*invMass; for (var iter = 0; iter < m_TimeStep.solverIterations; ++iter) { var t = (m_TimeStep.dtIter)*acceleration; // Ignore very large velocity changes if (Vector3.Dot(t, t) > (FluvioSettings.kMaxSqrVelocityChange * m_SimulationScale)) { t *= 0; } velocity += t; } m_EmitVelocities[particleIndex] = velocity; m_EmitPositions[particleIndex] = position + velocity * m_TimeStep.deltaTime; } }
protected override void OnUpdatePlugin(SolverData solverData, int particleIndex) { var seed = solverData.GetRandomSeed(particleIndex); for (int i = 0, l = m_TouchPointsCount; i < l; ++i) { var pt = m_TouchPoints[i]; var worldPosition = (Vector4)solverData.GetPosition(particleIndex); var d = pt - worldPosition; var len = d.magnitude; if (len < radius) solverData.AddForce(particleIndex, (d / len) * acceleration.Evaluate(seed, len / radius), ForceMode.Acceleration); } }