Exemplo n.º 1
0
    void SubdivideParticle(WaveParticle particle)
    {
        float angle = particle.dispersionAngle / 3.0f;

        particles.Add(new WaveParticle
        {
            birthPosition   = particle.birthPosition,
            direction       = Utils.Rotate(particle.direction, angle),
            amplitude       = particle.amplitude / 3.0f,
            dispersionAngle = particle.dispersionAngle / 3.0f,
            birthTime       = particle.birthTime,
        });

        particles.Add(new WaveParticle
        {
            birthPosition   = particle.birthPosition,
            direction       = Utils.Rotate(particle.direction, -angle),
            amplitude       = particle.amplitude / 3.0f,
            dispersionAngle = particle.dispersionAngle / 3.0f,
            birthTime       = particle.birthTime,
        });

        particle.dispersionAngle /= 3.0f;
        particle.amplitude       /= 3.0f;
    }
Exemplo n.º 2
0
    public void calculateSubdivisions(int currentFrame)
    {
        int currentIndex = mSubdivisions[currentFrame];

        // the max uint value represents a non-existent wave particle
        while (currentIndex != NO_PARTICLE)
        {
            WaveParticle currentParticle = mParticles[currentIndex];


            if (Mathf.Abs(currentParticle.amplitude) > _waveParticleKillThreshold)
            {
                Vector2 origin             = currentParticle.origin;
                Vector2 middleVelocity     = currentParticle.velocity;
                float   newDispersionAngle = currentParticle.dispersionAngle / 3;
                float   newAmplitude       = currentParticle.amplitude / 3;
                Vector2 leftVelocity       = Quaternion.AngleAxis(newDispersionAngle * (180f / Mathf.PI), Vector3.forward) * middleVelocity;
                Vector2 rightVelocity      = Quaternion.AngleAxis(newDispersionAngle * (-180f / Mathf.PI), Vector3.forward) * middleVelocity;

                addParticle(WaveParticle.createWaveParticleUnvalidated(origin, middleVelocity, newAmplitude, newDispersionAngle, currentParticle.startingFrame));
                addParticle(WaveParticle.createWaveParticleUnvalidated(origin, leftVelocity, newAmplitude, newDispersionAngle, currentParticle.startingFrame));
                addParticle(WaveParticle.createWaveParticleUnvalidated(origin, rightVelocity, newAmplitude, newDispersionAngle, currentParticle.startingFrame));
            }

            int nextIndex = _eventIndices[currentIndex];
            mParticles[currentIndex]    = WaveParticle.DEAD_PARTICLE;
            _eventIndices[currentIndex] = NO_PARTICLE;
            currentIndex = nextIndex;
        }

        mSubdivisions[currentFrame] = NO_PARTICLE;
    }
Exemplo n.º 3
0
 public void AddParticle(Vector2 position, Vector2 velocity, float amplitude, float dispersionAngle)
 {
     if (amplitude > _waveParticleKillThreshold)
     {
         WaveParticle wp = WaveParticle.createWaveParticle(position, velocity, amplitude, dispersionAngle, currentFrame);
         waveParticles.addParticle(wp);
     }
 }
