public int AddParticles(ref ISystemData particlesToAdd)
        {
            // Copy particles in to our structure
            int numAdded = _systemData.CopyFrom (_systemData.NumParticles, ref particlesToAdd, 0, particlesToAdd.NumParticles);

            // Return number added
            return numAdded;
        }
 public UnmanagedSimulation(int maxNumParticles)
 {
     SoAData soaData =new SoAData(maxNumParticles);
     _systemData = soaData;
     _systemDataStreams = soaData;
     _worldBounds = new object();
     _is2D = false;
 }
Exemple #3
0
        public int CopyFrom(int offset, ref ISystemData src, int srcOffset, int count)
        {
            int capacityLeft = MaxNumParticles - NumParticles;
            int numToCopy = count < capacityLeft ? count : capacityLeft;

            // Position
            Marshal.Copy(src.PositionX, srcOffset, _positionStreamX + offset, numToCopy);
            Marshal.Copy(src.PositionY, srcOffset, _positionStreamY + offset, numToCopy);
            Marshal.Copy(src.PositionZ, srcOffset, _positionStreamZ + offset, numToCopy);

            // Time
            if (_lifespanStream != null)
                Marshal.Copy(src.Lifespan, srcOffset, _lifespanStream + offset, numToCopy);
            if (_timeRemainingStream != null)
                Marshal.Copy(src.TimeRemaining, srcOffset, _timeRemainingStream + offset, numToCopy);

            // Velocity
            if (_velocityStreamX != null)
                Marshal.Copy(src.VelocityX, srcOffset, _velocityStreamX + offset, numToCopy);
            if (_velocityStreamY != null)
                Marshal.Copy(src.VelocityY, srcOffset, _velocityStreamY + offset, numToCopy);
            if (_velocityStreamZ != null)
                Marshal.Copy(src.VelocityZ, srcOffset, _velocityStreamZ + offset, numToCopy);

            // Mass
            if (_massStream != null)
                Marshal.Copy(src.Mass, srcOffset, _massStream + offset, numToCopy);

            // UserData
            if (_userDataStream != null)
                Marshal.Copy(src.UserData, srcOffset, (System.IntPtr)(_userDataStream + offset), numToCopy);

            // Update number of particles
            _numParticles += numToCopy;

            // Return number copied
            return numToCopy;
        }
        public int CopyFrom(int offset, ref ISystemData src, int srcOffset, int count)
        {
            int capacityLeft = MaxNumParticles - NumParticles;
            int numToCopy = count < capacityLeft ? count : capacityLeft;

            for (int i = offset, j = srcOffset; i < numToCopy; i++, j++)
            {
                _systemData[i].px = src.PositionX[j];
                _systemData[i].py = src.PositionY[j];
                _systemData[i].pz = src.PositionZ[j];

                _systemData[i].vx = src.VelocityX[j];
                _systemData[i].vy = src.VelocityY[j];
                _systemData[i].vz = src.VelocityZ[j];

                _systemData[i].lifespan = src.Lifespan[i];
                _systemData[i].timeRemaining = src.TimeRemaining[i];
                _systemData[i].mass = src.Mass[i];
            }

            // Update number of particles
            _numParticles += numToCopy;

            // Return number copied
            return numToCopy;
        }
