void p3d_init_random_seed(int seed) { // SHOULD THAT BE IN THERE ?? (TRO deadline 2016) std::srand((unsigned int) (seed)); // C library implementation mersenne_twister_rng.seed(seed); #ifdef USE_GSL _gsl_seed = gsl_rng_alloc (gsl_rng_taus); #endif printf("Used Seed (set user) = %u\n", seed); }
void deskMove(Furniture& item,double heat, Image<Color>& texture){ // Moves and saved to item, so long as it is inside // Using MTRand mtrand; int TIRES = 100; while(0 < TIRES){ double move_x = mtrand.rand(2*heat); double move_y = mtrand.rand(2*heat); //dummy item Furniture dummy(-1, "dummy", item.getAngle(), item.getPos().x , item.getPos().y); // we want to be able to fitter forward and backwards dummy.setPos( dummy.getPos().x - heat, dummy.getPos().y - heat); // jitter it dummy.setPos( dummy.getPos().x + move_x, dummy.getPos().y + move_y); if(insideSpace(dummy,texture) ){ // if we didn't fall off save item.setPos( dummy.getPos().x, dummy.getPos().y); break; }else{ //dec TIRES--; } }//while }//deskMove
// ========================================================================== // To get you started, this function places tiles on the board and // randomly and outputs the results (in all likelihood *not* a // solution!) in the required format void RandomlyPlaceTiles(Board &board, const std::vector<Tile*> &tiles, std::vector<Location> &locations) { // MersenneTwister is an excellent library for psuedo-random numbers! MTRand mtrand; for (int t = 0; t < tiles.size(); t++) { // loop generates random locations until we (eventually) find one // that is not occupied int i,j; do { // generate a random coordinate within the range 0,0 -> rows-1,cols-1 i = mtrand.randInt(board.numRows()-1); j = mtrand.randInt(board.numColumns()-1); } while (board.getTile(i,j) != NULL); // rotation is always 0 (for now) locations.push_back(Location(i,j,0)); board.setTile(i,j,tiles[t]); } }
int main(int argc, char* argv[]) { cl_parse(argc,argv); print_stats(); rng.seed(seed); densityOperator::Params pA; pA.b = bA; pA.L = L; pA.Ns = Ns; pA.Nz = Nz; pA.Ny = Ny; pA.Nx = Nx; densityOperator::Params pB; pB.b = bB; pB.L = L; pB.Ns = Ns; pB.Nz = Nz; pB.Ny = Ny; pB.Nx = Nx; densOpA = new densityOperator(pA); densOpB = new densityOperator(pB); initRandom(wA); initRandom(wB); double chi_inv = 1.0 / chi; int padlength = tostring(nsteps).length() + 3; for(long long counter = 0; counter <= nsteps;counter++) { if(counter % REPORT == 0) { timer(); cout<<"% Done: "<<fixed<<setprecision(5)<<counter<<"/"<<nsteps<<"\n"; } if(counter % PICTURE == 0) { int err = writeSilo(output_prefix+"/"+tostring(counter,padlength,'0')+".silo","w",&saveSilo); if(err) std::cout<<"Warning: writeSilo returned errors!\n"; } Array<complex<double>,3> factor1((0.5*rho_0/chi_inv)*(wB - wA)); wA += dt*( Na*densOpA->solve(&wA) - factor1 ); wB += dt*( Nb*densOpB->solve(&wB) + factor1 ); } return 0; }
uint p3d_init_random(void) { // srand(time(NULL)); // C library implementation uint t = (uint)time(NULL); printf("Used Seed = %u\n", t); mersenne_twister_rng.seed(t); #ifdef USE_GSL _gsl_seed = gsl_rng_alloc (gsl_rng_taus); #endif return t; }
void PhotonMapping::TracePhoton(const Vec3f &position, const Vec3f &direction, const Vec3f &energy, int iter) { // ============================================== // ASSIGNMENT: IMPLEMENT RECURSIVE PHOTON TRACING // ============================================== // Trace the photon through the scene. At each diffuse or // reflective bounce, store the photon in the kd tree. // One optimization is to *not* store the first bounce, since that // direct light can be efficiently computed using classic ray // tracing. //do ray cast Ray r(position,direction*(1/direction.Length())); Hit h; raytracer->CastRay(r,h,true); if (h.getT()>1000) return; MTRand mtrand; Vec3f refl = h.getMaterial()->getReflectiveColor(); Vec3f diff = h.getMaterial()->getDiffuseColor(); double ran=mtrand.rand(); if (iter==0) ran= mtrand.rand(refl.Length()+diff.Length()); //std::cout<<iter<<" "<<h.getT()<<" "<<refl.Length()+diff.Length()<<std::endl; //send reflective photon if (iter<args->num_bounces&&ran<=refl.Length()) TracePhoton(r.pointAtParameter(h.getT()),r.getDirection()-2*(r.getDirection().Dot3(h.getNormal()))*h.getNormal(),energy,iter+1); else if (iter<args->num_bounces&&ran<=refl.Length()+diff.Length()) TracePhoton(r.pointAtParameter(h.getT()),RandomDiffuseDirection(h.getNormal()),energy,iter+1); else { Photon p(position,direction,energy,iter); kdtree->AddPhoton(p); } }
void RandGen :: load (const std::string& file) { MTRand::uint32 temp[MTRand::SAVE]; std::ifstream ifs ((file+".rand").c_str(), std::ios::binary); if (!ifs) { std::cout << "Error: RandGen :: save: cannot open file '" << file << "\n"; exit(10); } ifs.read ((char*)temp, MTRand::SAVE*sizeof(MTRand::uint32)); ifs.close(); gen.load (temp); }
void Recode(GaloisElemV& des, GaloisElemV src) { //cout << "Recode(GaloisElemV& in_cache, const GaloisElemV new_come)" << endl; MTRand CodingCoefficient; int x = CodingCoefficient.randInt(CodingSpace)+1;//int(tompo); GaloisElem a(&gf, x); int y = CodingCoefficient.randInt(CodingSpace)+1;//int(tompo); GaloisElem b(&gf, y); GaloisElemV::iterator it_des = des.begin(); GaloisElemV::iterator it_src = src.begin(); for(;it_des != des.end(); ) { (*it_des) = a * (*it_des) + b * (*it_src); it_des++; it_src++; } }
void Graph::pass_messages(MTRand &mtrand){ for (std::vector<Person*>::const_iterator p2 = m_people.begin(); p2 != m_people.end(); ++p2){ std::list<Person*> friends=((*p2)->get_friends()); std::list<Message*> messages_lst=((*p2)->get_messages()); //std::cout<<"size"<<friends.size()<<std::endl; if(messages_lst.size()==0) { continue; } //std::cout<<"Person"<<(*p2)->get_name()<<std::endl; //for (std::list<Message *>::const_iterator it1 = messages_lst.begin(); it1 != messages_lst.end(); ++it1){ int random_num=mtrand.randInt(friends.size()); //std::cout<<"random number generated"<<random_num<<std::endl; if(random_num==0) { continue; } else{ std::list<Person*>::const_iterator it3=friends.begin(); std::list<Message *>::const_iterator it1 = messages_lst.begin(); for(int i=0;i<random_num-1;i++){ it3++; } //Person* p1=*it3; std::string pers=(*it3)->get_name(); // std::cout<<"person"<<pers<<std::endl; const std::string z=((*it1)->get_message()); //std::cout<<z; bool a=add_message(pers,z); bool b=((*p2)->remove_message(*it1)); } // find the random number from the friends list and send the message to that number // we need to add the message into the graph also and that will call message of person. // We need to change the owner of the function also //continue; //} } }
// Timer redraw void newParticle(int value) { particle p; p.position.x = startPosition.x; p.position.y = startPosition.y; p.position.z = startPosition.z; MTRand rand; p.randDisplacement.x = rand.randDblExc(randDisplacementMax.x - randDisplacementMin.x) + randDisplacementMin.x; p.randDisplacement.y = rand.randDblExc(randDisplacementMax.y - randDisplacementMin.y) + randDisplacementMin.y; p.randDisplacement.z = rand.randDblExc(randDisplacementMax.z - randDisplacementMin.z) + randDisplacementMin.z; if (randomColor) { p.color[0] = rand.randDblExc(); p.color[1] = rand.randDblExc(); p.color[2] = rand.randDblExc(); p.color[3] = 1.0; } p.age = 0; parts.push_back(p); glutPostRedisplay(); glutTimerFunc(redrawTime, newParticle, 1); }
// constructs a random clockpiece clockPiece::clockPiece() { // creates an MTRand that can make random numbers MTRand randGen; // initialize data mPieceType = randGen.randInt(PTYPE_AMT); mPieceInterval = 0; mPendulumLength = 0; mNumTeeth = 0; mIsConnected = false; mIsPowered = false; mIsAttToHand = false; // determine other member variables based on the part type if (mPieceType == PTYPE_PENDULUM) // random length of pendulum between 0 and 1 meter mPendulumLength = randGen.rand(); else if (mPieceType == PTYPE_GEAR) // random number of gear teeth (physical minimum is 3) mNumTeeth = randGen.randInt(MAX_TEETH - 3) + 3; }
/**************************************************************************//** * Return a random position close to the supplied one. Shell Jump ******************************************************************************/ dVec Cylinder::randUpdateJumpShell (MTRand &random, const dVec &pos) const { dVec randPos; randPos = pos; double theta = atan2(pos[1],pos[0]); double oldr = sqrt(pos[0]*pos[0] + pos[1]*pos[1]); double newr; if (random.rand() > 0.5) newr = oldr + (1.00 + 2.50*random.rand()); else newr = oldr - (1.00 + 2.50*random.rand()); if (newr < 0.0) newr *= -1.0; double ranTheta = M_PI*(-0.05 + 0.1*random.rand()); randPos[0] = newr*cos(theta + ranTheta); randPos[1] = newr*sin(theta + ranTheta); randPos[2] += constants()->displaceDelta()*(-0.5 + random.rand()); putInside(randPos); return randPos; }
void SwarmFitterInterface::randomizeTopology(vector< SwarmFly > & swarm, int maxInformed, MTRand & randGen) { for (int i = 0; i < (int)swarm.size(); i++) { swarm[i].resetInformants(); showMessage(str(i) + " informs: { ",4,fixedParams); for (int j = 0; j < maxInformed; j++) { int randI = randGen.randInt(swarm.size()-1); swarm[randI].addInformant(&(swarm[j])); showMessage(str(randI) + " ",4,fixedParams); } showMessage("}\n",4,fixedParams); } }
void Recode(GaloisElemVV& _factors, GaloisElemV factor) { cout << "Recode(GaloisElemVV& in_cache, const GaloisElemV new_come)" << endl; MTRand CodingCoefficient; int x = CodingCoefficient.randInt(CodingSpace)+1;//int(tompo); //int x = 1; GaloisElem a(&gf, x); int y = CodingCoefficient.randInt(CodingSpace)+1;//int(tompo); //int y = 1; GaloisElem b(&gf, y); for(GaloisElemVV::iterator it_vv = _factors.begin();it_vv != _factors.end(); it_vv++) { GaloisElemV::iterator it_f = factor.begin(); GaloisElemV::iterator it_v = it_vv->begin(); for(; it_v != it_vv->end(); ) { (*it_v) = a * (*it_v) + b * (*it_f); it_v++; it_f++; } } }
/* * Method: Number * * Generates a real (non-integer) number. * * > number = rand:Number() * > number = rand:Number(max) * > number = rand:Number(min, max) * * Parameters: * * min - optional, the minimum possible value for the generated number. If * omitted, defaults to 0 * * max - optional, the maximum possible value for the generated number. If * omitted, defaults to a very large number (currently 2^32-1) * * Return: * * number - the random number * * Availability: * * alpha 10 * * Status: * * stable */ static int l_rand_number(lua_State *l) { MTRand *rand = LuaObject<MTRand>::CheckFromLua(1); double min, max; if (lua_isnumber(l, 2) && lua_isnumber(l, 3)) { min = lua_tonumber(l, 2); max = lua_tonumber(l, 3); } else if (lua_isnumber(l, 2)) { min = 0.0; max = lua_tonumber(l, 2); } else { lua_pushnumber(l, rand->Double()); return 1; } if (min > max) luaL_error(l, "Max must be bigger than min in random number range"); lua_pushnumber(l, rand->Double(min, max)); return 1; }
void initRandom(Array<complex<double>,3>& arr) { complex<double> total = 0; for(blitz::Array<complex<double>,3>::iterator it = arr.begin(); it != arr.end(); ++it) { double r1 = 2.0*(rng.rand53() - 0.5); double r2 = 2.0*(rng.rand53() - 0.5); *it = complex<double>(r1,r2); total += *it; } arr -= total / double(Nx*Ny*Nz); }
/* * Method: Integer * * Generates an integer number * * > number = rand:Integer() * > number = rand:Integer(max) * > number = rand:Integer(min, max) * * Parameters: * * min - optional, the minimum possible value for the generated number. If * omitted, defaults to 0 * * max - optional, the maximum possible value for the generated number. If * omitted, defaults to a very large number (currently 2^32-1) * * Return: * * number - the random number * * Availability: * * alpha 10 * * Status: * * stable */ static int l_rand_integer(lua_State *l) { MTRand *rand = LuaObject<MTRand>::GetFromLua(1); int min, max; if (lua_isnumber(l, 2) && lua_isnumber(l, 3)) { min = lua_tointeger(l, 2); max = lua_tointeger(l, 3); } else if (lua_isnumber(l, 2)) { min = 0; max = lua_tointeger(l, 2); } else { lua_pushnumber(l, rand->Int32()); return 1; } if (min > max) luaL_error(l, "Max must be bigger than min in random number range"); lua_pushnumber(l, rand->Int32(min, max)); return 1; }
void setupInitalRandomPos(std::vector<Furniture> & fVec, Image<Color>& texture){ // Genereate Random Position std::cout << "Randomizing"<< std::endl; MTRand mtrand; unsigned int curIndex = 0; // for each piece of furnature while(curIndex < fVec.size()){ std::cout << "Desk "<< curIndex<<" Tying" << std::endl; // random x and y and rotation float start_x = mtrand.rand(TEXTURE_SIZE_X); float start_y = mtrand.rand(TEXTURE_SIZE_Y); double start_rot = mtrand.rand(2* M_PI); // set to that random values fVec[curIndex].setPos(start_x, start_y); fVec[curIndex].setAngle(start_rot); // check if were good if(insideSpace(fVec[curIndex], texture)){ //debug Color avgColor = getApproxColor(fVec[curIndex] , texture); std::cout << "Desk "<< curIndex<<" PASS "; std::cout << static_cast<unsigned>(avgColor.r)<< ", "; std::cout << static_cast<unsigned>(avgColor.g)<< ", "; std::cout << static_cast<unsigned>(avgColor.b)<< std::endl; curIndex++; }else{ std::cout << "Desk "<< curIndex<<" FAIL"<< std::endl; } } }
double gasdev() { static int iset=0; static double gset; double fac,rsq,v1,v2; // if (idum < 0) iset=0; if (iset == 0) { do { v1=2.0*rnd.rand()-1.0; v2=2.0*rnd.rand()-1.0; rsq=v1*v1+v2*v2; } while (rsq >= 1.0 || rsq == 0.0); fac=sqrt(-2.0*log(rsq)/rsq); gset=v1*fac; iset=1; return v2*fac; } else { iset=0; return gset; } };
double rand_chance(void) { return mtRand.randExc(100.0); }
/// Finds a random 2D point, within the specified region, that has no other objects within the requested radius, using an exising (already seeded) Mersenne Twister random number generator. bool GridDatabase2D::randomPositionInRegionWithoutCollisions(const Util::AxisAlignedBox & region, SpatialDatabaseItemPtr item, bool excludeAgents, MTRand & randomNumberGenerator) { Point ret(0.0f, 0.0f, 0.0f); bool notFoundYet; unsigned int numTries = 0; float radius = 0.0f; AgentInterface * ai; AgentInitialConditions aic; if ( item->isAgent() ) { ai = dynamic_cast<AgentInterface*>(item); radius = ai->radius(); aic = ai->getAgentConditions(ai); } float xspan = region.xmax - region.xmin - 2*radius; float zspan = region.zmax - region.zmin - 2*radius; do { ret.x = region.xmin + radius + ((float)randomNumberGenerator.rand(xspan)); ret.y = 0.0f; ret.z = region.zmin + radius + ((float)randomNumberGenerator.rand(zspan)); aic.position = ret; // assume this new point has no collisions, until we find out below notFoundYet = false; // check if ret collides with anything set<SpatialDatabaseItemPtr> neighbors; neighbors.clear(); float _new_radius = radius; getItemsInRange(neighbors, ret.x - _new_radius, ret.x + _new_radius, ret.z - _new_radius, ret.z + _new_radius, NULL); set<SpatialDatabaseItemPtr>::iterator neighbor; for (size_t dirs=0; dirs < 10; dirs++) { float theta = randomNumberGenerator.rand() * M_2_PI; double directionX = cos(theta); double directionZ = sin(theta); aic.direction = Util::Vector(directionX, 0.0f, directionZ); ai->reset(aic, ai->getSimulationEngine()); ai->disable(); /* * increment must be after loop body or (*neighbor)->isAgent()) will be called on an * element that is beyond the set. */ for (neighbor = neighbors.begin(); neighbor != neighbors.end(); neighbor++) { if ((excludeAgents) && ((*neighbor)->isAgent())) { continue; } notFoundYet = (*neighbor)->overlaps(ret, radius) || ai->overlaps((*neighbor)); if (notFoundYet) { std::cout << "Try again placing agent: " << std::endl; break; } } if (notFoundYet) { // no intersections break; } }// dirs numTries++; if (numTries > 1000) { cerr << "ERROR: trying too hard to find a random position in region. The region is probably already too dense." << endl; if (numTries > 10000) { throw GenericException("Gave up trying to find a random position in region."); } } } while (notFoundYet); return !notFoundYet; }
void GenCol(float col[4], MTRand &rng) const { float ma = 1 + float(rng.Double(modAll*2)-modAll); for (int i=0; i<4; i++) col[i] = baseCol[i] + float(rng.Double(-modCol[i], modCol[i])); for (int i=0; i<3; i++) col[i] = Clamp(ma*col[i], 0.0f, 1.0f); }
double rand_norm(void) { return mtRand.randExc(); }
/**************************************************************************//** * Return a random position inside the cube. ******************************************************************************/ dVec Prism::randPosition(MTRand &random) const { dVec randPos; for (int i = 0; i < NDIM; i++) randPos[i] = side[i]*(-0.5 + random.randExc()); return randPos; }
const double operator()(const double & ignore) { return GlobalMT.rand(); }
//************************* // Main // int main(int argc, char *argv[]) { int sckt; pthread_t recvThread; char sendBuffer[BUFFER_SIZE]; int indexBuffer; int sharedRecs; RTDBconf_var rec[MAX_RECS]; unsigned int frameCounter = 0; int i, j; int life; struct sched_param proc_sched; pthread_attr_t thread_attr; struct itimerval it; struct _frameHeader frameHeader; struct timeval tempTimeStamp; nosend = 0; if ((argc < 2) || (argc > 3)) { printUsage(); return (-1); } if (argc == 3) { if(strcmp(argv[2], "nosend") == 0) { printf("\n*** Running in listing only mode ***\n\n"); nosend = 1; } else { printUsage(); return (-1); } } /* initializations */ delay = 0; timer = 0; end = 0; RUNNING_AGENTS = 1; /* Assign a real-time priority to process */ proc_sched.sched_priority=60; if ((sched_setscheduler(getpid(), SCHED_FIFO, &proc_sched)) < 0) { PERRNO("setscheduler"); return -1; } if(signal(SIGALRM, signal_catch) == SIG_ERR) { PERRNO("signal"); return -1; } if(signal(SIGINT, signal_catch) == SIG_ERR) { PERRNO("signal"); return -1; } if((sckt = openSocket(argv[1])) == -1) { PERR("openMulticastSocket"); printf("\nUsage: comm <interface_name>\n\n"); return -1; } if(DB_init() == -1) { PERR("DB_init"); closeSocket(sckt); return -1; } if((sharedRecs = DB_comm_ini(rec)) < 1) { PERR("DB_comm_ini"); DB_free(); closeSocket(sckt); return -1; } #ifdef FILEDEBUG if ((filedebug = fopen("log.txt", "w")) == NULL) { PERRNO("fopen"); DB_free(); closeSocket(sckt); return -1; } #endif /* initializations */ for (i=0; i<MAX_AGENTS; i++) { lostPackets[i]=0; agent[i].lastFrameCounter = 0; agent[i].state = NOT_RUNNING; agent[i].removeCounter = 0; } myNumber = Whoami(); agent[myNumber].state = RUNNING; /* receive thread */ pthread_attr_init (&thread_attr); pthread_attr_setinheritsched (&thread_attr, PTHREAD_INHERIT_SCHED); if ((pthread_create(&recvThread, &thread_attr, receiveDataThread, (void *)&sckt)) != 0) { PERRNO("pthread_create"); DB_free(); closeSocket(sckt); return -1; } /* Set itimer to reactivate the program */ it.it_value.tv_usec=(__suseconds_t)(TTUP_US); it.it_value.tv_sec=0; it.it_interval.tv_usec=(__suseconds_t)(TTUP_US); it.it_interval.tv_sec=0; setitimer (ITIMER_REAL, &it, NULL); printf("communication: STARTED in "); #ifdef UNSYNC printf("unsync mode...\n"); #else printf("sync mode...\n"); #endif MTRand randomGenerator; while (!end) { //pause(); double waitTime = randomGenerator.randNorm(0,1) * TTUP_US * 0.05 + TTUP_US; usleep(waitTime); // not timer event if (timer == 0) continue; #ifndef UNSYNC // dynamic agent 0 if ((delay > (int)MIN_UPDATE_DELAY_US) && (agent[myNumber].dynamicID == 0) && timer == 1) { it.it_value.tv_usec = (__suseconds_t)(delay - (int)MIN_UPDATE_DELAY_US/2); it.it_value.tv_sec = 0; setitimer (ITIMER_REAL, &it, NULL); delay = 0; continue; } #endif timer = 0; indexBuffer = 0; bzero(sendBuffer, BUFFER_SIZE); update_stateTable(); // update dynamicID j = 0; for (i = 0; i < MAX_AGENTS; i++) { if ((agent[i].state == RUNNING) || (agent[i].state == REMOVE)) { agent[i].dynamicID = j; j++; } agent[myNumber].stateTable[i] = agent[i].state; } RUNNING_AGENTS = j; MAX_DELTA = (int)(TTUP_US/RUNNING_AGENTS * 2/3); // frame header frameHeader.number = myNumber; frameHeader.counter = frameCounter; frameCounter ++; for (i = 0; i < MAX_AGENTS; i++) frameHeader.stateTable[i] = agent[myNumber].stateTable[i]; frameHeader.noRecs = sharedRecs; memcpy(sendBuffer + indexBuffer, &frameHeader, sizeof(frameHeader)); indexBuffer += sizeof(frameHeader); for(i = 0; i < sharedRecs; i++) { // id memcpy(sendBuffer + indexBuffer, &rec[i].id, sizeof(rec[i].id)); indexBuffer += sizeof(rec[i].id); // size memcpy(sendBuffer + indexBuffer, &rec[i].size, sizeof(rec[i].size)); indexBuffer += sizeof(rec[i].size); // life and data life = DB_get(myNumber, rec[i].id, sendBuffer + indexBuffer + sizeof(life)); memcpy(sendBuffer + indexBuffer, &life, sizeof(life)); indexBuffer = indexBuffer + sizeof(life) + rec[i].size; } if (indexBuffer > BUFFER_SIZE) { PERR("Pretended frame is bigger that the available buffer."); PERR("Please increase the buffer size or reduce the number of disseminated records"); break; } if (nosend == 0) { if (sendData(sckt, sendBuffer, indexBuffer) != indexBuffer) PERRNO("Error sending data"); } gettimeofday (&tempTimeStamp, NULL); lastSendTimeStamp.tv_sec = tempTimeStamp.tv_sec; lastSendTimeStamp.tv_usec = tempTimeStamp.tv_usec; // reset values for next round for (i=0; i<MAX_AGENTS; i++) { agent[i].delta = 0; agent[i].received = NO; } } FDEBUG (filedebug, "\nLost Packets:\n"); for (i=0; i<MAX_AGENTS; i++) FDEBUG (filedebug, "%d\t", lostPackets[i]); FDEBUG (filedebug, "\n"); printf("communication: STOPED.\nCleaning process...\n"); #ifdef FILEDEBUG fclose (filedebug); #endif closeSocket(sckt); pthread_join(recvThread, NULL); DB_free(); printf("communication: FINISHED.\n"); return 0; }
void CityOnPlanet::PutCityBit(MTRand &rand, const matrix4x4d &rot, vector3d p1, vector3d p2, vector3d p3, vector3d p4) { double rad = (p1-p2).Length()*0.5; LmrModel *model(0); double modelRadXZ(0); const LmrCollMesh *cmesh(0); vector3d cent = (p1+p2+p3+p4)*0.25; cityflavourdef_t *flavour(0); citybuildinglist_t *buildings(0); // pick a building flavour (city, windfarm, etc) for (int flv=0; flv<CITYFLAVOURS; flv++) { flavour = &cityflavour[flv]; buildings = &s_buildingLists[flavour->buildingListIdx]; int tries; for (tries=20; tries--; ) { const citybuilding_t &bt = buildings->buildings[rand.Int32(buildings->numBuildings)]; model = bt.resolvedModel; modelRadXZ = bt.xzradius; cmesh = bt.collMesh; if (modelRadXZ < rad) break; if (tries == 0) return; } bool tooDistant = ((flavour->center - cent).Length()*(1.0/flavour->size) > rand.Double()); if (!tooDistant) break; else flavour = 0; } if (flavour == 0) { if (rad > MIN_SEG_SIZE) goto always_divide; else return; } if (rad > modelRadXZ*2.0) { always_divide: vector3d a = (p1+p2)*0.5; vector3d b = (p2+p3)*0.5; vector3d c = (p3+p4)*0.5; vector3d d = (p4+p1)*0.5; vector3d e = (p1+p2+p3+p4)*0.25; PutCityBit(rand, rot, p1, a, e, d); PutCityBit(rand, rot, a, p2, b, e); PutCityBit(rand, rot, e, b, p3, c); PutCityBit(rand, rot, d, e, c, p4); } else { cent = cent.Normalized(); double height = m_planet->GetTerrainHeight(cent); /* don't position below sealevel! */ if (height - m_planet->GetSBody()->GetRadius() <= 0.0) return; cent = cent * height; assert(cmesh); Geom *geom = new Geom(cmesh->geomTree); int rotTimes90 = rand.Int32(4); matrix4x4d grot = rot * matrix4x4d::RotateYMatrix(M_PI*0.5*double(rotTimes90)); geom->MoveTo(grot, cent); geom->SetUserData(this); // f->AddStaticGeom(geom); BuildingDef def = { model, cmesh->GetBoundingRadius(), rotTimes90, cent, geom, false }; m_buildings.push_back(def); } }
CityOnPlanet::CityOnPlanet(Planet *planet, SpaceStation *station, Uint32 seed) { m_buildings.clear(); m_planet = planet; m_frame = planet->GetFrame(); m_detailLevel = Pi::detail.cities; /* Resolve city model numbers since it is a bit expensive */ if (!s_cityBuildingsInitted) { s_cityBuildingsInitted = true; for (int i=0; i<MAX_BUILDING_LISTS; i++) { lookupBuildingListModels(&s_buildingLists[i]); } } Aabb aabb; station->GetAabb(aabb); matrix4x4d m; station->GetRotMatrix(m); vector3d mx = m*vector3d(1,0,0); vector3d mz = m*vector3d(0,0,1); MTRand rand; rand.seed(seed); vector3d p = station->GetPosition(); vector3d p1, p2, p3, p4; double sizex = START_SEG_SIZE;// + rand.Int32((int)START_SEG_SIZE); double sizez = START_SEG_SIZE;// + rand.Int32((int)START_SEG_SIZE); // always have random shipyard buildings around the space station cityflavour[0].buildingListIdx = 0;//2; cityflavour[0].center = p; cityflavour[0].size = 500; for (int i=1; i<CITYFLAVOURS; i++) { cityflavour[i].buildingListIdx = MAX_BUILDING_LISTS>1 ? rand.Int32(MAX_BUILDING_LISTS-1) : 0; citybuildinglist_t *blist = &s_buildingLists[cityflavour[i].buildingListIdx]; double a = rand.Int32(-1000,1000); double b = rand.Int32(-1000,1000); cityflavour[i].center = p + a*mx + b*mz; cityflavour[i].size = rand.Int32(int(blist->minRadius), int(blist->maxRadius)); } for (int side=0; side<4; side++) { /* put buildings on all sides of spaceport */ switch(side) { case 3: p1 = p + mx*(aabb.min.x) + mz*aabb.min.z; p2 = p + mx*(aabb.min.x) + mz*(aabb.min.z-sizez); p3 = p + mx*(aabb.min.x+sizex) + mz*(aabb.min.z-sizez); p4 = p + mx*(aabb.min.x+sizex) + mz*(aabb.min.z); break; case 2: p1 = p + mx*(aabb.min.x-sizex) + mz*aabb.max.z; p2 = p + mx*(aabb.min.x-sizex) + mz*(aabb.max.z-sizez); p3 = p + mx*(aabb.min.x) + mz*(aabb.max.z-sizez); p4 = p + mx*(aabb.min.x) + mz*(aabb.max.z); break; case 1: p1 = p + mx*(aabb.max.x-sizex) + mz*aabb.max.z; p2 = p + mx*(aabb.max.x) + mz*aabb.max.z; p3 = p + mx*(aabb.max.x) + mz*(aabb.max.z+sizez); p4 = p + mx*(aabb.max.x-sizex) + mz*(aabb.max.z+sizez); break; default: case 0: p1 = p + mx*aabb.max.x + mz*aabb.min.z; p2 = p + mx*(aabb.max.x+sizex) + mz*aabb.min.z; p3 = p + mx*(aabb.max.x+sizex) + mz*(aabb.min.z+sizez); p4 = p + mx*aabb.max.x + mz*(aabb.min.z+sizez); break; } PutCityBit(rand, m, p1, p2, p3, p4); } AddStaticGeomsToCollisionSpace(); }
float rand_chance_f(void) { return (float)mtRand.randExc(100.0); }
float rand_norm_f(void) { return (float)mtRand.randExc(); }