示例#1
0
 void EnumerateMagnets()
 {
     numMagnets = 0;
     if (Parent == null)
     {
         return;
     }
     foreach (Node node in Parent.Nodes)
     {
         ParticlesMagnet magnet = node as ParticlesMagnet;
         if (magnet != null)
         {
             if (numMagnets >= MaxMagnets)
             {
                 break;
             }
             Matrix32 transform   = magnet.CalcLocalToParentTransform();
             Widget   basicWidget = GetBasicWidget();
             if (basicWidget != null)
             {
                 for (Node n = Parent; n != basicWidget; n = n.Parent)
                 {
                     if (n.AsWidget != null)
                     {
                         transform *= n.AsWidget.CalcLocalToParentTransform();
                     }
                 }
             }
             magnets[numMagnets++] = new MagnetData {
                 Magnet = magnet,
                 PrecalcTransitionMatrix    = transform.CalcInversed(),
                 PrecalcInvTransitionMatrix = transform
             };
         }
     }
 }
示例#2
0
        void ApplyMagnetToParticle(Particle p, MagnetData magnetData, float delta)
        {
            ParticlesMagnet magnet         = magnetData.Magnet;
            Vector2         targetPosition = p.RegularPosition;

            targetPosition = magnetData.PrecalcTransitionMatrix.TransformVector(targetPosition);
            switch (magnet.Shape)
            {
            case EmitterShape.Area:
                // Looking for point of magnet's edge, in the direction of particle is moving.
                if (targetPosition.X > 0 && targetPosition.X < magnet.Size.X &&
                    targetPosition.X > 0 && targetPosition.Y < magnet.Size.Y)
                {
                    // Particle is got inside magnet, move it outside.
                    float d0 = targetPosition.X;
                    float d1 = targetPosition.Y;
                    float d2 = magnet.Size.X - targetPosition.X;
                    float d3 = magnet.Size.Y - targetPosition.Y;
                    if (d0 < d1 && d0 < d2 && d0 < d3)
                    {
                        targetPosition.X = 0;
                    }
                    else if (d1 < d0 && d1 < d2 && d1 < d3)
                    {
                        targetPosition.Y = 0;
                    }
                    else if (d2 < d0 && d2 < d1 && d2 < d3)
                    {
                        targetPosition.X = magnet.Size.X;
                    }
                    else
                    {
                        targetPosition.Y = magnet.Size.Y;
                    }
                }
                else
                {
                    targetPosition.X = Mathf.Clamp(targetPosition.X, 0, magnet.Size.X);
                    targetPosition.Y = Mathf.Clamp(targetPosition.Y, 0, magnet.Size.Y);
                }
                break;

            case EmitterShape.Ellipse:
                if (Math.Abs(magnet.Size.Y) > 1e-5)
                {
                    Vector2 center = 0.5f * magnet.Size;
                    float   k      = magnet.Size.X / magnet.Size.Y;
                    targetPosition   -= center;
                    targetPosition.Y *= k;
                    targetPosition    = targetPosition.Normalized;
                    targetPosition   *= magnet.Size.X * 0.5f;
                    targetPosition.Y /= k;
                    targetPosition   += center;
                }
                else
                {
                    targetPosition = 0.5f * magnet.Size;
                }
                break;

            case EmitterShape.Line:
                targetPosition.Y = 0.5f * magnet.Size.Y;
                if (targetPosition.X < 0.0f)
                {
                    targetPosition.X = 0.0f;
                }
                else if (targetPosition.X > magnet.Size.X)
                {
                    targetPosition.X = magnet.Size.X;
                }
                break;

            case EmitterShape.Point:
                targetPosition = 0.5f * magnet.Size;
                break;
            }
            targetPosition = magnetData.PrecalcInvTransitionMatrix.TransformVector(targetPosition);

            Vector2 direction       = targetPosition - p.RegularPosition;
            float   squaredDistance = direction.SqrLength;

            direction = direction.Normalized;

            float magnetStrength = magnet.Strength;

            if (magnet.Attenuation > 0.0001f)
            {
                magnetStrength /= (float)Math.Pow(squaredDistance, magnet.Attenuation * 0.5f);
            }

            float t = magnetStrength * p.MagnetAmountCurrent * delta;

            if (t * t > squaredDistance)
            {
                t = (float)Math.Sqrt(squaredDistance);
            }
            p.RegularPosition += direction * t;
        }