Ejemplo n.º 1
0
        /// <inheritdoc/>
        public override unsafe void Update(float dt, ParticlePool pool)
        {
            if (!pool.FieldExists(ParticleFields.Position) || !pool.FieldExists(ParticleFields.Velocity))
            {
                return;
            }

            var posField  = pool.GetField(ParticleFields.Position);
            var velField  = pool.GetField(ParticleFields.Velocity);
            var lifeField = pool.GetField(ParticleFields.Life);

            foreach (var particle in pool)
            {
                var surfacePoint  = new Vector3(0, 0, 0);
                var surfaceNormal = new Vector3(0, 1, 0);

                var particlePos = (*((Vector3 *)particle[posField]));
                var particleVel = (*((Vector3 *)particle[velField]));

                var isInside = false;
                if (FieldShape != null)
                {
                    FieldShape.PreUpdateField(WorldPosition, WorldRotation, WorldScale);

                    isInside = FieldShape.IsPointInside(particlePos, out surfacePoint, out surfaceNormal);
                }

                if (IsHollow != isInside)
                {
                    if (IsHollow)
                    {
                        surfaceNormal *= -1;
                    }

                    // The particle is on the wrong side of the collision shape and must collide
                    (*((Vector3 *)particle[posField])) = surfacePoint;

                    var verIncidentCoef = Vector3.Dot(surfaceNormal, particleVel);

                    var verticalIncidentVelocity   = verIncidentCoef * surfaceNormal;
                    var horizontalIncidentVelocity = particleVel - verticalIncidentVelocity;

                    particleVel = horizontalIncidentVelocity * (1 - Friction) +
                                  verticalIncidentVelocity * ((verIncidentCoef > 0) ? Restitution : -Restitution);

                    (*((Vector3 *)particle[velField])) = particleVel;


                    // TODO Maybe set some collision flags if other calculations depend on them

                    // Possibly kill the particle
                    if (KillParticles)
                    {
                        // Don't set the particle's life directly to 0 just yet - it might need to spawn other particles on impact
                        (*((float *)particle[lifeField])) = MathUtil.ZeroTolerance;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        public override unsafe void Update(float dt, ParticlePool pool)
        {
            // The force field operates over position and velocity. If the particles don't have such fields we can't run this update
            if (!pool.FieldExists(ParticleFields.Position) || !pool.FieldExists(ParticleFields.Velocity))
            {
                return;
            }

            var posField = pool.GetField(ParticleFields.Position);
            var velField = pool.GetField(ParticleFields.Velocity);

            // Depending on our settings some of the energy will be lost (it directly translates to changes in position)
            //  and some of the energy will be preserved (it translates to changes in velocity)
            var directToPosition = 1f - EnergyConservation;

            foreach (var particle in pool)
            {
                var alongAxis  = new Vector3(0, 1, 0);
                var awayAxis   = new Vector3(0, 0, 1);
                var aroundAxis = new Vector3(1, 0, 0);

                var particlePos = (*((Vector3 *)particle[posField]));
                var particleVel = (*((Vector3 *)particle[velField]));

                var forceMagnitude = 1f;
                if (FieldShape != null)
                {
                    FieldShape.PreUpdateField(WorldPosition, WorldRotation, WorldScale);

                    forceMagnitude = FieldShape.GetDistanceToCenter(particlePos, particleVel, out alongAxis, out aroundAxis, out awayAxis);

                    forceMagnitude = FieldFalloff.GetStrength(forceMagnitude);
                }
                forceMagnitude *= dt * parentScale;

                var totalForceVector = ForceFixed +
                                       alongAxis * ForceDirected +
                                       aroundAxis * ForceVortex +
                                       awayAxis * ForceRepulsive;

                totalForceVector *= forceMagnitude;

                // Force contribution to velocity - conserved energy
                var vectorContribution = totalForceVector * EnergyConservation;
                (*((Vector3 *)particle[velField])) += vectorContribution;

                // Force contribution to position - lost energy
                vectorContribution = (vectorContribution * (dt * 0.5f)) + (totalForceVector * directToPosition);
                (*((Vector3 *)particle[posField])) += vectorContribution;
            }
        }
Ejemplo n.º 3
0
        public override unsafe void Update(float dt, ParticlePool pool)
        {
            if (!pool.FieldExists(ParticleFields.Position) || !pool.FieldExists(ParticleFields.Velocity))
            {
                return;
            }

            var posField = pool.GetField(ParticleFields.Position);
            var velField = pool.GetField(ParticleFields.Velocity);
//            var colField = pool.GetField(ParticleFields.Color);

            var directToPosition = 1f - EnergyConservation;

            foreach (var particle in pool)
            {
                var alongAxis  = new Vector3(0, 1, 0);
                var awayAxis   = new Vector3(0, 0, 1);
                var aroundAxis = new Vector3(1, 0, 0);

                var particlePos = (*((Vector3 *)particle[posField]));
                var particleVel = (*((Vector3 *)particle[velField]));

                var forceMagnitude = 1f;
                if (FieldShape != null)
                {
                    FieldShape.PreUpdateField(WorldPosition, WorldRotation, WorldScale);

                    forceMagnitude = FieldShape.GetDistanceToCenter(particlePos, particleVel, out alongAxis, out aroundAxis, out awayAxis);

                    forceMagnitude = FieldFalloff.GetStrength(forceMagnitude);
                }
                forceMagnitude *= dt * parentScale;

                var totalForceVector = ForceFixed +
                                       alongAxis * ForceDirected +
                                       aroundAxis * ForceVortex +
                                       awayAxis * ForceRepulsive;

                totalForceVector *= forceMagnitude;

                // Force contribution to velocity - conserved energy
                var vectorContribution = totalForceVector * EnergyConservation;
                (*((Vector3 *)particle[velField])) += vectorContribution;

                // Force contribution to position - lost energy
                vectorContribution = (vectorContribution * (dt * 0.5f)) + (totalForceVector * directToPosition);
                (*((Vector3 *)particle[posField])) += vectorContribution;
            }
        }