예제 #1
0
	public FParticleSystem (int maxParticleCount)
	{
		_maxParticleCount = maxParticleCount;
		_particles = new FParticle[_maxParticleCount];
		
		_availableParticles = new FParticle[_maxParticleCount];
		_availableParticleCount = _maxParticleCount;
		_unavailableParticleIndex = _maxParticleCount-1;
		
		for(int p = 0; p<_maxParticleCount; p++)
		{
			_particles[p] = _availableParticles[p] = new FParticle();	
		}
		
		ListenForUpdate(HandleUpdate);
	}
예제 #2
0
    public FParticleSystem(int maxParticleCount)
    {
        _maxParticleCount = maxParticleCount;
        _particles        = new FParticle[_maxParticleCount];

        _availableParticles       = new FParticle[_maxParticleCount];
        _availableParticleCount   = _maxParticleCount;
        _unavailableParticleIndex = _maxParticleCount - 1;

        for (int p = 0; p < _maxParticleCount; p++)
        {
            _particles[p] = _availableParticles[p] = new FParticle();
        }

        ListenForUpdate(HandleUpdate);
    }
예제 #3
0
    private void VerletIntegrate(float InSubstepTime, Vector3 Gravity)
    {
        int   NumParticles   = NumSegments + 1;
        float SubstepTimeSqr = InSubstepTime * InSubstepTime;

        for (int ParticleIndex = 0; ParticleIndex < NumParticles; ParticleIndex++)
        {
            FParticle particle = Particles[ParticleIndex];
            if (particle.bFree)
            {
                Vector3 Velocity    = particle.position - particle.OldPosition;
                Vector3 NewPosition = particle.position + Velocity + (SubstepTimeSqr * Gravity);

                particle.OldPosition = particle.position;
                particle.position    = NewPosition;
            }
        }
    }
예제 #4
0
    private void HandleUpdate()
    {
        float deltaTime = Time.deltaTime;

        for (int p = 0; p < _maxParticleCount; p++)
        {
            FParticle particle = _particles[p];

            if (particle.timeRemaining <= 0)
            {
                //this particle isn't alive, go to the next one
            }
            else if (particle.timeRemaining <= deltaTime)            //is it going to end during this update?
            {
                //add it back to the available particles
                _availableParticles[_availableParticleCount] = particle;
                _availableParticleCount++;
                particle.timeRemaining = 0;

                //don't bother updating it because it won't be rendered anyway
            }
            else             //do the update!
            {
                particle.timeRemaining -= deltaTime;

                particle.color.r += particle.redDeltaPerSecond * deltaTime;
                particle.color.g += particle.greenDeltaPerSecond * deltaTime;
                particle.color.b += particle.blueDeltaPerSecond * deltaTime;
                particle.color.a += particle.alphaDeltaPerSecond * deltaTime;

                particle.scale += particle.scaleDeltaPerSecond * deltaTime;

                particle.speedX += accelX * deltaTime;
                particle.speedY += accelY * deltaTime;

                particle.x += particle.speedX * deltaTime;
                particle.y += particle.speedY * deltaTime;
            }
        }

        _isMeshDirty = true;         //needs redraw!
    }
예제 #5
0
    void Start()
    {
        int NumParticles = NumSegments + 1;

        Particles.Clear();

        // Use linerenderer as visual cable representation
        _lineRenderer = transform.GetComponent <LineRenderer>();
        if (_lineRenderer == null)
        {
            _lineRenderer = gameObject.AddComponent <LineRenderer>();
        }
        _lineRenderer.SetVertexCount(NumSegments);
        _lineRenderer.SetWidth(.2f, .2f);
        _lineRenderer.SetColors(Color.cyan, Color.blue);

        Vector3 Delta = CableEnd.position - CableStart.position;

        for (int ParticleIndex = 0; ParticleIndex < NumParticles; ParticleIndex++)
        {
            Transform newTransform = Instantiate(PrefabParticle, Vector3.zero, Quaternion.identity) as Transform;

            float   Alpha = (float)ParticleIndex / (float)NumParticles;
            Vector3 InitializePosition = CableStart.transform.position + (Alpha * Delta);

            FParticle particle = newTransform.GetComponent <FParticle>();
            particle.position         = InitializePosition;
            particle.OldPosition      = InitializePosition;
            particle.transform.parent = this.transform;
            particle.name             = "Particle_0" + ParticleIndex.ToString();
            Particles.Add(particle);

            if (ParticleIndex == 0 || ParticleIndex == (NumParticles - 1))
            {
                particle.bFree = false;
            }
            else
            {
                particle.bFree = true;
            }
        }
    }
