Esempio n. 1
0
bool cloth::NarrowPhaseCheck(Face &body1, Face &body2)
{
	//demoResult.clear();
	//std::vector<Simplex> simplex;

	glm::vec3 direction = body1.particleA->getPos() - body2.particleA->getPos();

	simplex.push_back(support(direction, body1, body2));

	direction = -simplex[0].minkowskiDifference;
	int counter = 100;

	while (counter > 0)
	{
		Simplex tempSimplex;
		tempSimplex = support(direction, body1, body2);

		// Last point added was not past the origin in this direction
		if(glm::dot(tempSimplex.minkowskiDifference, direction) < 0)
		{
			return false;
		}
		simplex.push_back(tempSimplex);

		//check intersect
		if (processSimplex(simplex, direction))
		{
			return true;
		}
		counter--;
	}
}
PhysicsCollisionData PhysicsColliderSphere::collideWith(PhysicsCollider *other) {
    if (other->getType() == PhysicsColliderTypeSphere) {
        PhysicsColliderSphere *_other = static_cast<PhysicsColliderSphere *>(other);
        float centerDistance = glm::length(this->getPosition() - _other->getPosition());
        float radiusSum = this->getRadius() + _other->getRadius();
        
        glm::vec3 normal = glm::normalize(this->getPosition() - _other->getPosition());
        
        if (radiusSum < centerDistance)
            return PhysicsCollisionData(false, 0);
        else {
            return PhysicsCollisionData(normal, true, centerDistance - radiusSum);
        }
    } else if (other->getType() == PhysicsColliderTypeAABB) {
        PhysicsColliderAABB *_other = static_cast<PhysicsColliderAABB *>(other);
        
        glm::vec3 separatingAxis = this->getPosition() - _other->getPosition();
        float distance = glm::length(separatingAxis);
        
        separatingAxis = glm::normalize(separatingAxis);
        
        if (separatingAxis.x >= separatingAxis.y && separatingAxis.x >= separatingAxis.z)
            separatingAxis /= separatingAxis.x;
        else if (separatingAxis.y >= separatingAxis.x && separatingAxis.y >= separatingAxis.z)
            separatingAxis /= separatingAxis.y;
        else
            separatingAxis /= separatingAxis.z;
        
        separatingAxis.x *= _other->getWidth() / 2.0f;
        separatingAxis.y *= _other->getHeight() / 2.0f;
        separatingAxis.z *= _other->getDepth() / 2.0f;
        
        if (distance <= (this->getRadius() + glm::length(separatingAxis)))
            return PhysicsCollisionData(true, distance);
        else
            return PhysicsCollisionData(false, distance);
    } else if (other->getType() == PhysicsColliderTypePlane) {
        PhysicsColliderPlane *_other = static_cast<PhysicsColliderPlane *>(other);
        
        float distanceFromCenter = glm::dot(_other->getNormal(), this->getPosition()) - _other->getDistance();
        
        float distanceFromSphere = distanceFromCenter - this->getRadius();
        
        if (distanceFromSphere < 0)
            return PhysicsCollisionData(true, distanceFromSphere);
        else
            return PhysicsCollisionData(false, distanceFromSphere);
    } else if (other->getType() == PhysicsColliderTypeMesh) {
        PhysicsColliderMesh *_other = static_cast<PhysicsColliderMesh *>(other);
        
        Simplex simplex;
        
        glm::vec3 direction = glm::vec3(1, 1, 1);
        glm::vec3 a = support(_other, this, direction, simplex);
        simplex.add(a);
        
        direction = -a;
        
        int max = 10;
        
        for (int i = 0; i < max; i++) {
            glm::vec3 point = support(_other, this, direction, simplex);
            
            if (glm::dot(point, direction) < 0) {
                return PhysicsCollisionData(false, 0);
            } else {
                simplex.add(point);
                
                if (processSimplex(simplex, direction) == true) {
                    return PhysicsCollisionData(true, 0);
                }
            }
        }
    }
    return PhysicsCollisionData(false, 0);
}