예제 #1
0
        public void Execute(ParticleSystemJobData particles, int startIndex, int count)
        {
            var positions = particles.positions;

            int endIndex = startIndex + count;

            for (int i = startIndex; i < endIndex; i++)
            {
                int    particleIndex    = sortKeys[i].Index;
                float3 particlePosition = positions[particleIndex];

                int i2 = i + 1;
                while (i2 < particles.count)
                {
                    int    particleIndex2    = sortKeys[i2++].Index;
                    float3 particlePosition2 = positions[particleIndex2];

                    if (math.distancesq(particlePosition, particlePosition2) < distance * distance)
                    {
                        lineList.Enqueue(new Line
                        {
                            Start = particlePosition,
                            End   = particlePosition2
                        });
                    }
                    else if (particlePosition2.x - particlePosition.x > distance)
                    {
                        break;
                    }
                }
            }
        }
 public void Execute(ParticleSystemJobData particles, int i)
 {
     // Collider Collisions
     if (collisionPointsCount > 0)
     {
         int maxParticles = ClipperTest.maxParticleCollisions > collisionPointsCount ? collisionPointsCount : ClipperTest.maxParticleCollisions;
         for (int j = 0; j < maxParticles; j++)
         {
             float windPushBackPercent = 1;
             float fireBurnUpPercent   = .075f;
             if (myElement == ElementType.Earth)
             {
                 windPushBackPercent = windPushBackPercent * .75f;
                 fireBurnUpPercent   = fireBurnUpPercent * .75f;
             }
             if (elementCollision[j] == ElementType.Wind)
             {
                 PushBackCollision(particles, i, j, maxParticles, windPushBackPercent);
             }
             else if (elementCollision[j] == ElementType.Fire)
             {
                 KillOtherParticle(particles, i, j, maxParticles, fireBurnUpPercent);
             }
         }
     }
 }
        void PushBackCollision(ParticleSystemJobData particles, int particleIndex, int collisionIndex, int maxParticles, float percent)
        {
            float   particleWeight  = collisionPointsCount / maxParticles;
            Vector3 collisionPoint  = new Vector3(collisionPointsX[collisionIndex], collisionPointsY[collisionIndex], collisionPointsZ[collisionIndex]);
            Vector3 currentPosition = new Vector3(particles.positions.x[particleIndex], particles.positions.y[particleIndex], particles.positions.z[particleIndex]);
            float   distance        = Vector2.Distance(collisionPoint, currentPosition);

            if (distance < maxParticleCollisionEffectDistance)
            {
                var   aliveTimePercent   = particles.aliveTimePercent;
                float distanceForceConst = percent * (1 - (distance / (maxParticleCollisionEffectDistance * particleWeight))) * deltaTime;

                var velocitiesX = particles.velocities.x;
                var velocitiesY = particles.velocities.y;
                var velocitiesZ = particles.velocities.z;
                if (velocitiesX[particleIndex] < collisionVelocitiesX[collisionIndex])
                {
                    velocitiesX[particleIndex] += collisionVelocitiesX[collisionIndex] * distanceForceConst * particleWeight;
                }
                if (velocitiesY[particleIndex] < collisionVelocitiesY[collisionIndex])
                {
                    velocitiesY[particleIndex] += collisionVelocitiesY[collisionIndex] * distanceForceConst * particleWeight;
                }
                if (velocitiesZ[particleIndex] < collisionVelocitiesZ[collisionIndex])
                {
                    velocitiesZ[particleIndex] += collisionVelocitiesZ[collisionIndex] * distanceForceConst * particleWeight;
                }
            }
        }
예제 #4
0
        public void Execute(ParticleSystemJobData jobData)
        {
            var partColors = jobData.startColors;
            var partPos    = jobData.positions;

            for (int i = 0; i < jobData.count; ++i)
            {
                Points[i] = new float3(partPos.x[i], partPos.y[i], partPos.z[i]);
            }

            // Set every particle to white first
            for (int i = 0; i < jobData.count; i++)
            {
                partColors[i] = new Color32(0, 0, 0, 255);
            }

            // Set all neighbours to result color
            for (int i = 0; i < KnnResults.Length; i++)
            {
                var results  = KnnResults[i];
                var setColor = Colors[i];

                for (int j = 0; j < results.Length; ++j)
                {
                    partColors[results[j]] = setColor;
                }
            }
        }