Exemplo n.º 4
0
    //public IEnumerator<WaveParticle> GetEnumerator()
    //{
    //    Assert.IsTrue(mCurrentHead < _numParticles);
    //    int startIndex = (mCurrentHead == 0) ? _numParticles - 1 : mCurrentHead - 1;
    //    int index = startIndex;

    //    {
    //        Assert.IsTrue(index != NO_PARTICLE);
    //        if (mParticles[index].amplitude != 0)
    //        {
    //            WaveParticle particle = mParticles[index];
    //            yield return particle;
    //        }
    //        index = (index == 0) ? _numParticles - 1 : index - 1;
    //    }

    //    while (index != startIndex)
    //    {
    //        Assert.IsTrue(index != NO_PARTICLE);
    //        if (mParticles[index].amplitude != 0)
    //        {
    //            WaveParticle particle = mParticles[index];
    //            yield return particle;
    //        }
    //        index = (index == 0) ? _numParticles - 1 : index - 1;
    //    }
    //}

    public void addParticle(WaveParticle particle)
    {
        // TODO: clean up code!

        float timeToSubdivision        = WaveParticle.RADIUS * 0.5f / (WaveParticle.PARTICLE_SPEED * particle.dispersionAngle);
        bool  reflectBeforeSubdivision = false;

        {
            // TODO: Calculate Raycast
            Vector3    origin    = new Vector3(particle.origin.x - 2f, 0f, particle.origin.y - 2f);
            Vector3    direction = new Vector3(particle.velocity.x, 0f, particle.velocity.y);
            RaycastHit hit;
            if (Physics.Raycast(origin, direction, out hit))
            {
                float timeToReflection = hit.distance / WaveParticle.PARTICLE_SPEED;

                if (timeToReflection < timeToSubdivision)
                {
                    reflectBeforeSubdivision = true;
                    /// reflection
                    ///
                    int reflectionFrame = ((ushort)(Mathf.RoundToInt(timeToReflection / Time.fixedDeltaTime)));
                    reflectionFrame = (particle.startingFrame + reflectionFrame) % WaveParticle.FRAME_CYCLE_LENGTH;

                    int oldParticleIndex = mReflections[reflectionFrame];

                    int nextIndex = oldParticleIndex;
                    mReflections[reflectionFrame] = mCurrentHead;

                    mParticles[mCurrentHead]    = particle;
                    _eventIndices[mCurrentHead] = nextIndex;
                }
                Debug.DrawLine(origin, hit.point);
            }
            else
            {
                Debug.DrawRay(origin, direction, Color.red);
            }
        }

        if (!reflectBeforeSubdivision)
        {
            int subdivisionFrame = ((ushort)(Mathf.RoundToInt(timeToSubdivision / Time.fixedDeltaTime)));
            subdivisionFrame = (particle.startingFrame + subdivisionFrame) % WaveParticle.FRAME_CYCLE_LENGTH;


            int oldParticleIndex = mSubdivisions[subdivisionFrame];
            int nextIndex        = oldParticleIndex;
            mSubdivisions[subdivisionFrame] = mCurrentHead;

            mParticles[mCurrentHead]    = particle;
            _eventIndices[mCurrentHead] = nextIndex;
        }

        mCurrentHead = (mCurrentHead + 1) % _numParticles;
    }
    public void TestSubdivisions()
    {
        var pc = new CPUParticleContainer();

        pc.Initialise(30000, 0.0001f);
        for (int i = 0; i < 1000000; i++)
        {
            pc.addParticle(WaveParticle.createWaveParticle(new Vector2(0, 0), new Vector2(0.5f, 0.5f), 1f, Mathf.PI / 2, 0));
        }
    }
    public void TestParticleAdditions()
    {
        var pc = new CPUParticleContainer();

        pc.Initialise(30000, 0.0001f);
        pc.addParticle(WaveParticle.createWaveParticle(new Vector2(0, 0), new Vector2(1, 0), 1f, Mathf.PI / 2, 0));
        int count = 0;

        foreach (var wp in pc)
        {
            count++;
        }
        Assert.That(count, Is.EqualTo(1));
        //Assert.That(count, Is.EqualTo(pc.numActiveParticles));
    }
Exemplo n.º 7
0
    public void addParticle(WaveParticle particle)

    {
        ///
        /// Calculate when WaveParticle is due to subdivide
        ///
        int subdivisionFrame;

        {
            // if the dispersion angle is 0, the subdivide particle at latest possilbe time
            if (particle.dispersionAngle == 0f)
            {
                subdivisionFrame = particle.startingFrame + WaveParticle.FRAME_CYCLE_LENGTH;
            }
            else
            {
                float timeToSubdivision   = WaveParticle.RADIUS * 0.5f / (WaveParticle.PARTICLE_SPEED * particle.dispersionAngle);
                int   framesToSubdivision = (Mathf.RoundToInt(timeToSubdivision / Time.fixedDeltaTime));
                if (framesToSubdivision > WaveParticle.FRAME_CYCLE_LENGTH)
                {
                    framesToSubdivision = WaveParticle.FRAME_CYCLE_LENGTH;
                }
                subdivisionFrame = (framesToSubdivision + particle.startingFrame) % WaveParticle.FRAME_CYCLE_LENGTH;
            }
        }

        ///
        /// Using the calculated subdivision frame, add the current particle as an event in that frame
        ///
        addSubdivisionEvent((_currentHead + _pendingParticlesHead) % _particleContainerSize, subdivisionFrame);

        ///
        /// Add the current particle to the to-be-committed buffer
        ///
        /// Commit the current buffer if it ends up full
        ///
        _pendingParticles[_pendingParticlesHead++] = particle;
        if (_pendingParticlesHead >= _pendingParticles.Length)
        {
            commitParticles();
        }
    }
Exemplo n.º 8
0
    /// <summary>
    /// Create new wave particles due to computed object motion.
    /// </summary>
    void GenerateWaveParticles()
    {
        // TODO: Fix the ripple generator.
        if (Input.GetKey(KeyCode.Mouse0))
        {
            RaycastHit globalMousePosition;
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out globalMousePosition))
            {
                Vector3 localMousePosition = transform.InverseTransformPoint(globalMousePosition.point);
                Vector2 clickLocation      = new Vector2(localMousePosition.x + extendedHeightField.Width / 2f, localMousePosition.z + extendedHeightField.Height / 2f);


                // Create a small ripple of particles
                {
                    WaveParticle wp = WaveParticle.createWaveParticle(clickLocation, new Vector2(0.5f, 0.5f), 0.8f, Mathf.PI * 2, currentFrame);
                    waveParticles.addParticle(wp);
                }
            }
        }
    }