// ---This function generates the standard 3D Poisson Disk Sampling Pattern--- /////////////////////////////////////////////////////////////////////////////// short int VDSamplingUpper::genPoissonSampling(VariableDensity *vd) { float fillvalue = vd->getFillvalue(); // indicate if a suitable mask was found and show the reason min_dist_status = 0; // parameters to compute a new point Point newPoint; long newGridPos[2]; float newRealPos[2]; long *newGridPosPtr; Point actualPoint; long *actGridPosPtr; float *actRealPosPtr; float radius; float angle; bool tooClose = true; int nextIndex = 0; // next index of active_list bool found = false; // reininitialise the grids, lists and the sampling mask anchor = 0; nElements = 0; for(long i=0; i<height; i++) { for(long j=0; j<width; j++) { if ((vd->getFraction()[i][j] != -1) && (vd->getFraction()[i][j] != -3)) { grid[i][j] = noPoint; samplingMask[i][j] = 0; grid2[i][j] = 0; } if (vd->getFraction()[i][j] == -3) // border point { Point actualPoint = grid[i][j]; filledCircle(actualPoint, vd); savePointInActList(actualPoint); } } } nSamplingMaskPoints = nSamplingMaskPointsHelper; // first point /////////////// if (nElements == 0) { bool found_first_point = false; // create fix first sampling point to the center (not really center if height or width even!) if(flag_first) { // find first point newGridPos[0] = long(ceil(float(height)/2)-1); newGridPos[1] = long(ceil(float(width)/2)-1); // set first point, if partial fourier allows it if((newGridPos[0] >= pF_border[0]) && (newGridPos[1] >= pF_border[1])) { newPoint.setGridPos(newGridPos); newRealPos[0] = float(newGridPos[0])+0.5; newRealPos[1] = float(newGridPos[1])+0.5; newPoint.setRealPos(newRealPos); // save the first point savePoint(newPoint, vd); found_first_point = true; } } // create random first sampling point while(found_first_point == false) { // find the first point newRealPos[0] = float(height) * SomeFunctions::randZeroOne(); // was wenn randZeroOne = 1? newRealPos[1] = float(width) * SomeFunctions::randZeroOne(); newPoint.setRealPos(newRealPos); newPoint.pointFloatToLong(); newGridPosPtr = newPoint.getGridPos(); // set first point, if partial fourier allows it if ((newGridPosPtr[0] >= pF_border[0]) && (newGridPosPtr[1] >= pF_border[1]) && vd->getFraction()[newGridPosPtr[0]][newGridPosPtr[1]] != -2) { // save the first point savePoint(newPoint, vd); found_first_point = true; } } } //cout << "nElements = " << nElements << endl; cout << "."; // remaining points //////////////////// while( float(nSamplingMaskPoints)/float(nPointsToCreate) < (2.0 - deviation) ) { found = false; if(nElements == 0) { min_dist_status = 2; // min_dist too large break; } else { // take a random element of the active list nextIndex = long(floor(0.5 + SomeFunctions::randZeroOne() * float(nElements-1))); actualPoint = LinkedList::showElement(nextIndex, anchor, nElements); } // randomly generate a new point around the active one allowed region // lies between minimal distance (for this voxel) and twice minimal distance for(int i = 0; i<nPointsToTest; i++) { actGridPosPtr = actualPoint.getGridPos(); actRealPosPtr = actualPoint.getRealPos(); // random radius depending on fraction if (vd->getFraction()[actGridPosPtr[0]][actGridPosPtr[1]] == -3) { radius = fillvalue * min_dist * (1 + SomeFunctions::randZeroOne()); } else radius = vd->getFraction()[actGridPosPtr[0]][actGridPosPtr[1]] * min_dist * ( 1 + SomeFunctions::randZeroOne() ); if (radius < 1) // avoids setting no point near a point with low values of fraction radius = 1; // random angle between 0..2pi angle = 2 * float(PI) * SomeFunctions::randZeroOne(); // set position of the new point newRealPos[0] = actRealPosPtr[0] + radius * sin(angle); newRealPos[1] = actRealPosPtr[1] + radius * cos(angle); newPoint.setRealPos(newRealPos); // check if the point is in the grid and not inside the partial fourier region if ((newRealPos[0] >= pF_border[0]) && (newRealPos[1] >= pF_border[1]) && (newRealPos[0] < height) && (newRealPos[1] < width) && vd->getFraction()[long(newRealPos[0])][long(newRealPos[1])] != -2) { newPoint.pointFloatToLong(); newGridPosPtr = newPoint.getGridPos(); // check if there is already a point or a point disk if ( (grid[newGridPosPtr[0]][newGridPosPtr[1]].getIsPoint() == true) || (grid2[newGridPosPtr[0]][newGridPosPtr[1]] == 1)) continue; // check if the newPoint is too close to other points checkNeighbourhood( newPoint, tooClose, vd ); if ( !tooClose ) { found = true; savePoint(newPoint,vd); } } } // remove actualPoint from active_list if ( /*!found &&*/ (nElements != 0) ) { LinkedList::deleteElement(nextIndex, anchor, nElements); } } // Postproc step ////////////////// // check if the number of generated points is in the deviation-range //if( (nElements == 0) && !(min_dist_status == 3) && ( float(nSamplingMaskPoints)/float(nPointsToCreate) >= deviation ) && ( float(nSamplingMaskPoints)/float(nPointsToCreate) <= (2-deviation) ) ) //{ // min_dist_status = 3; // cout << "...best approx found!!" << endl << endl; //} return min_dist_status; }
void VDSamplingUpper::savePointToGrids(Point p, VariableDensity *vd) { long *gridPos = p.getGridPos(); grid[gridPos[0]][gridPos[1]] = p; filledCircle(p, vd); // fill grid2 with point and circle around it }
void generate_terrarium() { game.map.resize(128,128); torch.buf.resize(128,128); s16 cx = torch.buf.getw()/2, cy = torch.buf.geth()/2; torch.buf.reset(); torch.buf.cache.reset(); game.map.reset(); // glass on the rim filledCircle(cx, cy, 60, set_tile_i, (void*)GROUND); hollowCircle(cx, cy, 60, set_tile_i, (void*)GLASS); AddStars(); u32 timerVal; printf("Growing trees... "); startTimer(); CATrees(); timerVal = stopTimer(); printf("done (%.2fs).\n", timerVal*1024/33.513982e6); printf("Filling lakes... "); startTimer(); CALakes(); timerVal = stopTimer(); printf("done (%.2fs).\n", timerVal*1024/33.513982e6); printf("Buying shrubberies... "); startTimer(); AddGrass(); timerVal = stopTimer(); printf("done (%.2fs).\n", timerVal*1024/33.513982e6); printf("Checking connectivity... "); if (checkConnected()) { printf("connected.\n"); } else { printf("\1\x1f\x01unconnected\2.\n"); } printf("Simulating inhabitation... "); Inhabit(); printf("done.\n"); printf("Spawning creatures... "); SpawnCreatures(); printf("done.\n"); printf("Dropping items... "); for (int i = 0; i < 60; i++) { s16 x = rand32() % torch.buf.getw(), y = rand32() % torch.buf.geth(); if (!game.map.solid(x,y)) { Object *on = new Object(ROCK); stack_item_push(game.map.at(x,y)->objects, on); } else i--; } printf("done.\n"); s16 x = cx, y = cy; while (!game.map.walkable(x, y)) randwalk(x, y); game.player.x = x; game.player.y = y; game.player.setPos(x,y); game.map.at(x,y)->creature = &game.player; Object *on = new Object(BATON); stack_item_push(game.map.at(x,y)->objects, on); on = new Object(LEATHER_JACKET); stack_item_push(game.map.at(x,y)->objects, on); on = new Object(PAIR_OF_BLUNDSTONE_BOOTS); stack_item_push(game.map.at(x,y)->objects, on); x = cx; y = cy; set_tile(cx+40, cy, FIRE); lightsource *li = new lightsource; li->set(9<<12, (int)(0.1*(1<<12)), (int)(1.0*(1<<12)), (int)(0.1*(1<<12))); li->orig_intensity = li->intensity = 1<<11; li->x = (cx+40)<<12; li->y = cy<<12; li->flicker = FLICKER_RADIUS; game.map.lights.push(li); set_tile(cx+30, cy, FIRE); li = new lightsource; li->set(9<<12, (int)(1.0*(1<<12)), (int)(0.1*(1<<12)), (int)(0.1*(1<<12))); li->orig_intensity = li->intensity = 1<<11; li->x = (cx+30)<<12; li->y = cy<<12; li->flicker = FLICKER_RADIUS; game.map.lights.push(li); set_tile(cx+35, cy-7, FIRE); li = new lightsource; li->set(9<<12, (int)(0.1*(1<<12)), (int)(0.1*(1<<12)), (int)(1.0*(1<<12))); li->orig_intensity = li->intensity = 1<<11; li->x = (cx+35)<<12; li->y = (cy-7)<<12; li->flicker = FLICKER_RADIUS; game.map.lights.push(li); game.map.block.refresh_blocked_from(); torch.dirty_screen(); torch.reset_luminance(); }