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);
    }
}
Ejemplo n.º 2
0
//===========================================================
//コンストラクタ
//===========================================================
CMath::CMath()
{

	//初期化処理
	int cnt=0;

	while(cnt<360)
	{
		_tsin[cnt] = sinf(cnt*(PI/180.0f));
		if(cnt==0||cnt==180)
		{
			_tsin[cnt] = 0;
		}
		_tcos[cnt] = cosf(cnt*(PI/180.0f));
		if(cnt==90||cnt==270)
		{
			_tcos[cnt] = 0;
		}
		_ttan[cnt] = tanf(cnt*(PI/180.0f));
		cnt++;
	}
	float num = 256.0f;
	for (int cnt = 0;cnt <= 512;cnt++,num--)
	{
		_tatan[cnt] = (float)atan2(num,256);
	}
	std::random_device randDevice;
	MTRand = std::mt19937(randDevice());
}
Ejemplo n.º 3
0
void GameInstanceServer::newRound()
{
    m_currentRound++;
    // dispatch to the server thread if necessary
    m_eventService.dispatch([this]() {

        std::random_device randDevice;
        //float range = m_asteroidField->getCubeSideLength();
        float range = chunksize; // todo: new range calculation?
        float maxRand = randDevice.max();

        /* THIS IS FOR SELECTING A PLANET AS OBJECTIVE. It doesnt work right now because asteroids are not static due to chunking
        AsteroidField* chunk000Asteroids = m_universe.at(osg::Vec3i(0, 0, 0)).m_asteroidField->getAsteroidField;

        //randomly select an asteroid to be set as objective
        int id = (randDevice() / (maxRand+1.0f)) * chunk000Asteroids->getLength();
        Asteroid* a = chunk000Asteroids->getAsteroid(id);

        osg::Vec3f finishArea = a->getPosition();
        m_gameInfo->setObjective(finishArea, a->getRadius());*/

        osg::Vec3f startingPoint = osg::Vec3f(
                                       range*randDevice() / maxRand,
                                       range*randDevice() / maxRand,
                                       range*randDevice() / maxRand);
        osg::Vec3f finishArea = osg::Vec3f(
                                    range*randDevice() / maxRand,
                                    range*randDevice() / maxRand,
                                    range*randDevice() / maxRand);
        m_gameInfo->setObjective(finishArea, 1);


        GameMessage::pointer msg = m_gameInfo->objectiveMessage();
        for (std::map<MessagePeer*, SpaceShipServer::pointer>::iterator peerSpaceShip = m_peerSpaceShips.begin(); peerSpaceShip != m_peerSpaceShips.end(); ++peerSpaceShip)
        {
            //inform clients about new objective
            MessagePeer* buddy = peerSpaceShip->first;
            buddy->send(msg);

        }
    });
}