Esempio n. 1
0
        private void UpdateThread(object numThread)
        {
            float lifetime;
            Vector2 position;
            Vector2 velocity;
            float rotation;
            Rectangle rect;
            byte alpha;
            float floatAlpha;

            int numthread = (int)numThread;
            int particleperthread = (int)((float)numParticles / numThreads)+1;
            int startparticle = particleperthread * numthread;
            int endparticle = (int)MathHelper.Clamp( startparticle + particleperthread,0,positions.GetLength(0));
            DateTime last= DateTime.Now;
            DateTime start;
            Vector2 grav;

            while (running)
            {
                if (newframe[numthread] == true)
                {
            #if DEBUG
                    start = DateTime.Now;
            #endif
                    Vector2 newpos;
                    //(float)gametime.ElapsedGameTime.TotalSeconds;
                    float elapsed = (float)gametime.ElapsedGameTime.TotalSeconds;
                    //float elapsed = 0.003f;
                    //int length = particles.GetLength(0);
                    for (int i = startparticle; i < endparticle; i++)
                    {
                        // Save Particle information into a single Variable to avoid Array Bounds checks.
                        lifetime = lifetimes[i];
                        velocity = velocities[i];
                        position = positions[i];
                        rotation = Rotations[i];
                        rect = rects[i];
                        alpha = alphas[i];
                        floatAlpha = floatalphas[i];

                        #region SingleParticleUpdateLogic

                        lifetime += elapsed;
                        if (lifetime < totallifetime)
                        {
                            if (gravtype == GravityType.OverallForce)
                            {
                                grav = gravity;
                            }
                            else if (gravtype == GravityType.Newton)
                            {
                                grav = new Vector2();
                                if (fixedMasses)
                                {
                                    foreach (NewtonMass mass in masses)
                                    {
                                        grav += (mass.center - position) * (mass.weight * particleMass / (mass.center - position).LengthSquared());

                                    }
                                }
                                else
                                {
                                    for (int massIndex = 0; massIndex < masses.Count; massIndex++)
                                    {
                                        Vector2 Tempgrav = (masses[massIndex].center - position) * (masses[massIndex].weight * particleMass / (masses[massIndex].center - position).LengthSquared());
                                        grav += Tempgrav / particleMass;
                                        masses[massIndex] = new NewtonMass() { center = masses[massIndex].center, velocity = masses[massIndex].velocity - Tempgrav / masses[massIndex].weight * elapsed * elapsed, weight = masses[massIndex].weight };
                                    }
                                }
                                //grav /= 2;
                            }
                            else
                            {
                                grav = (gravity - position) * (1000 / (gravity - position).Length());
                            }
                            velocity += grav * elapsed;
                            velocity *= airFriction;
                            newpos = position + velocity * elapsed;
                            if (collisiontype == CollisionType.Collision)
                            {
                                #region ObjectCollision
                                foreach (Rectangle colliderect in collisionrectangles)
                                {
                                    //RightCollision
                                    if (position.X + size <= colliderect.X && newpos.X + size >= colliderect.X)
                                    {
                                        if (newpos.Y + size >= colliderect.Y && newpos.Y <= colliderect.Y + size)
                                        {
                                            velocity.X /= -1;//+ (float)(rand.NextDouble() / 10);
                                            velocity /= friction;
                                            newpos = position + velocity * elapsed;
                                            continue;
                                        }
                                    }

                                    //LeftCollision
                                    else if (position.X > colliderect.Right && newpos.X <= colliderect.Right)
                                    {
                                        if (newpos.Y + size >= colliderect.Y && newpos.Y <= colliderect.Y + size)
                                        {
                                            velocity.X /= -2;//+ (float)(rand.NextDouble() / 10);
                                            velocity /= friction;
                                            newpos = position + velocity * elapsed;
                                            continue;

                                        }
                                    }

                                    //BottomCollision
                                    else if (position.Y + size <= colliderect.Y && newpos.Y + size >= colliderect.Y)
                                    {
                                        if (position.X + size >= colliderect.X && position.X <= colliderect.Right)
                                        {
                                            velocity.Y /= -1;//+ (float)(rand.NextDouble() / 10);
                                            velocity /= friction;
                                            newpos = position + velocity * elapsed;
                                            continue;
                                        }
                                    }
                                    //UpCollision
                                    else if (position.Y >= colliderect.Y + size && newpos.Y <= colliderect.Y + size)
                                    {
                                        if (newpos.X + size >= colliderect.X && newpos.X <= colliderect.Right)
                                        {
                                            velocity.Y /= -1;//+ (float)(rand.NextDouble() / 10);
                                            velocity /= friction;
                                            newpos = position + velocity * elapsed;
                                            continue;
                                        }
                                    }

                                }
                                #endregion
                            }

                            if (BetweenParticleCollision)
                            {
                                for (int betweenParticlesIndex = 0; betweenParticlesIndex < positions.Length; betweenParticlesIndex++)
                                {
                                    Vector2 tempVel;
                                    if (lifetimes[betweenParticlesIndex]<totallifetime)
                                    {
                                        if (position.X + size <= positions[betweenParticlesIndex].X && newpos.X + size >= positions[betweenParticlesIndex].X)
                                        {
                                            if (newpos.Y + size >= positions[betweenParticlesIndex].Y && newpos.Y <= positions[betweenParticlesIndex].Y + size)
                                            {
                                                //velocity.X /= -1;//+ (float)(rand.NextDouble() / 10);
                                                tempVel = velocity;
                                                velocity = velocities[betweenParticlesIndex];
                                                velocities[betweenParticlesIndex] = tempVel;
                                                velocity /= friction;
                                                continue;
                                            }
                                        }

                                                                    //LeftCollision
                                        else if (position.X > positions[betweenParticlesIndex].X + size && newpos.X <= positions[betweenParticlesIndex].X + size)
                                        {
                                            if (newpos.Y + size >= positions[betweenParticlesIndex].Y && newpos.Y <= positions[betweenParticlesIndex].Y + size)
                                            {
                                                tempVel = velocity;
                                                velocity = velocities[betweenParticlesIndex];
                                                velocities[betweenParticlesIndex] = tempVel;
                                                velocity /= friction;
                                                continue;

                                            }
                                        }

                                        //BottomCollision
                                        else if (position.Y + size <= positions[betweenParticlesIndex].Y && newpos.Y + size >= positions[betweenParticlesIndex].Y)
                                        {
                                            if (position.X + size >= positions[betweenParticlesIndex].X && position.X <= positions[betweenParticlesIndex].X + size)
                                            {
                                                tempVel = velocity;
                                                velocity = velocities[betweenParticlesIndex];
                                                velocities[betweenParticlesIndex] = tempVel;
                                                velocity /= friction;
                                                continue;
                                            }
                                        }
                                        //UpCollision
                                        else if (position.Y >= positions[betweenParticlesIndex].Y + size && newpos.Y <= positions[betweenParticlesIndex].Y + size)
                                        {
                                            if (newpos.X + size >= positions[betweenParticlesIndex].X && newpos.X <= positions[betweenParticlesIndex].X + size)
                                            {
                                                tempVel = velocity;
                                                velocity = velocities[betweenParticlesIndex];
                                                velocities[betweenParticlesIndex] = tempVel;
                                                velocity /= friction;
                                                continue;
                                            }
                                        }
                                    }
                                }
                            }

                            Vector2 newVelocity = velocity * elapsed;
                            position += newVelocity;
                            rect.X = (int)position.X + size / 2;
                            rect.Y = (int)position.Y + size / 2;
                            if ((newVelocity).LengthSquared() > 1)
                            {
                                rotation = (float)Math.Acos(velocity.X / (velocity.Length()));
                                if (velocity.Y < 0)
                                    rotation *= -1;
                            }
                            alpha = (byte)(255 - (255 * (lifetime / totallifetime)));
                            floatAlpha = lifetime / totallifetime;

                        }
                        else if (Interlocked.Read(ref newSpawnCount) >= 0)
                        {
                            Interlocked.Decrement(ref newSpawnCount);
                            ResetParticle(i);
                            lifetime = lifetimes[i];
                            velocity = velocities[i];
                            position = positions[i];
                            rotation = Rotations[i];
                            rect = rects[i];
                            alpha = alphas[i];
                            floatAlpha = floatalphas[i];
                        }
                        #endregion

                        lifetimes[i] = lifetime;
                        velocities[i] = velocity;
                        positions[i] = position;
                        Rotations[i] = rotation;
                        rects[i] = rect;
                        alphas[i] = alpha;
                        floatalphas[i] = floatAlpha;
                    }
            #if DEBUG
                    duration[numthread] = DateTime.Now - start;
                    last = start;
            #endif
                    newframe[numthread] = false;
                }
                resetEvents[numthread].Set(); //Tell that this thread is ready
                barrier.SignalAndWait(); //Wait for Barrier to go on.

            }
        }
Esempio n. 2
0
        public void Update(GameTime gameTime)
        {
            if (initialized && enabled)
            {
                if (!fixedMasses)
                {
                    for (int i = 0; i < masses.Count; i++)
                    {
                        masses[i] = new NewtonMass() { center = masses[i].center + (masses[i].velocity), velocity = masses[i].velocity, weight = masses[i].weight };

                    }
                }

                gametime = gameTime;

                if (spawntype == SpawnType.Fontaine)
                {
                    newSpawners -= newSpawners - newSpawnCount;
                    newSpawners += (spawnperS * (float)gametime.ElapsedGameTime.TotalSeconds);
                    newSpawnCount = (long)newSpawners;
                }

                if (!useCuda)
                {
                    for (int i = 0; i < numThreads; i++)
                    {
                        if (updatethread[i].ThreadState == ThreadState.Unstarted)
                            updatethread[i].Start(i);
                        newframe[i] = true;
                    }
                }
                else
                {
                    DateTime start = DateTime.Now;
                    ParticleOptions options = CreateOptions((float)gametime.ElapsedGameTime.TotalSeconds);
                    particleCuda.Run(CreateHolder(),options);
                    duration[0] = DateTime.Now - start;
                }
            }
        }