Exemple #5
0
        protected override void _EmitParticles(int numParticlesToEmit, float oneOverPPS, float dt, float pt, out ISystemData particlesToEmit)
        {
            // TODO: Pool this stuff
            if (_particlesToEmit.MaxNumParticles < numParticlesToEmit)
                _particlesToEmit = new SoAData(numParticlesToEmit);

            const int numBatches = 0;
            int numRemainder = numParticlesToEmit;

            float initialMass = _InitialMass(pt);
            float initialSpeed = _InitialSpeed(pt);
            float initialLifespan = _InitialLifespan(pt);

            bool emitOnSurfaceOnly = _EmitOnSurfaceOnly(pt);
            bool emitRingOnly = _EmitRingOnly(pt);

            float radius = _Radius(pt);

            // Emit remaining particles individually
            int numBatchesTimesFour = numBatches * 4;
            for (int i = 0; i < numRemainder; i++) {
                // Calculate pos on circle with a random angle
                float angle = (float)(RandomSource.NextDouble()) * MathF.TwoPI;
                float posX = MathF.Cos(angle) * radius;
                float posY = MathF.Sin(angle) * radius;
                float posZ = emitRingOnly ? 0.0f : MathF.Sin((float)(RandomSource.NextDouble()) * MathF.TwoPI) * radius;

                // If this emitter is supposed to emit only on the surface
                // don't need to get a random distance
                if (!emitOnSurfaceOnly) {
                    float distance = (float)RandomSource.NextDouble();
                    posX *= distance;
                    posY *= distance;
                    posZ *= distance;
                }

                // Transform position
                // TODO: Matrix and transform stuff

                // Length
                float len = MathF.Sqrt((posX * posX) + (posY * posY) + (posZ * posZ));

                // Normalize
                float velX = posX / len;
                float velY = posY / len;
                float velZ = posZ / len;

                // Scale by speed
                velX *= initialSpeed;
                velY *= initialSpeed;
                velZ *= initialSpeed;

                // Avoid clumping by doing some pre-simulation
                float preSimTime = (i + 1) * oneOverPPS;
                if (oneOverPPS > 0) {
                    posX += velX * preSimTime;
                    posY += velY * preSimTime;
                    posZ += velZ * preSimTime;
                }

                // Store out position
                _particlesToEmit._positionStreamX[numBatchesTimesFour + i] = posX;
                _particlesToEmit._positionStreamY[numBatchesTimesFour + i] = posY;
                _particlesToEmit._positionStreamZ[numBatchesTimesFour + i] = posZ;

                // Store out velocity
                _particlesToEmit._velocityStreamX[numBatchesTimesFour + i] = velX;
                _particlesToEmit._velocityStreamY[numBatchesTimesFour + i] = velY;
                _particlesToEmit._velocityStreamZ[numBatchesTimesFour + i] = velZ;

                // Store out lifespan and mass
                float lifespan = initialLifespan - preSimTime;
                _particlesToEmit._lifespanStream[numBatchesTimesFour + i] = lifespan;
                _particlesToEmit._timeRemainingStream[numBatchesTimesFour + i] = lifespan;
                _particlesToEmit._massStream[numBatchesTimesFour + i] = initialMass;
            }

            // Assign number of particles
            _particlesToEmit._numParticles = numParticlesToEmit;

            // Assign the output variable
            particlesToEmit = _particlesToEmit;
        }
Exemple #6
0
 /// <summary>
 /// This method is a request to emit a number of particles. The implementor should assign, and populate 
 /// the <see cref="ISystemData"/> passed as a parameter with the particles it does emit.
 /// </summary>
 /// 
 /// <remarks>
 /// If the value of  <see cref="particlesToEmit"/> is not <see cref="null"/>, <see cref="ISimulation.AddParticles"/>
 /// will be called following the return of this method.
 /// </remarks>
 /// 
 /// <param name="numParticlesToEmit"> The number of particles requested for emission </param>
 /// <param name="oneOverPPS"> A value which does not need to be recomputed, and is needed in most emitters (1.0 / ParticlesPerSecond) </param>
 /// <param name="dt"> The time, in seconds, since the last call to AdvanceTime(). </param>
 /// <param name="pt"> A normalized value which is to used by the Emitter as an interpolation parameter. </param>
 /// <param name="particlesToEmit"> A <see cref="ISystemData"/> full of particles to add to the <see cref="ISimulation"/>. </param>
 protected abstract void _EmitParticles(int numParticlesToEmit, float oneOverPPS, float dt, float pt, out ISystemData particlesToEmit);
Exemple #7
0
        public int CopyFrom(int offset, ref ISystemData src, int srcOffset, int count)
        {
            int capacityLeft = MaxNumParticles - NumParticles;
            int numToCopy = count < capacityLeft ? count : capacityLeft;

            // Position
            System.Array.Copy(src.PositionX, srcOffset, _positionStreamX, offset, numToCopy);
            System.Array.Copy(src.PositionY, srcOffset, _positionStreamY, offset, numToCopy);
            System.Array.Copy(src.PositionZ, srcOffset, _positionStreamZ, offset, numToCopy);

            // Time
            System.Array.Copy(src.Lifespan, srcOffset, _lifespanStream, offset, numToCopy);
            System.Array.Copy(src.TimeRemaining, srcOffset, _timeRemainingStream, offset, numToCopy);

            // Velocity
            System.Array.Copy(src.VelocityX, srcOffset, _velocityStreamX, offset, numToCopy);
            System.Array.Copy(src.VelocityY, srcOffset, _velocityStreamY, offset, numToCopy);
            System.Array.Copy(src.VelocityZ, srcOffset, _velocityStreamZ, offset, numToCopy);

            // Mass
            System.Array.Copy(src.Mass, srcOffset, _massStream, offset, numToCopy);

            // UserData
            System.Array.Copy(src.UserData, srcOffset, _userDataStream, offset, numToCopy);

            // Update number of particles
            _numParticles += numToCopy;

            // Return number copied
            return numToCopy;
        }