예제 #5
0
 public void Execute(ParticleSystemJobData particles)
 {
     if (hasInitialVelocity || hasMaximumVelocity)
     {
         var velocitiesX = particles.velocities.x;
         var velocitiesY = particles.velocities.y;
         var velocitiesZ = particles.velocities.z;
         for (int i = 0; i < particles.count; i++)
         {
             if (hasInitialVelocity && particles.aliveTimePercent[i] * totalLifeTime / 100f < ParticleMagic.MINLIFETIME)
             {
                 velocitiesX[i] = directionX * initialVelocity;
                 velocitiesY[i] = directionY * initialVelocity;
                 velocitiesZ[i] = directionZ * initialVelocity;
             }
             else if (shouldFollowTarget)
             {
                 float randomSeed = particles.randomSeeds[i] / (float)uint.MaxValue + .5f;
                 velocitiesX[i] += ((targetX - particles.positions.x[i]) * randomSeed - velocitiesX[i] * force / 1000f);
                 velocitiesY[i] += ((targetY - particles.positions.y[i]) * randomSeed - velocitiesY[i] * force / 1000f);
                 velocitiesZ[i] += ((targetZ - particles.positions.z[i]) * randomSeed - velocitiesZ[i] * force / 1000f);
             }
             Vector3 velocity = new Vector3(velocitiesX[i], velocitiesY[i], velocitiesZ[i]);
             if (hasMaximumVelocity && velocity.magnitude > maxVelocity)
             {
                 velocity       = velocity.normalized;
                 velocitiesX[i] = velocity.x * maxVelocity;
                 velocitiesY[i] = velocity.y * maxVelocity;
                 velocitiesZ[i] = velocity.z * maxVelocity;
             }
         }
     }
 }
예제 #6
0
        public void Execute(ParticleSystemJobData particles, int startIndex, int count)
        {
            m_RotationDifference = m_RotationDifference / 180 * math.PI;
            var rotations = particles.rotations.z;

            for (int i = startIndex; i < startIndex + count; i++)
            {
                rotations[i] += m_RotationDifference;
            }
        }
예제 #7
0
        public void Execute(ParticleSystemJobData particles)
        {
            var positionsX = particles.positions.x;
            var positionsY = particles.positions.y;
            var positionsZ = particles.positions.z;

            for (int i = 0; i < particles.count && i < particlePositionsX.Length; i++)
            {
                positionsX[i] = particlePositionsX[i] + offsetX;
                positionsY[i] = particlePositionsY[i] + offsetY;
                positionsZ[i] = particlePositionsZ[i] + offsetZ;
            }
        }
