bool AsteroidsGame::checkCollision(const Asteroid& tempAsteroid, const WorldEntity& e) 
{
	auto& tempTLocate = e.Transform.Translation;
	auto& asteroidLocate = tempAsteroid.Transform.Translation;
	float distanceSquare = pow(tempTLocate.X - asteroidLocate.X, 2) + pow(tempTLocate.Y - asteroidLocate.Y, 2) + pow(tempTLocate.Z - asteroidLocate.Z, 2);
	if (distanceSquare < tempAsteroid.getRadius())
	{
		Log::Info << "Collision detected." << std::endl;
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
AsteroidFieldChunkServer::AsteroidFieldChunkServer(int asteroidNumber, float chunkSideLength, float astMinSize, float astMaxSize, uint32_t ownerId, osg::Vec3i chunk, GameInstanceServer* ctx, PhysicsEngine* engine) :
GameObject(ownerId, ctx)
{
    m_chunkCoord = chunk;
    m_physicsEngine = engine;
    std::random_device randDevice;

    //Generate Asteroid Field
    //step 1: scatter asteroids. save to AsteroidField
    m_asteroids = std::make_shared<AsteroidField>();
    float astSizeDif = astMaxSize - astMinSize;
    float asteroidCubeMaxSidelength = astMaxSize * 2;
    float radius;
    osg::Vec3f pos;
    for (int i = 0; i < asteroidNumber; i++)
    {
        pos.set(
            randDevice()*1.0f / randDevice.max() * chunkSideLength,
            randDevice()*1.0f / randDevice.max() * chunkSideLength,
            randDevice()*1.0f / randDevice.max() * chunkSideLength);
        radius = ( ( randDevice() * 1.0f / randDevice.max() ) * ( randDevice() * 1.0f / randDevice.max() ) * astSizeDif + astMinSize ) * 0.5f;
        m_asteroids->addAsteroid(pos, radius);
    }

    //step 2: move asteroids to avoid overlappings (heuristic). save to Level::asteroidField
    int accuracy = 10; //how often d'you wanna apply heuristic?
    for (int iterations = 0; iterations < accuracy; iterations++)
    {
        std::shared_ptr<AsteroidField> previousScattering = m_asteroids;
        m_asteroids = std::make_shared<AsteroidField>();
        for (int i = 0; i < asteroidNumber; i++)
        {
            float favoredDistance = (asteroidCubeMaxSidelength - astMaxSize) / 2 + previousScattering->getAsteroid(i)->getRadius();
            float boundingBoxRadius = favoredDistance + astMaxSize / 2;
            std::list<Asteroid*> candidates = previousScattering->getAsteroidsInBlock(previousScattering->getAsteroid(i)->getPosition(), osg::Vec3f(boundingBoxRadius, boundingBoxRadius, boundingBoxRadius));
            osg::Vec3f shift(0, 0, 0);
            int numberOfCloseAsteroids = 0;
            for (std::list<Asteroid*>::iterator it = candidates.begin(); it != candidates.end(); it++) {
                if (*it != previousScattering->getAsteroid(i)) {
                    osg::Vec3f d = previousScattering->getAsteroid(i)->getPosition() - (*it)->getPosition();
                    float scale = -((d.length() - (*it)->getRadius()) - favoredDistance);
                    if (scale > 0) {
                        d.normalize();
                        shift += shift + (d * scale *0.5f); //push away from other close asteroids
                        numberOfCloseAsteroids++;
                    }
                }
            }
            m_asteroids->addAsteroid(previousScattering->getAsteroid(i)->getPosition() + shift, previousScattering->getAsteroid(i)->getRadius());
        }
    }

    // Add asteroids as collision bodies to the engine
    for (unsigned int i = 0; i < m_asteroids->getLength(); ++i)
    {
        Asteroid* currentAst = m_asteroids->getAsteroid(i);
        unsigned int id = engine->addCollisionSphere(currentAst->getPosition() + GameInstanceServer::chunkToPosition(m_chunkCoord), currentAst->getRadius());
        m_physicsIds.push_back(id);
    }
}