PhysicsObjectId WorldTestUnitAi :: getCollisionForObject (const PhysicsObject& object) const { double radius = object.getRadius(); // check for collision with moon if(object.getPosition().isNormLessThan(MOON_RADIUS + radius)) return ID_MOON; // check for collision with target if(object.getId() != ID_TARGET && m_target_disappear_time <= 0.0 && object.getPosition().isDistanceLessThan(m_target.getPosition(), m_target.getRadius() + radius)) { return ID_TARGET; } // don't check against agent // don't check against bullets // check for collision with ring particles for(unsigned int i = 0; i < m_ring_particle_count; i++) { assert(i < RING_PARTICLE_COUNT_MAX); const RingParticleData& rp = ma_ring_particles[i]; if(object.getPosition().isDistanceLessThan(rp.m_position, rp.m_radius + radius)) return PhysicsObjectId(TYPE_RING_PARTICLE, PhysicsObjectId::FLEET_NATURE, i); } // no collisions return PhysicsObjectId::ID_NOTHING; }
void PhysicsSimulator::respondToCollisions(std::vector<PhysicsCollisionTuple> collisions, float delta) { for (size_t i = 0; i < collisions.size(); i++) { PhysicsObject *first = std::get<0>(collisions[i]); PhysicsCollider *firstCollider = std::get<1>(collisions[i]); PhysicsObject *second = std::get<2>(collisions[i]); PhysicsCollider *secondCollider = std::get<3>(collisions[i]); //PhysicsCollisionData data = std::get<4>(collisions[i]); // Perfectly Elastic Collision if (first->getElasticity() == 1 && second->getElasticity() == 1) { bool reflection = false; if (firstCollider->getType() == PhysicsColliderTypePlane && ((PhysicsColliderPlane *)firstCollider)->getReflective() == true) { reflection = true; glm::vec3 normal = ((PhysicsColliderPlane *)firstCollider)->getNormal(); float magnitude = glm::length(second->getVelocity()); glm::vec3 initial = second->getVelocity(); glm::vec3 newVelocity = initial - (2.0f * normal * glm::dot(initial, normal)); second->setVelocity(glm::normalize(newVelocity) * magnitude); } if (secondCollider->getType() == PhysicsColliderTypePlane && ((PhysicsColliderPlane *)secondCollider)->getReflective() == true) { reflection = true; glm::vec3 normal = ((PhysicsColliderPlane *)secondCollider)->getNormal(); float magnitude = glm::length(first->getVelocity()); glm::vec3 initial = first->getVelocity(); glm::vec3 newVelocity = initial - (2.0f * normal * glm::dot(initial, normal)); first->setVelocity(glm::normalize(newVelocity) * magnitude); } if (reflection == false) { float m1 = first->getMass(); float m2 = second->getMass(); // This is the collision normal (line of collision) and the normal of the tangent plane glm::vec3 normal = glm::normalize(second->getPosition() - first->getPosition()); // Get scalar projections onto the normal double _v1ns = glm::dot(first->getVelocity(), normal); double _v2ns = glm::dot(second->getVelocity(), normal); double v1ns = ((1 * m2 * (_v2ns - _v1ns)) / (m1 + m2)) + ((m1 * _v1ns) / (m1 + m2)) + ((m2 * _v2ns) / (m1 + m2)); double v2ns = ((1 * m1 * (_v1ns - _v2ns)) / (m1 + m2)) + ((m2 * _v2ns) / (m1 + m2)) + ((m1 * _v1ns) / (m1 + m2)); glm::vec3 v1n = float(v1ns) * normal; glm::vec3 v2n = float(v2ns) * normal; glm::vec3 v1t = first->getVelocity() - (glm::dot(first->getVelocity(), normal) * normal); glm::vec3 v2t = second->getVelocity() - (glm::dot(second->getVelocity(), normal) * normal); glm::vec3 v1 = v1n + v1t; glm::vec3 v2 = v2n + v2t; first->setVelocity(v1); second->setVelocity(v2); } } } }
bool Particles::isCollide(PhysicsObject &object) const{ Vector3 position = object.getPosition(); SectorID id(position); int x = id.getI(); int y = id.getJ(); int z = id.getK(); int searchSection = 1; for (int i = x - searchSection; i <= x + searchSection; i++){ for (int j = y - searchSection; j <= y + searchSection; j++){ for (int k = z - searchSection; k <= z + searchSection; k++){ int density = SectorID::calculateDensity(i, j, k); Sector sector(i, j, k, density); if (sector.isCollide(object)) { return true; } } } } return false; }