예제 #8
0
 public void Execute(ParticleSystemJobData particles)
 {
     if (immortalityOn)
     {
         var aliveTimePercent = particles.aliveTimePercent;
         for (int i = 0; i < particles.count; i++)
         {
             if (aliveTimePercent[i] / 100f * totalLifeTime > ParticleMagic.MINLIFETIME)
             {
                 aliveTimePercent[i] = ParticleMagic.MINLIFETIME / totalLifeTime * 100f + 1;
             }
         }
     }
 }
        void KillOtherParticle(ParticleSystemJobData particles, int particleIndex, int collisionIndex, int maxParticles, float percent)
        {
            float   particleWeight  = collisionPointsCount / maxParticles;
            Vector3 collisionPoint  = new Vector3(collisionPointsX[collisionIndex], collisionPointsY[collisionIndex], collisionPointsZ[collisionIndex]);
            Vector3 currentPosition = new Vector3(particles.positions.x[particleIndex], particles.positions.y[particleIndex], particles.positions.z[particleIndex]);
            float   distance        = Vector2.Distance(collisionPoint, currentPosition);

            if (distance < maxParticleCollisionEffectDistance)
            {
                var   aliveTimePercent   = particles.aliveTimePercent;
                float distanceDeathConst = percent * (1 - (distance / (maxParticleCollisionEffectDistance * particleWeight))) * deltaTime;
                aliveTimePercent[particleIndex] += percent * particleWeight;
            }
        }
        public void Execute(ParticleSystemJobData particles, int i)
        {
            // If the particle is a trigger Collisions
            if (isTrigger)
            {
                // If the particle is colliding with a trigger
                if (collideWithTrigger && particleTriggerColliders.ContainsKey(gameObjectID))
                {
                    Vector3 point   = new Vector3(particles.positions.x[i], particles.positions.y[i], particles.positions.z[i]);
                    int     hit     = 0;
                    Vector3 extends = particleTriggerColliders[gameObjectID].bounds.extents;
                    Vector3 center  = particleTriggerColliders[gameObjectID].bounds.center;
                    // IntRect bounds = particleTriggerColliders[gameObjectID].bounds;

                    // make sure the particle is within the bounds of the other trigger;
                    // Within left bounds ------------   Within right bounds
                    if (point.x > center.x - extends.x && point.x < center.x + extends.x
                        // Within bottom bounds ------------   Within top bounds
                        && point.y > center.y - extends.y && point.y < center.y + extends.y)
                    {
                        // Check to see if the particle is colliding with the trigger
                        for (int pathsIndex = 0; pathsIndex < particleTriggerColliders[gameObjectID].path.Count; pathsIndex++)
                        {
                            hit = Clipper.PointInPolygon(new IntPoint(point.x * clipperPrecision, point.y * clipperPrecision), particleTriggerColliders[gameObjectID].path[pathsIndex]);
                            if (hit != 0)
                            {
                                break;
                            }
                        }
                        // If we've collided with the trigger then, apply the relevant action
                        if (hit != 0)
                        {
                            //TODO: Add check for the amount one of particles we are colliding with
                            // If the particle is colliding with fire
                            if (particleTriggerColliders[gameObjectID].element == ElementType.Fire)
                            {
                                KillOtherParticle(particles, i, 100);
                                PushBackCollision(particles, i, 1);
                            }
                            // If the particle is colliding with Wind
                            else if (particleTriggerColliders[gameObjectID].element == ElementType.Wind)
                            {
                                PushBackCollision(particles, i, 1);
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
        public void Execute(ParticleSystemJobData particles, int startIndex, int count)
        {
            var positionsX = particles.positions.x;

            int endIndex = startIndex + count;

            for (int i = startIndex; i < endIndex; i++)
            {
                sortKeys[i] = new SortKey {
                    Key = positionsX[i], Index = i
                }
            }
            ;
        }
    }
예제 #12
0
        public void ProcessParticleSystem(ParticleSystemJobData jobData)
        {
            Color customColor = Color.white;

            var startColors = jobData.startColors;
            var customDatas = jobData.customData1;

            for (int idx = 0; idx < startColors.Length; idx++)
            {
                customColor.r    = customDatas.x[idx];
                customColor.g    = customDatas.y[idx];
                customColor.b    = customDatas.z[idx];
                customColor.a    = customDatas.w[idx];
                startColors[idx] = customColor;
            }
        }
예제 #13
0
        public void Execute(ParticleSystemJobData particles)
        {
            var positions  = particles.positions;
            var velocities = particles.velocities;

            int count = collisions.Count;

            for (int i = 0; i < count; i++)
            {
                var collision = collisions.Dequeue();

                positions[collision.Index]  += (Vector3)collision.DeltaPosition;
                velocities[collision.Index] += (Vector3)collision.DeltaVelocity;

                positions[collision.Index2]  += (Vector3)collision.DeltaPosition2;
                velocities[collision.Index2] += (Vector3)collision.DeltaVelocity2;
            }
        }
예제 #14
0
        public void ProcessParticleSystem(ParticleSystemJobData jobData)
        {
            var colors    = jobData.startColors;
            var positions = jobData.positions;

            for (int i = 0; i < jobData.count; ++i)
            {
                Points[i] = new float3(positions.x[i], positions.y[i], positions.z[i]);
            }

            for (int i = 0; i < jobData.count; i++)
            {
                colors[i] = new Color32(0, 0, 0, 255);
            }

            // Set all neighbours to red
            for (int i = 0; i < KnnResults.Length; i++)
            {
                colors[KnnResults[i]] = Colors[i / K];
            }
        }
        void PushBackCollision(ParticleSystemJobData particles, int particleIndex, float percent)
        {
            ParticleMagic pm       = particleTriggerColliders[gameObjectID].particleMagic;
            Vector3       velocity = pm.initialVelocity * pm.direction;

            var velocitiesX = particles.velocities.x;
            var velocitiesY = particles.velocities.y;
            var velocitiesZ = particles.velocities.z;

            // Set the x,y,and z velocities for the push back
            if (Mathf.Abs(velocitiesX[particleIndex]) < Mathf.Abs(velocity.x) || Mathf.Sign(velocitiesX[particleIndex]) != Mathf.Sign(velocity.x))
            {
                velocitiesX[particleIndex] += velocity.x * deltaTime * percent;
            }
            if (Mathf.Abs(velocitiesY[particleIndex]) < Mathf.Abs(velocity.y) || Mathf.Sign(velocitiesY[particleIndex]) != Mathf.Sign(velocity.y))
            {
                velocitiesY[particleIndex] += velocity.y * deltaTime * percent;
            }
            if (Mathf.Abs(velocitiesZ[particleIndex]) < Mathf.Abs(velocity.z) || Mathf.Sign(velocitiesZ[particleIndex]) != Mathf.Sign(velocity.z))
            {
                velocitiesZ[particleIndex] += velocity.z * deltaTime * percent;
            }
        }
예제 #16
0
 public void Execute(ParticleSystemJobData particles)
 {
     new NativeSlice <SortKey>(sortKeys, 0, particles.count).Sort();
 }
        void KillOtherParticle(ParticleSystemJobData particles, int particleIndex, float percent)
        {
            var aliveTimePercent = particles.aliveTimePercent;

            aliveTimePercent[particleIndex] += percent * deltaTime;
        }
예제 #18
0
        public void Execute(ParticleSystemJobData particles, int startIndex, int count)
        {
            if (areaArray.IsCreated && areaArray.Length > 0)
            {
                var positionsX = particles.positions.x;
                var positionsY = particles.positions.y;
                var positionsZ = particles.positions.z;

                // scaleX = scaleX != default( float ) ? scaleX : 1;
                // scaleY = scaleY != default( float ) ? scaleY : 1;
                // scaleZ = scaleZ != default( float ) ? scaleZ : 1;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    System.Random rand = new System.Random((int)particles.randomSeeds[i]);
                    if (particles.aliveTimePercent[i] * totalLifeTime / 100f < ParticleMagic.MINLIFETIME || shouldFollowStartPosition)
                    {
                        float randomSeed       = particles.randomSeeds[i] / (float)uint.MaxValue;
                        float targetArea       = totalArea * (float)rand.NextDouble();//randomSeed;
                        float currentAreaCount = 0;
                        int   triangleIndex    = 0;
                        for ( ; triangleIndex < areaArray.Length; triangleIndex++)
                        {
                            currentAreaCount += areaArray[triangleIndex];
                            if (currentAreaCount >= targetArea)
                            {
                                break;
                            }
                        }

                        // Get the triangle vertexes
                        Vector3 vertexA = new Vector3(verticesX[triangles[triangleIndex * 3]], verticesY[triangles[triangleIndex * 3]], verticesZ[triangles[triangleIndex * 3]]);
                        Vector3 vertexB = new Vector3(verticesX[triangles[triangleIndex * 3 + 1]], verticesY[triangles[triangleIndex * 3 + 1]], verticesZ[triangles[triangleIndex * 3 + 1]]);
                        Vector3 vertexC = new Vector3(verticesX[triangles[triangleIndex * 3 + 2]], verticesY[triangles[triangleIndex * 3 + 2]], verticesZ[triangles[triangleIndex * 3 + 2]]);

                        // Scale the triangle
                        Vector3 scale = new Vector3(scaleX, scaleY, scaleZ);
                        vertexA = Vector3.Scale(vertexA, scale);
                        vertexB = Vector3.Scale(vertexB, scale);
                        vertexC = Vector3.Scale(vertexC, scale);

                        // Rotate the triangle
                        Quaternion rotation = new Quaternion(quaterionX, quaterionY, quaterionZ, quaterionW);
                        vertexA = rotation * vertexA;
                        vertexB = rotation * vertexB;
                        vertexC = rotation * vertexC;

                        // Place the particle at a random point on the triangle
                        float randomSeed2     = (float)rand.NextDouble();
                        float startPositionsX = offsetX + (1 - Mathf.Sqrt(randomSeed)) * vertexA.x + (Mathf.Sqrt(randomSeed) * (1 - randomSeed2)) * vertexB.x + (Mathf.Sqrt(randomSeed) * randomSeed2) * vertexC.x;
                        float startPositionsY = offsetY + (1 - Mathf.Sqrt(randomSeed)) * vertexA.y + (Mathf.Sqrt(randomSeed) * (1 - randomSeed2)) * vertexB.y + (Mathf.Sqrt(randomSeed) * randomSeed2) * vertexC.y;
                        float startPositionsZ = offsetZ + (1 - Mathf.Sqrt(randomSeed)) * vertexA.z + (Mathf.Sqrt(randomSeed) * (1 - randomSeed2)) * vertexB.z + (Mathf.Sqrt(randomSeed) * randomSeed2) * vertexC.z;

                        if (particles.aliveTimePercent[i] * totalLifeTime / 100f < ParticleMagic.MINLIFETIME)
                        {
                            positionsX[i] = startPositionsX;
                            positionsY[i] = startPositionsY;
                            positionsZ[i] = startPositionsZ;
                        }

                        // Follow the start position of the shape
                        else if (shouldFollowStartPosition)
                        {
                            if (maxDistanceTillTp != default(float) && (new Vector3((startPositionsX - positionsX[i]), (startPositionsY - positionsY[i]), (startPositionsZ - positionsZ[i]))).magnitude > maxDistanceTillTp)
                            {
                                positionsX[i] = startPositionsX;
                                positionsY[i] = startPositionsY;
                                positionsZ[i] = startPositionsZ;
                            }
                            else
                            {
                                var velocitiesX = particles.velocities.x;
                                var velocitiesY = particles.velocities.y;
                                var velocitiesZ = particles.velocities.z;
                                velocitiesX[i] = (startPositionsX - positionsX[i]) * followSpeed * 10;
                                velocitiesY[i] = (startPositionsY - positionsY[i]) * followSpeed * 10;
                                velocitiesZ[i] = (startPositionsZ - positionsZ[i]) * followSpeed * 10;
                            }
                        }
                    }
                }
            }
            // areaArray.Dispose();
        }
예제 #19
0
        public void Execute(ParticleSystemJobData particles, int startIndex, int count)
        {
            var positions  = particles.positions;
            var velocities = particles.velocities;
            var sizes      = particles.sizes.x;

            int endIndex = startIndex + count;

            for (int i = startIndex; i < endIndex; i++)
            {
                int    particleIndex    = sortKeys[i].Index;
                float3 particlePosition = positions[particleIndex];
                float3 particleVelocity = velocities[particleIndex];
                float  particleSize     = sizes[particleIndex] * 0.5f * radiusScale;
                float  particleMass     = (4.0f / 3.0f) * math.PI * particleSize * particleSize * particleSize;

                int i2 = i + 1;
                while (i2 < particles.count)
                {
                    int    particleIndex2    = sortKeys[i2++].Index;
                    float3 particlePosition2 = positions[particleIndex2];
                    float  particleSize2     = sizes[particleIndex2] * 0.5f * radiusScale;
                    float  particleSizeSum   = particleSize + particleSize2;

                    if (math.distancesq(particlePosition, particlePosition2) < particleSizeSum * particleSizeSum)
                    {
                        float3 particleVelocity2 = velocities[particleIndex2];
                        float  particleMass2     = (4.0f / 3.0f) * math.PI * particleSize2 * particleSize2 * particleSize2;

                        // get the mtd
                        float3 delta = particlePosition - particlePosition2;
                        float  d     = math.length(delta);

                        // minimum translation distance to push particles apart after intersecting
                        float3 mtd = delta * ((particleSizeSum - d) / d);

                        // resolve intersection
                        // inverse mass quantities
                        float im1 = 1.0f / particleMass;
                        float im2 = 1.0f / particleMass2;

                        // push-pull them apart based off their mass
                        float3 deltaPosition  = mtd * (im1 / (im1 + im2));
                        float3 deltaPosition2 = -mtd * (im2 / (im1 + im2));
                        particlePosition += deltaPosition; // apply to cached variable too, to increase stability

                        // impact speed
                        float3 v  = (particleVelocity - particleVelocity2);
                        float  vn = math.dot(v, math.normalize(mtd));

                        // spheres intersecting but moving away from each other already
                        if (vn > 0.0f)
                        {
                            continue;
                        }

                        // collision impulse
                        float  imp     = (-(1.0f + bounce) * vn) / (im1 + im2);
                        float3 impulse = math.normalize(mtd) * imp;

                        // change in momentum
                        float3 deltaVelocity  = impulse * im1;
                        float3 deltaVelocity2 = -impulse * im2;

                        // enqueue collision response
                        collisions.Enqueue(new Collision
                        {
                            Index         = particleIndex,
                            DeltaPosition = deltaPosition,
                            DeltaVelocity = deltaVelocity,

                            Index2         = particleIndex2,
                            DeltaPosition2 = deltaPosition2,
                            DeltaVelocity2 = deltaVelocity2
                        });
                    }
                    else if (particlePosition2.x - particlePosition.x > maxDiameter)
                    {
                        break;
                    }
                }
            }
        }