/****************************************************************************
        *       Trail functions
        ****************************************************************************/

        /// <summary>
        /// Creates a trail and assigns it to a particle.
        /// </summary>
        /// <param name="particleInfo">Information about the particle.</param>
        public void AddTrail(TrailParticleInfo particleInfo)
        {
            // Check parent object
            if (_parentGameObject == null)
            {
                _parentGameObject = new GameObject("Playground Trails (" + playgroundSystem.name + ")", typeof(PlaygroundTrailParent));
                _parentTransform  = _parentGameObject.transform;
                _parentGameObject.GetComponent <PlaygroundTrailParent>().trailsReference = this;
            }

            ParticlePlaygroundTrail newTrail = new ParticlePlaygroundTrail(maxPoints);

            newTrail.trailGameObject       = new GameObject("Playground Trail " + particleInfo.particleId);
            newTrail.trailTransform        = newTrail.trailGameObject.transform;
            newTrail.trailTransform.parent = _parentTransform;
            newTrail.trailRenderer         = newTrail.trailGameObject.AddComponent <MeshRenderer>();
            newTrail.trailMeshFilter       = newTrail.trailGameObject.AddComponent <MeshFilter>();
            newTrail.trailMesh             = new Mesh();
            newTrail.trailMesh.MarkDynamic();
            newTrail.trailMeshFilter.sharedMesh   = newTrail.trailMesh;
            newTrail.trailRenderer.sharedMaterial = material;

            newTrail.particleId = particleInfo.particleId;

            if (createFirstPointOnParticleBirth)
            {
                newTrail.SetFirstPoint(particleInfo.position, particleInfo.velocity, EvaluateWidth(0), time, _calculationStartTime);
            }

            _trails.Add(newTrail);
        }
Example #2
0
        /// <summary>
        /// Creates a trail and assigns it to a particle.
        /// </summary>
        /// <param name="particleInfo">Information about the particle.</param>
        public void CreateTrail(TrailParticleInfo particleInfo)
        {
            // Check parent object
            if (_parentGameObject == null)
            {
                _parentGameObject = new GameObject("Playground Trails (" + playgroundSystem.name + ")", typeof(PlaygroundTrailParent));
                _parentTransform  = _parentGameObject.transform;
                _parentGameObject.GetComponent <PlaygroundTrailParent>().trailsReference = this;
            }

            ParticlePlaygroundTrail newTrail = new ParticlePlaygroundTrail(maxPoints);

            newTrail.trailGameObject = new GameObject("Playground Trail " + trails.Count);
            layer = Mathf.Clamp(layer, 0, 32);
            newTrail.trailGameObject.layer = layer;
            newTrail.trailTransform        = newTrail.trailGameObject.transform;
            newTrail.trailTransform.parent = _parentTransform;
            newTrail.trailRenderer         = newTrail.trailGameObject.AddComponent <MeshRenderer>();
            newTrail.trailMeshFilter       = newTrail.trailGameObject.AddComponent <MeshFilter>();
            newTrail.trailMesh             = new Mesh();
            newTrail.trailMesh.MarkDynamic();
            newTrail.trailMeshFilter.sharedMesh   = newTrail.trailMesh;
            newTrail.trailRenderer.sharedMaterial = material;

            newTrail.particleId = particleInfo.particleId;

            if (createFirstPointOnParticleBirth)
            {
                float w = EvaluateWidth(0);
                newTrail.SetFirstPoint(particleInfo.position, particleInfo.velocity, w, time, _calculationStartTime);

                // Send trail point event to listeners
                if (_hasTrailPointEventListener)
                {
                    _eventTrailPoint.Update(
                        trails.Count,
                        0,
                        particleInfo.position,
                        w,
                        time,
                        _calculationStartTime
                        );
                    trailPointEvent(_eventTrailPoint);
                }
            }

            trails.Add(newTrail);
        }
		/****************************************************************************
			Trail functions
		 ****************************************************************************/

		/// <summary>
		/// Creates a trail and assigns it to a particle.
		/// </summary>
		/// <param name="particleInfo">Information about the particle.</param>
		public void AddTrail (TrailParticleInfo particleInfo)
		{
			// Check parent object
			if (_parentGameObject == null)
			{
				_parentGameObject = new GameObject("Playground Trails ("+playgroundSystem.name+")", typeof(PlaygroundTrailParent));
				_parentTransform = _parentGameObject.transform;
				_parentGameObject.GetComponent<PlaygroundTrailParent>().trailsReference = this;
			}

			ParticlePlaygroundTrail newTrail = new ParticlePlaygroundTrail(maxPoints);
			newTrail.trailGameObject = new GameObject("Playground Trail "+particleInfo.particleId);
			newTrail.trailTransform = newTrail.trailGameObject.transform;
			newTrail.trailTransform.parent = _parentTransform;
			newTrail.trailRenderer = newTrail.trailGameObject.AddComponent<MeshRenderer>();
			newTrail.trailMeshFilter = newTrail.trailGameObject.AddComponent<MeshFilter>();
			newTrail.trailMesh = new Mesh();
			newTrail.trailMesh.MarkDynamic();
			newTrail.trailMeshFilter.sharedMesh = newTrail.trailMesh;
			newTrail.trailRenderer.sharedMaterial = material;
			
			newTrail.particleId = particleInfo.particleId;

			if (createFirstPointOnParticleBirth)
				newTrail.SetFirstPoint(particleInfo.position, particleInfo.velocity, EvaluateWidth(0), time, _calculationStartTime);

			_trails.Add (newTrail);
		}
        /****************************************************************************
        *       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));
                    }
                }
            }
        }