/// <summary> /// This function will be called whenever a particle is colliding. /// </summary> /// <param name="particle">The collided particle.</param> void OnParticleCollisionEvent(PlaygroundEventParticle particle) { if (createPointsOnCollision) { int trailIndex = GetNewestTrailWithParticleId(particle.particleId); if (trailIndex < 0) { return; } ParticlePlaygroundTrail trailAtIndex = _trails[trailIndex]; trailAtIndex.AddPoint(playgroundSystem.particleCache[particle.particleId].position, EvaluateWidth(0), time, _calculationStartTime); } }
/**************************************************************************** * Internal ****************************************************************************/ void CalculateTrail() { // Iterate through all trails for (int i = 0; i < _trails.Count; i++) { ParticlePlaygroundTrail trail = _trails[i]; // Skip this trail if it's prepared to be removed if (trail.CanRemoveTrail()) { continue; } if (trail.particleId >= 0 && !trail.IsDead()) { if (trail.GetBirthIterator() > 0) { // New point creation float pointDistance = Vector3.Distance(trail.GetParticlePosition(), trail.GetLastAddedPointPosition()); if (pointDistance > minVertexDistance) { float pathDeviationAngle = trail.GetPathDeviation(); if (pointDistance > maxVertexDistance || pathDeviationAngle > maxPathDeviation) { trail.AddPoint(playgroundSystem.particleCache[trail.particleId].position, EvaluateWidth(0), time, _calculationStartTime); } } } else { // First point creation trail.SetFirstPoint(playgroundSystem.particleCache[trail.particleId].position, playgroundSystem.particleCache[trail.particleId].velocity, EvaluateWidth(0), time, _calculationStartTime); } // Set the particle position info trail.SetParticlePosition(playgroundSystem.particleCache[trail.particleId].position); } // Update the trail points for (int x = 0; x < trail.trailPoints.Count; x++) { TrailPoint trailPoint = trail.trailPoints[x]; if (trailPoint.CanRemove()) { trail.RemovePoint(x); if (!_localSpace) { continue; } } float normalizedLifetime = trailPoint.GetNormalizedLifetime(); // Update trail points data trailPoint.Update( _calculationStartTime, EvaluateWidth(normalizedLifetime) ); // Set end point to follow particle if (!trail.IsDead() && x == trail.trailPoints.Count - 1) { trailPoint.position = trail.GetParticlePosition(); } // Rotation of trail points Vector3 currentPosition = trailPoint.position; Vector3 nextPosition = x < trail.trailPoints.Count - 1? trail.trailPoints[x + 1].position : currentPosition + (currentPosition - trail.trailPoints[x - 1].position); Vector3 lookDirection = Vector3.up; switch (renderMode) { case TrailRenderMode.Vertical: lookDirection = Vector3.forward; break; case TrailRenderMode.Billboard: lookDirection = (_billboardTransformPosition - currentPosition).normalized; break; } // If this is local space then recompute current & next position based on the local matrix if (_localSpace) { currentPosition = _localMatrix.MultiplyPoint3x4(currentPosition); nextPosition = _localMatrix.MultiplyPoint3x4(nextPosition); } Vector3 dir = renderMode != TrailRenderMode.CustomRenderScale? (Vector3.Cross(lookDirection, nextPosition - currentPosition)).normalized : customRenderScale; Vector3 lPoint = currentPosition + (dir * (trailPoint.width * .5f)); Vector3 rPoint = currentPosition - (dir * (trailPoint.width * .5f)); // Set mesh vertices into the rotated position trail.meshVerticesCache[x * 2] = lPoint; trail.meshVerticesCache[(x * 2) + 1] = rPoint; // Set uv float uvRatio = uvMode == TrailUvMode.Lifetime? normalizedLifetime : (x * 1f) / (trail.GetBirthIterator() - 1); trail.meshUvsCache[x * 2] = new Vector2(uvRatio, 0); trail.meshUvsCache[(x * 2) + 1] = new Vector2(uvRatio, 1f); // Update colors if (colorMode == TrailColorMode.Lifetime) { Color32 color = EvaluateColor(normalizedLifetime); color.a = (byte)(color.a * (pointArrayAlpha.Evaluate((x * 1f) / (trail.GetBirthIterator() - 1)))); trail.SetColor(x, color); } else { trail.SetColor(x, EvaluateColor(i, x)); } } } }