float randNormal() { static float y1, y2; // This generates 2 numbers at a time, so // alternate between generating a new one and // just returning the last one static bool doGen = true; if (!doGen) { // return the other number we generated // last time return y2; } else { float x1, x2, w; // reject points outside the unit circle do { x1 = (2.0f * randUniform()) - 1.0; x2 = (2.0f * randUniform()) - 1.0; w = x1*x1 + x2*x2; } while (w >= 1.0 ); w = sqrt( (-2.0 * logf(w)) / w ); y1 = x1 * w; y2 = x2 * w; return y1; } }
static void doLoop(bool warmup, int pgm, uint32_t passCount) { if (warmup) { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); ptSwap(); glFinish(); return; } startTimer(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); for (uint32_t ct=0; ct < passCount; ct++) { int loc = glGetUniformLocation(pgm, "u_texOff"); glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount); randUniform(pgm, "u_color"); randUniform(pgm, "u_0"); randUniform(pgm, "u_1"); randUniform(pgm, "u_2"); randUniform(pgm, "u_3"); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } ptSwap(); glFinish(); endTimer(passCount); }
double nucmath::getRandom(double start, double end) { #ifdef __MINGW32__ return start + static_cast<double>(rand()) / static_cast<float>(RAND_MAX / (end - start)); #else std::uniform_real_distribution<double> randUniform(0.0, 1.0); return start + randUniform(rnd2)*abs(end - start); #endif }
void VoxSprite::chooseRandomDir() { int d = int( randUniform() * 5.0 ); m_angle = d * 90.0; m_timeout = randNormal( 4.0, 1.0 ); }
void ParticleBuff::emitRadial( ParticleType ptype, float x, float y, float radius ) { Particle *p = emitPart( ptype ); if (!p) return; // Buff full // set up general stuff const float initialVel = 50.0; p->x = x + randNormal() * radius; p->y = y + randNormal() * radius; p->maxAge = 3.0 + randNormal(); if ((ptype==Particle_RIPPLE) || (ptype==Particle_SMOKE)) { p->angle = 0.0; p->dx = 0.0; p->dy = 0.0; } else if (ptype == Particle_DOT) { p->dx = randNormal() * initialVel; p->dy = (1.0+randNormal()) * initialVel; } else { p->angle = randUniform() * 360.0; p->dx = randNormal() * initialVel; p->dy = randNormal() * initialVel; } p->age = 0; }
void Facility::dynamics(double beta, int timeStep) { double probability = 1 - pow(1 - beta, countInf()); std::vector<double> probs = { probability, (1 - probability) }; for (Agent* a : agents) { if ((*a).getState() == 0) { //sus to exp if (randProb(probs) == 0) { (*a).setState(1); } } else if ((*a).getState() == 1) { //exp to inf if ((*a).getEI() == -1) { if (inc_dist == 1 || inc_dist == 0) { //uniform or single value (*a).setEI(timeStep + ceil(randUniform()*(upper_inc - lower_inc)) + lower_inc); } else if (inc_dist == 2) { //triangular (*a).setEI(timeStep + ceil(randTriangle()*(upper_inc - lower_inc)) + lower_inc); } } else if (timeStep == (*a).getEI()) { (*a).setState(2); (*a).setEI(-1); } } else if ((*a).getState() == 2) { //inf to sus if ((*a).getIS() == -1) { if (inf_dist == 1 || inf_dist == 0) { //uniform or single value (*a).setIS(timeStep + ceil(randUniform()*(upper_inf - lower_inf)) + lower_inf); } else if (inf_dist == 2) { //triangular (*a).setIS(timeStep + ceil(randTriangle()*(upper_inf - lower_inf)) + lower_inf); } } else if (timeStep == (*a).getIS()) { (*a).setState(0); (*a).setIS(-1); } } } }
void Facility::reset() { agents.clear(); //reinitialize agents for (int i = 0; i < startS; i++) { Agent * a = new Agent(); (*a).setState(0); (*a).setEI(-1); (*a).setIS(-1); (*a).setDischarge(LOS()); (*a).setFacility(facility); agents.push_back(a); } for (int i = 0; i < startE; i++) { Agent * a = new Agent(); (*a).setState(1); if (inc_dist == 1 || inc_dist == 0) { //uniform or single value (*a).setEI(ceil(randUniform()*(upper_inc - lower_inc)) + lower_inc); } else if (inc_dist == 2) { //triangular (*a).setEI(ceil(randTriangle()*(upper_inc - lower_inc)) + lower_inc); } (*a).setIS(-1); (*a).setDischarge(LOS()); (*a).setFacility(facility); agents.push_back(a); } for (int i = 0; i < startI; i++) { Agent * a = new Agent(); (*a).setState(2); (*a).setEI(-1); if (inf_dist == 1 || inf_dist == 0) { //uniform or single value (*a).setIS(ceil(randUniform()*(upper_inf - lower_inf)) + lower_inf); } else if (inf_dist == 2) { //triangular (*a).setIS(ceil(randTriangle()*(upper_inf - lower_inf)) + lower_inf); } (*a).setDischarge(LOS()); (*a).setFacility(facility); agents.push_back(a); } }
int Facility::randProb(std::vector<double> probs) { double currProb = probs[0]; double rand = randUniform(); for (int i = 0; i<(probs.size() - 1); i++) { if (rand<currProb) { return i; //return index of drawn probability } currProb = currProb + probs[i + 1]; } return probs.size() - 1; }
void ParticleBuff::emitRadial( ParticleType ptype, float x, float y, float radius ) { Particle *p = emitPart( ptype ); if (!p) return; // Buff full // set up general stuff const float initialVel = 50.0; p->x = x + randNormal() * radius; p->y = y + randNormal() * radius; p->maxAge = 3.0 + randNormal(); //p->r = 1.0; p->g = 1.0; p->b = 1.0; float t = randUniform(); float rA = 166/255.0; float gA = 202/255.0; float bA = 222/255.0; float rB = 31/255.0; float gB = 45/255.0; float bB = 227/255.0; p->r = (rA*t) + (rB*(1.0-t)); p->g = (gA*t) + (gB*(1.0-t)); p->b = (bA*t) + (bB*(1.0-t)); if ((ptype==Particle_RING) || (ptype==Particle_SMOKE)) { p->angle = randUniform( 0.0, 360.0); p->dx = 0.0; p->dy = 0.0; } else if (ptype == Particle_DOT) { p->dx = randNormal() * initialVel; p->dy = (1.0+randNormal()) * initialVel; } else { p->angle = randUniform() * 360.0; p->dx = randNormal() * initialVel; p->dy = randNormal() * initialVel; } p->age = 0; }
Facility::Facility(int facil, std::string in, boost::variate_generator< boost::mt19937&, boost::random::triangle_distribution < > > * triangle, boost::variate_generator< boost::mt19937&, boost::random::uniform_real_distribution < > > * uniform, int incdist, double upinc, double lowinc, int infdist, double upinf, double lowinf) { facility = facil; std::string input[11]; int i = 0; std::stringstream ssin(in); while (ssin.good() && i < 11) { ssin >> input[i]; ++i; } name = input[0]; subfacil = stoi(input[1]); startS = stoi(input[2]); startE = stoi(input[3]); startI = stoi(input[4]); bed_size = stoi(input[5]); prev = stod(input[6]); inc = stod(input[7]); LOS_mean = stod(input[8]); LOS_dev = stod(input[9]); LOS_dist = stoi(input[10]); RNGpoint = uniform; triangleRNGpoint = triangle; genpoint = new boost::mt19937 (time(0)); //create RNG boost::random::lognormal_distribution< > lognormalDistribution(LOS_mean, LOS_dev); boost::random::normal_distribution< > normalDistribution(LOS_mean, LOS_dev); lognormRNGpoint = new boost::variate_generator< boost::mt19937&, boost::random::lognormal_distribution < > >(*genpoint, lognormalDistribution); normalRNGpoint = new boost::variate_generator< boost::mt19937&, boost::random::normal_distribution < > >(*genpoint, normalDistribution); inf_dist = infdist; inc_dist = incdist; lower_inf = lowinf; upper_inf = upinf; lower_inc = lowinc; upper_inc = upinc; //initialize agents for (int i = 0; i < startS; i++) { Agent * a = new Agent(); (*a).setState(0); (*a).setEI(-1); (*a).setIS(-1); (*a).setDischarge(LOS()); (*a).setFacility(facility); agents.push_back(a); } for (int i = 0; i < startE; i++) { Agent * a = new Agent(); (*a).setState(1); if (inc_dist == 1 || inc_dist == 0) { //uniform or single value (*a).setEI(ceil(randUniform()*(upper_inc - lower_inc)) + lower_inc); } else if (inc_dist == 2) { //triangular (*a).setEI(ceil(randTriangle()*(upper_inc - lower_inc)) + lower_inc); } (*a).setIS(-1); (*a).setDischarge(LOS()); (*a).setFacility(facility); agents.push_back(a); } for (int i = 0; i < startI; i++) { Agent * a = new Agent(); (*a).setState(2); (*a).setEI(-1); if (inf_dist == 1 || inf_dist == 0) { //uniform or single value (*a).setIS(ceil(randUniform()*(upper_inf - lower_inf)) + lower_inf); } else if (inf_dist == 2) { //triangular (*a).setIS(ceil(randTriangle()*(upper_inf - lower_inf)) + lower_inf); } (*a).setDischarge(LOS()); (*a).setFacility(facility); agents.push_back(a); } }
// fill up vertex buffer from part list void ParticleBuff::updateParts( float dt ) { for (size_t i=0; i < m_numParts; ++i) { Particle &p = m_parts[i]; float lasty = p.y; p.x = p.x + p.dx * dt; p.y = p.y + p.dy * dt; // Hack -- spawn a ripple if we cross the water surface if ((lasty >= 100) && (p.y <= 100)) { emitRadial( Particle_RIPPLE, p.x, p.y + randUniform( -3.0, 3.0), 0.0 ); p.age = p.maxAge; } // update age p.age += dt; float life = p.age / p.maxAge; switch (p.ptype) { case Particle_DOT: case Particle_DOT2: // Apply gravity p.dy = p.dy + (-100*dt); // update size p.sx = p.sy = 10.0 * (1.0 - life); break; case Particle_SMOKE: // grow and fade p.sx = 30.0 + 30 * life; p.sy = 30.0 + 30 * life; break; case Particle_RIPPLE: // grow and fade p.sx = 10.0 + 50 * life; p.sy = 10.0 + 50 * life; break; } } // kill off old particles for (int i = m_numParts-1; i >=0; i--) { // did this particle age out? if (m_parts[i].age > m_parts[i].maxAge) { // If this is not the last particle, // swap the last one into its place if (i<m_numParts-1) { m_parts[i] = m_parts[m_numParts-1]; } m_numParts--; } } }
void TestApp::SceneCollect::init() { // Set up luddite stuff luddite::RenderDeviceGL *renderDeviceGL = new luddite::RenderDeviceGL(); m_renderDevice = renderDeviceGL; // Setup camera (TODO: do this differently) glhPerspectivef2( renderDeviceGL->matProjection, 20.0, 800.0/600.0, 1.0, 500.0 ); matrix4x4f cameraXlate, cameraRot; cameraXlate.Translate(0.0, -4, -15.0); cameraRot.RotateX( 15.0 * (M_PI/180.0) ); renderDeviceGL->matBaseModelView = cameraXlate * cameraRot; // Initialize shader DB m_mtlDB = new luddite::MaterialDB( ); m_mtlDB->initShaderDB(); // Add material def files m_mtlDB->addMaterialDefs("CollectGame.material.xml" ); luddite::Material *mtl = m_mtlDB->getNamedMaterial( m_renderDevice, "mtl.environment" ); // Build scene graph m_worldRoot = new luddite::SceneNode( "worldRoot" ); // Load the ground plane obj file in the center. m_groundPlane = scene_objfile_named( "grid10x10.obj", m_renderDevice, m_mtlDB ); m_worldRoot->addChild( m_groundPlane ); // Load the player mesh m_player = scene_objfile_named( "player.obj", m_renderDevice, m_mtlDB ); m_worldRoot->addChild( m_player ); // Load the trees luddite::SceneNode *tree = scene_objfile_named("tree_fir.obj", m_renderDevice, m_mtlDB ); tree->m_pos = vec3f( 2.0, 0.0, 1.5 ); m_worldRoot->addChild( tree ); m_trees.push_back(tree); // Add tree instances for (int i=0; i <20; i++) { luddite::SceneNode *treeInst = tree->makeInstance(); // Generate a random position for the tree, outside the center of the // map (TODO: also don't overlap other trees) do { vec3f treePos = vec3f( randUniform(-10.0, 10.0), 0.0, randUniform(-10.0, 10.0) ); treeInst->m_pos = treePos; } while (prmath::LengthSquared(treeInst->m_pos) < 1.0 ); m_worldRoot->addChild( treeInst ); m_trees.push_back( treeInst ); } // FIXME.. this is temporary, shouldn't need to do this (and we shouldn't // upload all the shaders, only used ones) m_mtlDB->useAllShaders( m_renderDevice ); // Finally, create scene for our node graph m_scene = new luddite::Scene( m_worldRoot ); }
static void generate(const PARAMS *p,DATA *d) { double dTheta,dSpaceTheta,dSpaceZ,dDepth,dSpaceXY; int i,iR,iZ,iX,iY; randSeedGenerator(time(NULL) % getpid() + getppid()); i = 0; if (p->nStuck > 0) { printf("Generating %i stuck particle%s in %ix(%i/%i) grid.\n", p->nStuck,p->nStuck == 1 ? "" : "s", p->nStuckR,p->nStuckZ,p->nStuckZ > 1 ? p->nStuckZ - 1 : 1); dTheta = TWO_PI/p->nStuckR; printf("Stuck-particle cell dimensions: %g cm x %g cm (angular increment = %g deg).\n", 100.0*p->dStuckR*AU,100.0*p->dStuckZ*AU,dTheta*180.0/PI); for (iZ=0;iZ<p->nStuckZ;iZ++) for (iR=0;iR<p->nStuckR;iR++) { if (p->nStuckZ > 1 && iR % 2 == 1 && iZ == 0) continue; /* to stagger the grid */ do { d[i].radius = p->dStuckAvg + gaussian(p->dStuckDev,p->dCutoff); } while (d[i].radius <= 0.0); /* reject non-physical values */ dSpaceTheta = (p->dStuckR - 2.0*d[i].radius)/p->dCylRad; /* available longitudinal space in cell */ if (dSpaceTheta < 0.0) dSpaceTheta = 0.0; dSpaceZ = p->dStuckZ - 2.0*d[i].radius; /* available vertical space in cell */ if (dSpaceZ < 0.0) dSpaceZ = 0.0; dDepth = 2.0*(0.5 - (p->dDepthAvg + gaussian(p->dDepthDev,p->dCutoff)))*d[i].radius; d[i].pos[0] = (p->dCylRad - dDepth)*cos(dTheta*iR + (randUniform() - 0.5)*dSpaceTheta); d[i].pos[1] = (p->dCylRad - dDepth)*sin(dTheta*iR + (randUniform() - 0.5)*dSpaceTheta); d[i].pos[2] = -0.5*p->dCylLen + ((double) iZ + 0.5)*p->dStuckZ + (randUniform() - 0.5)*dSpaceZ - (p->nStuckZ > 1 ? (iR % 2)*0.5*p->dStuckZ : 0.0); ++i; } } assert(i == p->nStuck); if (p->nFree > 0) { printf("Generating %i free particle%s in %ix%ix%i grid.\n", p->nFree,p->nFree == 1 ? "" : "s", p->nFreeXY,p->nFreeXY,p->nFreeZ); printf("Free-particle cell dimensions: %g cm x %g cm x %g cm.\n", 100.0*p->dFreeXY*AU,100.0*p->dFreeXY*AU,100.0*p->dFreeZ*AU); for (iZ=0;iZ<p->nFreeZ;iZ++) for (iX=0;iX<p->nFreeXY;iX++) for (iY=0;iY<p->nFreeXY;iY++) { do { do { d[i].radius = p->dFreeAvg + gaussian(p->dFreeDev,p->dCutoff); } while (d[i].radius <= 0.0); dSpaceXY = (p->dFreeXY - 2.0*d[i].radius); /* available xy-space in cell */ } while (dSpaceXY <= 0.0); dSpaceZ = p->dFreeZ - 2.0*d[i].radius; /* available z-space in cell */ if (dSpaceZ < 0.0) dSpaceZ = 0.0; d[i].pos[0] = -sqrt(0.5)*p->dCylRad + ((double) iX + 0.5)*p->dFreeXY + (randUniform() - 0.5)*dSpaceXY; d[i].pos[1] = -sqrt(0.5)*p->dCylRad + ((double) iY + 0.5)*p->dFreeXY + (randUniform() - 0.5)*dSpaceXY; d[i].pos[2] = -0.5*p->dCylLen + ((double) iZ + 0.5)*p->dFreeZ + (randUniform() - 0.5)*dSpaceZ; ++i; } } assert(i == p->nPart); }
void Bonsai::buildAll() { // generate a unique random seed for the whole thing from the name DBG::info("Generate planet '%s'\n", m_name ); int master_seed = 1; for (const char *ch=m_name; *ch; ch++) { master_seed *= (*ch); } // generate random seeds for each step .. this keeps them // somewhat resistant to changes in the algoritms int pally_seed, param_seed, terrain_seed; srand( master_seed ); pally_seed = rand(); terrain_seed = rand(); param_seed = rand(); // Make the palette m_pally.generate( pally_seed ); // synthesize the height data m_hiteData = new float [ HITE_RES * HITE_RES ]; m_terrainColor = new GLubyte [ HITE_RES * HITE_RES * 3 ]; m_terrainNorm = new GLubyte [ HITE_RES * HITE_RES * 3 ]; // Set up params srand( param_seed ); m_params.offs = randUniform( 0.0, 1000.0 ); m_params.base = (int)randUniform( 0, NUM_BASE ); m_params.base_distAmt = randUniform( 0.0, 0.3 ); m_params.base_scale = randUniform( 0.3, 1.0 ); m_params.baseVeg = (int)randUniform( 0, NUM_BASEVEG ); m_params.baseVeg_hite_repeats = (int)randUniform( 1, 5 ); m_params.baseVeg_hite_repeats *= m_params.baseVeg_hite_repeats; m_params.patchVeg = (int)randUniform( 0, NUM_PATCHVEG ); m_params.patchVeg_scale = randUniform( 1.0, 20.0 ); m_params.patchVeg_nscale = randUniform( 0.01, 8.0 ); m_params.patchVeg_nscale *= m_params.patchVeg_nscale; m_params.patchMixMineral = (randUniform() > 0.5)?1:0; m_params.patchVeg_thresh = randUniform( 0.55, 0.85 ); // Decoration m_params.deco = (int)randUniform( 0, NUM_DECORATION ); m_params.decoLavaScale = randUniform( 1.0, 10.0 ); m_params.decoLavaWidth = randUniform( 0.01, 0.1 ); // ============================================= // build textures Luddite::HTexture htexColor; Luddite::HTexture htexNorms; // check if there is cached image data available htexColor = _checkCachedColorImage( "DIF0", m_terrainColor, HITE_RES); if ( (!htexColor.isNull() ) && (_checkCachedHeight( "HITE", m_hiteData, HITE_RES ) )) { DBG::info( "Land '%s' read cached color and height.\n", m_name ); } else { // Synthesize srand( terrain_seed ); // step for tuning/debugging quicker // step=1 for final quality int step = SYNTH_STEP; for (int j=0; j < HITE_RES; j += step) { // status progress( "Generating", j, HITE_RES ); for (int i=0; i < HITE_RES; i += step ) { float ii = (((float)i / (float)HITE_RES) * 2.0) - 1.0; float jj = (((float)j / (float)HITE_RES) * 2.0) - 1.0; // synthesize a texel size_t ndx = (j*HITE_RES)+i; synthesize( ndx, ii, jj ); for (int sj = 0; sj < step; sj++) { for(int si=0; si < step; si++) { if (si || sj) { size_t ndx2 = ((j+sj)*HITE_RES)+(i+si); m_terrainColor[ndx2 * 3 + 0] = m_terrainColor[ndx * 3 + 0]; m_terrainColor[ndx2 * 3 + 1] = m_terrainColor[ndx * 3 + 1]; m_terrainColor[ndx2 * 3 + 2] = m_terrainColor[ndx * 3 + 2]; m_hiteData[ndx2] = m_hiteData[ndx]; } } } } } // Calculate (fake) ambient occlusion for (int j=0; j < HITE_RES; j += 1) { progress( "AmbOccl", j, HITE_RES ); for (int i=0; i < HITE_RES; i += 1 ) { float ambOccl = 0.0f; int c = 0; size_t ndx = (j*HITE_RES)+i; // TODO: gaussian weight for (int ii=-8; ii < 8; ii += 2) { for (int jj=-8; jj < 8; jj += 2) { int i2 = i+ii; int j2 = j+jj; c += 1; float occl = 0.0; if ((i2 >=0) && (i2 < HITE_RES) && (j2 >=0) && (j2 < HITE_RES) ) { size_t ndx2 = (j2*HITE_RES)+i2; occl = m_hiteData[ndx2] - m_hiteData[ndx]; occl = fstep( 0.0, 0.015, occl ); ambOccl += occl; } } } // avg ambOccl /= c; ambOccl = clamp( 1.0-ambOccl, 0.0, 1.0 ); // darken color image (dbg replace) #if 0 m_terrainColor[ndx * 3 + 0] = (int)(ambOccl * 255); m_terrainColor[ndx * 3 + 1] = (int)(ambOccl * 255); m_terrainColor[ndx * 3 + 2] = (int)(ambOccl * 255); #else m_terrainColor[ndx * 3 + 0] *= ambOccl; m_terrainColor[ndx * 3 + 1] *= ambOccl; m_terrainColor[ndx * 3 + 2] *= ambOccl; #endif } } // Cache the height & color data SDL_WM_SetCaption( "[Cache Height/Color] LD19 Jovoc - Discovery", NULL ); _cacheColorImage( "DIF0", m_terrainColor, HITE_RES ); _cacheHeight( "HITE", m_hiteData, HITE_RES ); } // check if there is cached normal data available htexNorms = _checkCachedColorImage( "NRM", m_terrainNorm, HITE_RES); if ( !htexNorms.isNull() ) { DBG::info( "Land '%s' read cached normals.\n", m_name ); } else { // Shitty calc normals -- ideally this should use the // height samples to not soften it but for now do it this // way cause it's easier/faster for (int j=0; j < HITE_RES-1; j++) { progress( "Calc Normals", j, HITE_RES ); for (int i=0; i < HITE_RES-1; i++ ) { PVRTVec3 nrm; size_t ndx = (j*HITE_RES)+i; float a = m_hiteData[ndx]; float b = m_hiteData[ (j*HITE_RES)+(i+1) ]; float c = m_hiteData[ ((j+1)*HITE_RES)+i ]; //float scl = 5.4; float scl = 50.0f; float dy1 = (b - a) * scl; float dy2 = (c - a) * scl; PVRTVec3 n( dy1, dy2, 1.0 - sqrt( dy1*dy1 + dy2*dy2 ) ); n.normalize(); m_terrainNorm[ndx * 3 + 0] = (int)((n.x * 128.0) + 128.0); m_terrainNorm[ndx * 3 + 1] = (int)((n.y * 128.0) + 128.0); m_terrainNorm[ndx * 3 + 2] = (int)((n.z * 128.0) + 128.0); } } // Cache the normal map SDL_WM_SetCaption( "[Cache Normals] LD19 Jovoc - Discovery", NULL ); _cacheColorImage( "NRM", m_terrainNorm, HITE_RES ); } SDL_WM_SetCaption( "LD19 Jovoc - Discovery [Press TAB to ungrab mouse]", NULL ); // Build texture static int treeId = 0; Luddite::TextureDB *texDB = Luddite::TextureDB::singletonPtr(); if (htexColor.isNull()) { char s[20]; sprintf( s, "treeland%d", treeId++); htexColor = texDB->buildTextureFromData( s, m_terrainColor, 1024, 1024 ); } if (htexNorms.isNull()) { char s[20]; sprintf( s, "treenorms%d", treeId++); htexNorms = texDB->buildTextureFromData( s, m_terrainNorm, 1024, 1024 ); } // Make a land part m_treeLand = new TreeLand( m_hiteData, htexColor, htexNorms ); m_treeLand->build(); }
float randUniform( float minVal, float maxVal ) { return minVal + (randUniform() * (maxVal-minVal)); }