예제 #6
0
    private void SolveConstraints()
    {
        float SegmentLength = CableLength / (float)NumSegments;

        // For each iteration
        for (int IterationIndex = 0; IterationIndex < SolverIterations; IterationIndex++)
        {
            // For each segment
            for (int SegmentIndex = 0; SegmentIndex < NumSegments; SegmentIndex++)
            {
                FParticle ParticleA = Particles[SegmentIndex];
                FParticle ParticleB = Particles[SegmentIndex + 1];
                // Solve for this pair of particles
                SolveDistanceConstraint(ParticleA, ParticleB, SegmentLength);

                // Update render position
                _lineRenderer.SetPosition(SegmentIndex, ParticleA.position);
            }
        }
    }
예제 #7
0
    void Update()
    {
        // Update start+end positions first
        FParticle StartParticle = Particles[0];

        StartParticle.position = StartParticle.OldPosition = CableStart.position;

        FParticle EndParticle = Particles[NumSegments];

        EndParticle.position = EndParticle.OldPosition = CableEnd.position;

        Vector3 Gravity    = Physics.gravity;
        float   UseSubstep = Mathf.Max(SubstepTime, 0.005f);

        TimeRemainder += Time.deltaTime;
        while (TimeRemainder > UseSubstep)
        {
            PreformSubstep(UseSubstep, Gravity);
            TimeRemainder -= UseSubstep;
        }
    }
예제 #8
0
    void SolveDistanceConstraint(FParticle ParticleA, FParticle ParticleB, float DesiredDistance)
    {
        // Find current difference between particles
        Vector3 Delta           = ParticleB.position - ParticleA.position;
        float   CurrentDistance = Delta.magnitude;
        float   ErrorFactor     = (CurrentDistance - DesiredDistance) / CurrentDistance;

        // Only move free particles to satisfy constraints
        if (ParticleA.bFree && ParticleB.bFree)
        {
            ParticleA.position += ErrorFactor * 0.5f * Delta;
            ParticleB.position -= ErrorFactor * 0.5f * Delta;
        }
        else if (ParticleA.bFree)
        {
            ParticleA.position += ErrorFactor * Delta;
        }
        else if (ParticleB.bFree)
        {
            ParticleB.position -= ErrorFactor * Delta;
        }
    }
