double testfunc() { Random rng; double r = 0.0; for (int i=0; i<1000; i++) r += noise(1000.0*rng.Double(), 1000.0*rng.Double(), 1000.0*rng.Double()); return r; }
double testfunc2() { Random rng; double r = 0.0; for (int i=0; i<1000; i++) { r += 1000.0*rng.Double(); r += 1000.0*rng.Double(); r += 1000.0*rng.Double(); } return r; }
/* * 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) { Random *rand = LuaObject<Random>::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 Starfield::Fill(Random &rand) { Graphics::VertexBufferDesc vbd; vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.attrib[1].semantic = Graphics::ATTRIB_DIFFUSE; vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_UBYTE4; vbd.usage = Graphics::BUFFER_USAGE_STATIC; vbd.numVertices = BG_STAR_MAX; m_vertexBuffer.reset(m_renderer->CreateVertexBuffer(vbd)); assert(sizeof(StarVert) == 16); assert(m_vertexBuffer->GetDesc().stride == sizeof(StarVert)); auto vtxPtr = m_vertexBuffer->Map<StarVert>(Graphics::BUFFER_MAP_WRITE); //fill the array for (int i=0; i<BG_STAR_MAX; i++) { const Uint8 col = rand.Double(0.2,0.7)*255; // this is proper random distribution on a sphere's surface const float theta = float(rand.Double(0.0, 2.0*M_PI)); const float u = float(rand.Double(-1.0, 1.0)); vtxPtr->pos = vector3f( 1000.0f * sqrt(1.0f - u*u) * cos(theta), 1000.0f * u, 1000.0f * sqrt(1.0f - u*u) * sin(theta)); vtxPtr->col = Color(col, col, col, 255); //need to keep data around for HS anim - this is stupid m_hyperVtx[BG_STAR_MAX * 2 + i] = vtxPtr->pos; m_hyperCol[BG_STAR_MAX * 2 + i] = vtxPtr->col; vtxPtr++; } m_vertexBuffer->Unmap(); }
void Star::Render(Graphics::Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { double radius = GetClipRadius(); double rad = radius; vector3d fpos = viewCoords; double len = fpos.Length(); while (len > 1000.0f) { rad *= 0.25; fpos = 0.25*fpos; len *= 0.25; } matrix4x4d trans = matrix4x4d::Identity(); trans.Translate(float(fpos.x), float(fpos.y), float(fpos.z)); // face the camera dammit vector3d zaxis = viewCoords.NormalizedSafe(); vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized(); vector3d yaxis = zaxis.Cross(xaxis); matrix4x4d rot = matrix4x4d::MakeRotMatrix(xaxis, yaxis, zaxis).Inverse(); renderer->SetTransform(trans * rot); Random rand; //render star halo VertexArray va(ATTRIB_POSITION | ATTRIB_DIFFUSE); const Color bright(StarSystem::starRealColors[GetSystemBody()->GetType()]); const Color dark(Color::BLANK); va.Add(vector3f(0.f), bright); for (float ang=0; ang<2*M_PI; ang+=0.26183+rand.Double(0,0.4)) { va.Add(vector3f(rad*sin(ang), rad*cos(ang), 0), dark); } va.Add(vector3f(0.f, rad, 0.f), dark); renderer->DrawTriangles(&va, m_haloState, Graphics::vtxColorMaterial, TRIANGLE_FAN); TerrainBody::Render(renderer, camera, viewCoords, viewTransform); renderer->GetStats().AddToStatCount(Graphics::Stats::STAT_STARS, 1); }
bool SectorRandomSystemsGenerator::Apply(Random& rng, RefCountedPtr<Galaxy> galaxy, RefCountedPtr<Sector> sector, GalaxyGenerator::SectorConfig* config) { /* Always place random systems outside the core custom-only region */ if (config->isCustomOnly) return true; const int sx = sector->sx; const int sy = sector->sy; const int sz = sector->sz; const int customCount = static_cast<Uint32>(sector->m_systems.size()); const Sint64 dist = (1 + sx*sx + sy*sy + sz*sz); const Sint64 freq = (1 + sx * sx + sy * sy); const int numSystems = (rng.Int32(4,20) * galaxy->GetSectorDensity(sx, sy, sz)) >> 8; sector->m_systems.reserve(numSystems); for (int i=0; i<numSystems; i++) { Sector::System s(sector.Get(), sx, sy, sz, customCount + i); switch (rng.Int32(15)) { case 0: s.m_numStars = 4; break; case 1: case 2: s.m_numStars = 3; break; case 3: case 4: case 5: case 6: s.m_numStars = 2; break; default: s.m_numStars = 1; break; } s.m_pos.x = rng.Double(Sector::SIZE); s.m_pos.y = rng.Double(Sector::SIZE); s.m_pos.z = rng.Double(Sector::SIZE); /* * 0 - ~500ly from sol: explored * ~500ly - ~700ly (65-90 sectors): gradual * ~700ly+: unexplored */ if (((dist <= Square(90)) && ( dist <= Square(65) || rng.Int32(dist) <= Square(40))) || galaxy->GetFactions()->IsHomeSystem(SystemPath(sx, sy, sz, customCount + i))) s.m_explored = StarSystem::eEXPLORED_AT_START; else s.m_explored = StarSystem::eUNEXPLORED; // Frequencies are low enough that we probably don't need this anymore. if (freq > Square(10)) { const Uint32 weight = rng.Int32(1000000); if (weight < 1) { s.m_starType[0] = SystemBody::TYPE_STAR_IM_BH; // These frequencies are made up } else if (weight < 3) { s.m_starType[0] = SystemBody::TYPE_STAR_S_BH; } else if (weight < 5) { s.m_starType[0] = SystemBody::TYPE_STAR_O_WF; } else if (weight < 8) { s.m_starType[0] = SystemBody::TYPE_STAR_B_WF; } else if (weight < 12) { s.m_starType[0] = SystemBody::TYPE_STAR_M_WF; } else if (weight < 15) { s.m_starType[0] = SystemBody::TYPE_STAR_K_HYPER_GIANT; } else if (weight < 18) { s.m_starType[0] = SystemBody::TYPE_STAR_G_HYPER_GIANT; } else if (weight < 23) { s.m_starType[0] = SystemBody::TYPE_STAR_O_HYPER_GIANT; } else if (weight < 28) { s.m_starType[0] = SystemBody::TYPE_STAR_A_HYPER_GIANT; } else if (weight < 33) { s.m_starType[0] = SystemBody::TYPE_STAR_F_HYPER_GIANT; } else if (weight < 41) { s.m_starType[0] = SystemBody::TYPE_STAR_B_HYPER_GIANT; } else if (weight < 48) { s.m_starType[0] = SystemBody::TYPE_STAR_M_HYPER_GIANT; } else if (weight < 58) { s.m_starType[0] = SystemBody::TYPE_STAR_K_SUPER_GIANT; } else if (weight < 68) { s.m_starType[0] = SystemBody::TYPE_STAR_G_SUPER_GIANT; } else if (weight < 78) { s.m_starType[0] = SystemBody::TYPE_STAR_O_SUPER_GIANT; } else if (weight < 88) { s.m_starType[0] = SystemBody::TYPE_STAR_A_SUPER_GIANT; } else if (weight < 98) { s.m_starType[0] = SystemBody::TYPE_STAR_F_SUPER_GIANT; } else if (weight < 108) { s.m_starType[0] = SystemBody::TYPE_STAR_B_SUPER_GIANT; } else if (weight < 158) { s.m_starType[0] = SystemBody::TYPE_STAR_M_SUPER_GIANT; } else if (weight < 208) { s.m_starType[0] = SystemBody::TYPE_STAR_K_GIANT; } else if (weight < 250) { s.m_starType[0] = SystemBody::TYPE_STAR_G_GIANT; } else if (weight < 300) { s.m_starType[0] = SystemBody::TYPE_STAR_O_GIANT; } else if (weight < 350) { s.m_starType[0] = SystemBody::TYPE_STAR_A_GIANT; } else if (weight < 400) { s.m_starType[0] = SystemBody::TYPE_STAR_F_GIANT; } else if (weight < 500) { s.m_starType[0] = SystemBody::TYPE_STAR_B_GIANT; } else if (weight < 700) { s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; } else if (weight < 800) { s.m_starType[0] = SystemBody::TYPE_STAR_O; // should be 1 but that is boring } else if (weight < 2000) { // weight < 1300 / 20500 s.m_starType[0] = SystemBody::TYPE_STAR_B; } else if (weight < 8000) { // weight < 7300 s.m_starType[0] = SystemBody::TYPE_STAR_A; } else if (weight < 37300) { // weight < 37300 s.m_starType[0] = SystemBody::TYPE_STAR_F; } else if (weight < 113300) { // weight < 113300 s.m_starType[0] = SystemBody::TYPE_STAR_G; } else if (weight < 234300) { // weight < 234300 s.m_starType[0] = SystemBody::TYPE_STAR_K; } else if (weight < 250000) { // weight < 250000 s.m_starType[0] = SystemBody::TYPE_WHITE_DWARF; } else if (weight < 900000) { //weight < 900000 s.m_starType[0] = SystemBody::TYPE_STAR_M; } else { s.m_starType[0] = SystemBody::TYPE_BROWN_DWARF; } } else { const Uint32 weight = rng.Int32(1000000); if (weight < 100) { // should be 1 but that is boring s.m_starType[0] = SystemBody::TYPE_STAR_O; } else if (weight < 1300) { s.m_starType[0] = SystemBody::TYPE_STAR_B; } else if (weight < 7300) { s.m_starType[0] = SystemBody::TYPE_STAR_A; } else if (weight < 37300) { s.m_starType[0] = SystemBody::TYPE_STAR_F; } else if (weight < 113300) { s.m_starType[0] = SystemBody::TYPE_STAR_G; } else if (weight < 234300) { s.m_starType[0] = SystemBody::TYPE_STAR_K; } else if (weight < 250000) { s.m_starType[0] = SystemBody::TYPE_WHITE_DWARF; } else if (weight < 900000) { s.m_starType[0] = SystemBody::TYPE_STAR_M; } else { s.m_starType[0] = SystemBody::TYPE_BROWN_DWARF; } } //Output("%d: %d%\n", sx, sy); if (s.m_numStars > 1) { s.m_starType[1] = SystemBody::BodyType(rng.Int32(SystemBody::TYPE_STAR_MIN, s.m_starType[0])); if (s.m_numStars > 2) { s.m_starType[2] = SystemBody::BodyType(rng.Int32(SystemBody::TYPE_STAR_MIN, s.m_starType[0])); s.m_starType[3] = SystemBody::BodyType(rng.Int32(SystemBody::TYPE_STAR_MIN, s.m_starType[2])); } } if ((s.m_starType[0] <= SystemBody::TYPE_STAR_A) && (rng.Int32(10)==0)) { // make primary a giant. never more than one giant in a system if (freq > Square(10)) { const Uint32 weight = rng.Int32(1000); if (weight >= 999) { s.m_starType[0] = SystemBody::TYPE_STAR_B_HYPER_GIANT; } else if (weight >= 998) { s.m_starType[0] = SystemBody::TYPE_STAR_O_HYPER_GIANT; } else if (weight >= 997) { s.m_starType[0] = SystemBody::TYPE_STAR_K_HYPER_GIANT; } else if (weight >= 995) { s.m_starType[0] = SystemBody::TYPE_STAR_B_SUPER_GIANT; } else if (weight >= 993) { s.m_starType[0] = SystemBody::TYPE_STAR_O_SUPER_GIANT; } else if (weight >= 990) { s.m_starType[0] = SystemBody::TYPE_STAR_K_SUPER_GIANT; } else if (weight >= 985) { s.m_starType[0] = SystemBody::TYPE_STAR_B_GIANT; } else if (weight >= 980) { s.m_starType[0] = SystemBody::TYPE_STAR_O_GIANT; } else if (weight >= 975) { s.m_starType[0] = SystemBody::TYPE_STAR_K_GIANT; } else if (weight >= 950) { s.m_starType[0] = SystemBody::TYPE_STAR_M_HYPER_GIANT; } else if (weight >= 875) { s.m_starType[0] = SystemBody::TYPE_STAR_M_SUPER_GIANT; } else { s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; } } else if (freq > Square(5)) s.m_starType[0] = SystemBody::TYPE_STAR_M_GIANT; else s.m_starType[0] = SystemBody::TYPE_STAR_M; //Output("%d: %d%\n", sx, sy); } s.m_name = GenName(galaxy, *sector, s, customCount + i, rng); //Output("%s: \n", s.m_name.c_str()); sector->m_systems.push_back(s); } return true; }
void CityOnPlanet::PutCityBit(Random &rand, const matrix4x4d &rot, vector3d p1, vector3d p2, vector3d p3, vector3d p4) { double rad = (p1-p2).Length()*0.5; Uint32 instIndex(0); double modelRadXZ(0.0); const CollMesh *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 (unsigned int flv = 0; flv < CITYFLAVOURS; flv++) { flavour = &cityflavour[flv]; buildings = &s_buildingList; int tries; for (tries=20; tries--; ) { const citybuilding_t &bt = buildings->buildings[rand.Int32(buildings->numBuildings)]; instIndex = bt.instIndex; modelRadXZ = bt.xzradius; cmesh = bt.collMesh.Get(); 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->GetSystemBody()->GetRadius() <= 0.0) return; cent = cent * height; Geom *geom = new Geom(cmesh->GetGeomTree()); 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 = { instIndex, float(cmesh->GetRadius()), rotTimes90, cent, geom }; m_buildings.push_back(def); } }