private void OnCollision(Geom geom1, Geom geom2) { if (!geom1.body.Enabled || !geom2.body.Enabled) { return; } if ((geom1.collisionGroup == geom2.collisionGroup) && geom1.collisionGroup != 0 && geom2.collisionGroup != 0) { return; } if (!geom1.collisionEnabled || !geom2.collisionEnabled) { return; } if (geom1.body.isStatic && geom2.body.isStatic) { return; } if (geom1.body == geom2.body) { return; } if (((geom1.collisionCategories & geom2.collidesWith) == CollisionCategory.None) & ((geom2.collisionCategories & geom1.collidesWith) == CollisionCategory.None)) { return; } Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch(); arbiter.ConstructArbiter(geom1, geom2, _physicsSimulator); //TODO: Since we insert all arbiters that is already in the arbiterList into the pool //should we not restrict the size of the pool to a fixed number? A large simulation //that runs for some time might accumulate A LOT of arbiters in the pool. if (!_physicsSimulator.arbiterList.Contains(arbiter)) { _physicsSimulator.arbiterList.Add(arbiter); } else { _physicsSimulator.arbiterPool.Insert(arbiter); } }
private void OnCollision(Geom geom1, Geom geom2) { if (!geom1.body.enabled || !geom2.body.enabled) { return; } if ((geom1.collisionGroup == geom2.collisionGroup) && geom1.collisionGroup != 0 && geom2.collisionGroup != 0) { return; } if (!geom1.collisionEnabled || !geom2.collisionEnabled) { return; } if (geom1.body.isStatic && geom2.body.isStatic) { //don't collide two static bodies return; } if (((geom1.collisionCategories & geom2.collidesWith) == CollisionCategories.None) & ((geom2.collisionCategories & geom1.collidesWith) == CollisionCategories.None)) { return; } Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch(); arbiter.ConstructArbiter(geom1, geom2, _physicsSimulator); if (!_physicsSimulator.arbiterList.Contains(arbiter)) { _physicsSimulator.arbiterList.Add(arbiter); } else { _physicsSimulator.arbiterPool.Release(arbiter); } }
/// <summary> /// Iterates over the collision pairs and creates arbiters. /// </summary> private void HandleCollisions() { foreach (CollisionPair cp in collisionPairs.Keys) { // Note: Possible optimization. Maybe arbiter can be cached into value of // collisionPairs? Currently, the collisionPairs hash doesn't use its // value parameter - its just an unused bool value. Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch(); arbiter.ConstructArbiter(cp.geom1, cp.geom2, _physicsSimulator); if (!_physicsSimulator.arbiterList.Contains(arbiter)) { _physicsSimulator.arbiterList.Add(arbiter); } else { _physicsSimulator.arbiterPool.Release(arbiter); } } }
private void DoCollision() { //Iterate all the geoms and check against the next for (int i = 0; i < _physicsSimulator.geomList.Count - 1; i++) { for (int j = i + 1; j < _physicsSimulator.geomList.Count; j++) { _geometryA = _physicsSimulator.geomList[i]; _geometryB = _physicsSimulator.geomList[j]; if (!_geometryA.body.Enabled || !_geometryB.body.Enabled) { continue; } if ((_geometryA.collisionGroup == _geometryB.collisionGroup) && _geometryA.collisionGroup != 0 && _geometryB.collisionGroup != 0) { continue; } if (!_geometryA.collisionEnabled || !_geometryB.collisionEnabled) { continue; } if (_geometryA.body.isStatic && _geometryB.body.isStatic) { continue; } if (_geometryA.body == _geometryB.body) { continue; } if (((_geometryA.CollisionCategories & _geometryB.CollidesWith) == CollisionCategory.None) & ((_geometryB.CollisionCategories & _geometryA.CollidesWith) == CollisionCategory.None)) { continue; } //Assume intersection bool intersection = true; #region INLINE: if (AABB.Intersect(_geometryA.aabb, _geometryB.aabb)) .... //Check if there is no intersection if (_geometryA.AABB.min.X > _geometryB.AABB.max.X || _geometryB.AABB.min.X > _geometryA.AABB.max.X) { intersection = false; } else if (_geometryA.AABB.min.Y > _geometryB.AABB.Max.Y || _geometryB.AABB.min.Y > _geometryA.AABB.Max.Y) { intersection = false; } #endregion //Call the OnBroadPhaseCollision event first. If the user aborts the collision //it will not create an arbiter if (OnBroadPhaseCollision != null) { intersection = OnBroadPhaseCollision(_geometryA, _geometryB); } //If the user aborted the intersection, continue to the next geometry. if (!intersection) { continue; } //Note: Commented this out and copy-paste into from other colliders //_arbiter = _physicsSimulator.arbiterPool.Fetch(); //_arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator); //if (_physicsSimulator.arbiterList.Contains(_arbiter)) //{ // _physicsSimulator.arbiterPool.Insert(_arbiter); //} //else //{ // _physicsSimulator.arbiterList.Add(_arbiter); //} Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch(); arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator); if (!_physicsSimulator.arbiterList.Contains(arbiter)) { _physicsSimulator.arbiterList.Add(arbiter); } else { _physicsSimulator.arbiterPool.Insert(arbiter); } } } }
/// <summary> /// Updates this instance. /// </summary> public void Update() { //Iterate all the geoms and check against the next for (int i = 0; i < _physicsSimulator.GeomList.Count - 1; i++) { for (int j = i + 1; j < _physicsSimulator.GeomList.Count; j++) { _geometryA = _physicsSimulator.GeomList[i]; _geometryB = _physicsSimulator.GeomList[j]; if (!_geometryA.body.Enabled || !_geometryB.body.Enabled) { continue; } if ((_geometryA.CollisionGroup == _geometryB.CollisionGroup) && _geometryA.CollisionGroup != 0 && _geometryB.CollisionGroup != 0) { continue; } if (!_geometryA.CollisionEnabled || !_geometryB.CollisionEnabled) { continue; } if (_geometryA.body.isStatic && _geometryB.body.isStatic) { continue; } if (_geometryA.body == _geometryB.body) { continue; } if (((_geometryA.CollisionCategories & _geometryB.CollidesWith) == CollisionCategory.None) & ((_geometryB.CollisionCategories & _geometryA.CollidesWith) == CollisionCategory.None)) { continue; } if (_geometryA.IsGeometryIgnored(_geometryB) || _geometryB.IsGeometryIgnored(_geometryA)) { continue; } //Assume intersection bool intersection = true; //Check if there is no intersection if (_geometryA.AABB.min.X > _geometryB.AABB.max.X || _geometryB.AABB.min.X > _geometryA.AABB.max.X) { intersection = false; } else if (_geometryA.AABB.min.Y > _geometryB.AABB.Max.Y || _geometryB.AABB.min.Y > _geometryA.AABB.Max.Y) { intersection = false; } //Call the OnBroadPhaseCollision event first. If the user aborts the collision //it will not create an arbiter if (OnBroadPhaseCollision != null) { intersection = OnBroadPhaseCollision(_geometryA, _geometryB); } //If the user aborted the intersection, continue to the next geometry. if (!intersection) { continue; } Arbiter arbiter = _physicsSimulator.arbiterPool.Fetch(); arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator); if (!_physicsSimulator.ArbiterList.Contains(arbiter)) { _physicsSimulator.ArbiterList.Add(arbiter); } else { _physicsSimulator.arbiterPool.Insert(arbiter); } } } }
private void DoCollision() { for (int i = 0; i < _physicsSimulator.geomList.Count - 1; i++) { for (int j = i + 1; j < _physicsSimulator.geomList.Count; j++) { _geometryA = _physicsSimulator.geomList[i]; _geometryB = _physicsSimulator.geomList[j]; //possible early exits if (!_geometryA.Body.enabled || !_geometryB.Body.enabled) { continue; } if ((_geometryA.CollisionGroup == _geometryB.CollisionGroup) && _geometryA.CollisionGroup != 0 && _geometryB.CollisionGroup != 0) { continue; } if (!_geometryA.CollisionEnabled || !_geometryB.CollisionEnabled) { continue; } if (_geometryA.Body.isStatic && _geometryB.Body.isStatic) { //don't collide two static bodies continue; } if (_geometryA.Body == _geometryB.Body) { //don't collide two geometries connected to the same body continue; } if (((_geometryA.CollisionCategories & _geometryB.CollidesWith) == CollisionCategories.None) & ((_geometryB.CollisionCategories & _geometryA.CollidesWith) == CollisionCategories.None)) { continue; } bool intersection = true; #region INLINE: if (AABB.Intersect(_geometryA.aabb, _geometryB.aabb)) .... if (_geometryA.AABB.min.X > _geometryB.AABB.max.X || _geometryB.AABB.min.X > _geometryA.AABB.max.X) { intersection = false; } else if (_geometryA.AABB.min.Y > _geometryB.AABB.Max.Y || _geometryB.AABB.min.Y > _geometryA.AABB.Max.Y) { intersection = false; } #endregion if (intersection) { _arbiter = _physicsSimulator.arbiterPool.Fetch(); _arbiter.ConstructArbiter(_geometryA, _geometryB, _physicsSimulator); if (!_physicsSimulator.arbiterList.Contains(_arbiter)) { _physicsSimulator.arbiterList.Add(_arbiter); } else { _physicsSimulator.arbiterPool.Release(_arbiter); } } } } }