예제 #9
0
    override public void PopulateRenderLayer()
    {
        if (_isOnStage && _firstFacetIndex != -1)
        {
            _isMeshDirty = false;

            Vector3[] vertices = _renderLayer.vertices;
            Vector2[] uvs      = _renderLayer.uvs;
            Color[]   colors   = _renderLayer.colors;

            float a  = _concatenatedMatrix.a;
            float b  = _concatenatedMatrix.b;
            float c  = _concatenatedMatrix.c;
            float d  = _concatenatedMatrix.d;
            float tx = _concatenatedMatrix.tx;
            float ty = _concatenatedMatrix.ty;

//			Vector2 unitVector = _concatenatedMatrix.GetTransformedUnitVector();
//			float ux = unitVector.x;
//			float uy = unitVector.y;

            int vertexIndex0 = _firstFacetIndex * 4;
            int vertexIndex1 = vertexIndex0 + 1;
            int vertexIndex2 = vertexIndex0 + 2;
            int vertexIndex3 = vertexIndex0 + 3;

            float px;
            float py;
            float ps;

            for (int p = 0; p < _maxParticleCount; p++)
            {
                FParticle particle = _particles[p];

                if (particle.timeRemaining > 0)
                {
                    ps = particle.scale;

                    px = particle.x + particle.resultTopLeftX * ps;
                    py = particle.y + particle.resultTopLeftY * ps;
                    vertices[vertexIndex0] = new Vector3(px * a + py * c + tx, px * b + py * d + ty, _meshZ);

                    px = particle.x + particle.resultTopRightX * ps;
                    py = particle.y + particle.resultTopRightY * ps;
                    vertices[vertexIndex1] = new Vector3(px * a + py * c + tx, px * b + py * d + ty, _meshZ);

                    px = particle.x + particle.resultBottomRightX * ps;
                    py = particle.y + particle.resultBottomRightY * ps;
                    vertices[vertexIndex2] = new Vector3(px * a + py * c + tx, px * b + py * d + ty, _meshZ);

                    px = particle.x + particle.resultBottomLeftX * ps;
                    py = particle.y + particle.resultBottomLeftY * ps;
                    vertices[vertexIndex3] = new Vector3(px * a + py * c + tx, px * b + py * d + ty, _meshZ);

                    uvs[vertexIndex0] = particle.uvTopLeft;
                    uvs[vertexIndex1] = particle.uvTopRight;
                    uvs[vertexIndex2] = particle.uvBottomRight;
                    uvs[vertexIndex3] = particle.uvBottomLeft;

                    colors[vertexIndex0] = particle.color;
                    colors[vertexIndex1] = particle.color;
                    colors[vertexIndex2] = particle.color;
                    colors[vertexIndex3] = particle.color;
                }
                else                 //it's dead so put zeroes in
                {
                    vertices[vertexIndex0].Set(50, 0, 1000000);
                    vertices[vertexIndex1].Set(50, 0, 1000000);
                    vertices[vertexIndex2].Set(50, 0, 1000000);
                    vertices[vertexIndex3].Set(50, 0, 1000000);
                }

                vertexIndex0 += 4;
                vertexIndex1 += 4;
                vertexIndex2 += 4;
                vertexIndex3 += 4;
            }

            _renderLayer.HandleVertsChange();
        }
    }
예제 #10
0
    private void HandleUpdate()
    {
        float deltaTime = Time.deltaTime;

        for (int p = 0; p < _maxParticleCount; p++)
        {
            FParticle particle = _particles[p];

            if (particle.timeRemaining <= 0)
            {
                //this particle isn't alive, go to the next one
            }
            else if (particle.timeRemaining <= deltaTime)            //is it going to end during this update?
            {
                //add it back to the available particles
                _availableParticles[_availableParticleCount] = particle;
                _availableParticleCount++;
                particle.timeRemaining = 0;

                //don't bother updating it because it won't be rendered anyway
            }
            else             //do the update!
            {
                particle.timeRemaining -= deltaTime;

                particle.color.r += particle.redDeltaPerSecond * deltaTime;
                particle.color.g += particle.greenDeltaPerSecond * deltaTime;
                particle.color.b += particle.blueDeltaPerSecond * deltaTime;
                particle.color.a += particle.alphaDeltaPerSecond * deltaTime;

                particle.scale += particle.scaleDeltaPerSecond * deltaTime;

                particle.speedX += accelX * deltaTime;
                particle.speedY += accelY * deltaTime;

                particle.x += particle.speedX * deltaTime;
                particle.y += particle.speedY * deltaTime;

                if (particle.doesNeedRotationUpdates)
                {
                    particle.rotation += particle.rotationDeltaPerSecond * (double)deltaTime;

                    float sin = (float)Math.Sin(particle.rotation);
                    float cos = (float)Math.Cos(particle.rotation);

                    float ix, iy;

                    ix = particle.initialTopLeft.x;
                    iy = particle.initialTopLeft.y;
                    particle.resultTopLeftX = ix * cos - iy * sin;
                    particle.resultTopLeftY = ix * sin + iy * cos;

                    ix = particle.initialTopRight.x;
                    iy = particle.initialTopRight.y;
                    particle.resultTopRightX = ix * cos - iy * sin;
                    particle.resultTopRightY = ix * sin + iy * cos;

                    ix = particle.initialBottomRight.x;
                    iy = particle.initialBottomRight.y;
                    particle.resultBottomRightX = ix * cos - iy * sin;
                    particle.resultBottomRightY = ix * sin + iy * cos;

                    ix = particle.initialBottomLeft.x;
                    iy = particle.initialBottomLeft.y;
                    particle.resultBottomLeftX = ix * cos - iy * sin;
                    particle.resultBottomLeftY = ix * sin + iy * cos;
                }
            }
        }

        _isMeshDirty = true;         //needs redraw!
    }