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); } }
//=========================================================== //コンストラクタ //=========================================================== 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()); }
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); } }); }