public void TestResolveContacts()
        {
            var resolver = new ParticleContactResolver(100);

            var p = new List <Particle>
            {
                new Particle
                {
                    Position = new Vector2D(0, 0),
                    Velocity = new Vector2D(1, 0),
                    Mass     = 1
                },
                new Particle
                {
                    Position = new Vector2D(2, 0),
                    Velocity = new Vector2D(0, 0),
                    Mass     = 1
                }
            };
            var contact = new ParticleContact(p[0], p[1], 1, 1, new Vector2D(-1, 0));

            var contactList = new List <ParticleContact>();

            resolver.ResolveContacts(contactList, 1 / 60.0);

            contactList.Add(contact);
            resolver.ResolveContacts(contactList, 1 / 60.0);
            Assert.AreEqual(new Vector2D(-1, 0), p[0].Position, "物体0依据速度分量分离");
            Assert.AreEqual(new Vector2D(0, 0), p[0].Velocity, "物体0碰撞后速度相反");
            Assert.AreEqual(new Vector2D(1, 0), p[1].Velocity, "物体1碰撞后速度相反");

            p = new List <Particle>
            {
                new Particle
                {
                    Position = new Vector2D(0, 0),
                    Velocity = new Vector2D(1, 0),
                    Mass     = 1
                },
                new Particle
                {
                    Position = new Vector2D(2, 0),
                    Velocity = new Vector2D(0, 0),
                    Mass     = 1
                }
            };
            contactList = new List <ParticleContact>
            {
                new ParticleContact(p[1], p[0], 1, 1, new Vector2D(1, 0))
            };
            resolver.ResolveContacts(contactList, 1 / 60.0);
            Assert.AreEqual(new Vector2D(-1, 0), p[0].Position, "函数满足对称性");
            Assert.AreEqual(new Vector2D(0, 0), p[0].Velocity, "函数满足对称性");
            Assert.AreEqual(new Vector2D(1, 0), p[1].Velocity, "函数满足对称性");
        }
        public void TestResovleMultiContacts()
        {
            var resolver = new ParticleContactResolver(100);
            var p        = new List <Particle>
            {
                new Particle
                {
                    Position = new Vector2D(0, 0),
                    Velocity = new Vector2D(0, 0),
                    Mass     = 1
                },
                new Particle
                {
                    Position = new Vector2D(2, 0),
                    Velocity = new Vector2D(0, 0),
                    Mass     = 1
                },
                new Particle
                {
                    Position = new Vector2D(4, 0),
                    Velocity = new Vector2D(0, 0),
                    Mass     = 1
                }
            };
            var contactList = new List <ParticleContact>
            {
                new ParticleContact(p[0], p[1], 1, 1, new Vector2D(-1, 0)),
                new ParticleContact(p[2], p[1], 1, 1, new Vector2D(1, 0))
            };

            resolver.ResolveContacts(contactList, 1 / 60.0);
            Assert.AreEqual(new Vector2D(-1, 0), p[0].Position, "物体0向左分离");
            Assert.AreEqual(new Vector2D(2, 0), p[1].Position, "物体1位置不变");
            Assert.AreEqual(new Vector2D(5, 0), p[2].Position, "物体2向右分离");
        }
Пример #3
0
        /// <summary>
        /// Processes all the physics for the particle world.
        /// </summary>
        /// <param name="dt"></param>
        public void RunPhysics(double dt)
        {
            // First apply the forces
            ApplyForces(dt);

            // Then integrate the objects
            Integrate(dt);

            // Generate contacts
            int usedContacts = GenerateContacts();

            // And process them
            if (usedContacts > 0)
            {
                Resolver.ResolveContacts(m_contacts, usedContacts, dt);
            }
        }
Пример #4
0
        /// <summary>
        /// 进行碰撞检测并解决碰撞
        /// </summary>
        /// <param name="duration"></param>
        public void ResolveContacts(double duration)
        {
            _contactCounter = 0;

            // 产生碰撞表
            for (int i = 0; i < Settings.ContactIteration; i++)
            {
                _contactList.Clear();

                List <Shape> shapes = CollectAllShapes(_objects, _edges);

                // 执行质体碰撞检测器
                foreach (var contact in ExcuteParticleCollisionDetector(shapes))
                {
                    AddToContactList(contact);
                }

                // 执行碰撞发生器
                foreach (var contactGenerator in _generators)
                {
                    foreach (var contact in contactGenerator)
                    {
                        if (!AddToContactList(contact))
                        {
                            goto CONTACT_RESOLVE;
                        }
                    }
                }

                // 当不再产生新的碰撞时退出
                if (_contactList.Count == 0)
                {
                    break;
                }

CONTACT_RESOLVE:
                // 解决质体碰撞
                OnContact(new ContactEventArgs(_contactList));
                _particleContactResolver.Iterations = _contactList.Count * 2;
                _particleContactResolver.ResolveContacts(_contactList, duration);
            }
        }
Пример #5
0
    private void FixedUpdate()
    {
        if (!simulating)
        {
            return;
        }

        // Integrate particles.
        Integrate(Time.fixedDeltaTime);

        // Generate contacts.
        if (GenerateContacts() > 0)
        {
            // Go with a dynamic iteration count instead of fixed.
            if (calculateIterations)
            {
                resolver.iterations = contacts.Count * 2;
            }

            resolver.ResolveContacts(contacts, Time.fixedDeltaTime);
        }
    }
Пример #6
0
        /// <summary>
        /// Processes all the physics for the particle world.
        /// </summary>
        /// <param name="duration">Secondi</param>
        public void RunPhysics(float duration)
        {
            //Applica tutti i force generator
            forceRegistry.Update(duration);

            //Integra le forze per aggiornarne la posizione
            Integrate(duration);

            //Genera i contacts tra le particles
            uint usedContacts = GenerateContacts();

            //Processa i contacts
            //if (calculateIterations) resolver.SetIterations(usedContacts * 2);
            if (usedContacts > 0)
            {
                resolver.ResolveContacts(contacts, usedContacts, duration);
            }

            // Svuota gli accumularori di forze all'interno delle particelle
            //for (int i = 0; i < Particles.Count; i++)
            //    Particles[i].ClearAccumulator();
        }