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向右分离"); }
/// <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); } }
/// <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); } }
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); } }
/// <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(); }