Esempio n. 1
0
void ArcTerrain::diamondSquare(int tL[], int tR[], int bL[], int bR[], int level)
{
  // PROBLEM: ACCESSING UNASSIGNED VALUES FOR AVERAGE
  //std::cout << "bR = " << bR[0] << ", " << bR[1] << std::endl;
  //std::cout << "bL = " << bL[0] << ", " << bL[1] << std::endl;
  // find average
  float average = (mMap[tL[0]][tL[1]] +
		   mMap[tR[0]][tR[1]] +
		   mMap[bL[0]][bL[1]] +
		   mMap[bR[0]][bR[1]]) / 4;
  // find midPoint
  int cX = (tL[0] + bR[0]) / 2;
  int cY = (tL[1] + bR[1]) / 2;
  int C[] = {cX, cY};


  mMap[cX][cY] = average + randomHeight(level--);
  if (mMap[cX][cY] > mMax) mMax = mMap[cX][cY];
  if (mMap[cX][cY] < mMin) mMin = mMap[cX][cY];
  int T[] = {cX, tL[1]};
  double tA = (mMap[tL[0]][tL[1]] + 
	       mMap[tR[0]][tR[1]] + 
	       mMap[cX][cY]) / 3;

  //std::cout << cX << ", " << bL[1] << std::endl;
  int B[] = {cX, bL[1]};
  double bA = (mMap[bL[0]][bL[1]] + 
	       mMap[bR[0]][bR[1]] + 
	       mMap[cX][cY]) / 3;

  int L[] = {tL[0], cY};
  double lA = (mMap[tL[0]][tL[1]] + 
	       mMap[bL[0]][bL[1]] + 
	       mMap[cX][cY]) / 3;

  int R[] = {tR[0], cY};
  double rA = (mMap[tR[0]][tR[1]] + 
	       mMap[bR[0]][bR[1]] + 
	       mMap[cX][cY]) / 3;
 
  // Set midpoint to average + random height
  mMap[T[0]][T[1]] = tA;
  mMap[B[0]][B[1]] = bA;
  mMap[L[0]][L[1]] = lA;
  mMap[R[0]][R[1]] = rA;
  //level--;

  if (level > 0)
  {
    diamondSquare(tL, T, L, C, level); // TL
    diamondSquare(T, tR, C, R, level); // TR
    diamondSquare(L, C, bL, B, level); // BL
    diamondSquare(C, R, B, bR, level); // BR
  }
}
Esempio n. 2
0
void ArcTerrain::square(int T[], int B[], int L[], int R[], int level)
{
  //std::cout << "Square " << level << ":\n";
  int num2Average = 4;
  float sum = 0;
  float average = 0;
  bool top = true, bottom = true, left = true, right = true;
  // Error Check / find average
  if (((T[0] >= 0) && (T[1] >= 0)) && 
      (((T[0] < mSize) && (T[1] < mSize)))) sum += mMap[T[0]][T[1]];
  else {num2Average--; top = false;}
  if (((B[0] >= 0) && (B[1] >= 0)) && 
      (((B[0] < mSize) && (B[1] < mSize)))) sum += mMap[B[0]][B[1]];
  else {num2Average--; bottom = false;}
  if (((R[0] >= 0) && (R[1] >= 0)) && 
      (((R[0] < mSize) && (R[1] < mSize)))) sum += mMap[R[0]][R[1]];
  else {num2Average--; right = false;}
  if (((L[0] >= 0) && (L[1] >= 0)) && 
      (((L[0] < mSize) && (L[1] < mSize)))) sum += mMap[L[0]][L[1]];
  else {num2Average--; left = false;}
  if (num2Average != 0) average = sum / num2Average;
  //std::cout << average << " ";
  // Find midpoint
  int midX = T[0];
  int midY = L[1];
  // Set midpoint to average + random height
  mMap[midX][midY] = average+ randomHeight(level--);
  if (mMap[midX][midY] > mMax) mMax = mMap[midX][midY];
  if (mMap[midX][midY] < mMin) mMin = mMap[midX][midY];
  //level--;
  if (level > 0)
  {
    // find corners
    int mid[2] = {midX, midY};
    int tL[2] = {L[0], T[1]};
    int tR[2] = {R[0], T[1]};
    int bL[2] = {L[0], B[1]};
    int bR[2] = {R[0], B[1]};

    // diamond each quadrant if they exist
    if (top && left)     {diamond(tL, T, L, mid, level);}
    if (top && right)    {diamond(T, tR, mid, R, level);}
    if (bottom && left)  {diamond(L, mid, bL, B, level);}
    if (bottom && right) {diamond(mid, R, B, bR, level);}
  }
}
Esempio n. 3
0
void ArcTerrain::diamond(int tL[], int tR[], int bL[], int bR[], int level)
{
  //std::cout << "Diamond level " << level << ":\n";
  // find average
  float average = (mMap[tL[0]][tL[1]] +
		   mMap[tR[0]][tR[1]] +
		   mMap[bL[0]][bL[1]] +
		   mMap[bR[0]][bR[1]]) / 4;
  //std::cout << average << " ";
  // find midPoint
  int midX = (tL[0] + bR[0]) / 2;
  int midY = (tL[1] + bR[1]) / 2;
  
  // Set midpoint to average + random height
  mMap[midX][midY] = average + randomHeight(level--);
  if (mMap[midX][midY] > mMax) mMax = mMap[midX][midY];
  if (mMap[midX][midY] < mMin) mMin = mMap[midX][midY];
  //level--;
  if (level > 0)
  {
    // Find Diamonds
    int leftX   = 2 * tL[0] - midX;
    int rightX  = 2 * tR[0] - midX;
    int topY    = 2 * tL[1] - midY;
    int bottomY = 2 * bL[1] - midY;

    int left   [2] = {leftX ,  midY};
    int right  [2] = {rightX,  midY};
    int top    [2] = {midX,    topY};
    int bottom [2] = {midX, bottomY};
    int mid    [2] = {midX,    midY};

    // Square diamonds
    square(top, mid, tL, tR,    level); // top diamond
    square(mid, bottom, bL, bR, level); // bottom diamond
    square(tL, bL, left, mid,   level); // left diamond
    square(tR, bR, mid,  right, level); // right diamond
  }
}
Esempio n. 4
0
// creates a random, fractal heightfield
static void
setFractal
(
byte_t * grid,
int bytesPerElement,
PHY_ScalarType type,
int step
)
{
	btAssert(grid);
	btAssert(bytesPerElement > 0);
	btAssert(step > 0);
	btAssert(step < s_gridSize);

	int newStep = step / 2;
//	std::cerr << "Computing grid with step = " << step << ": before\n";
//	dumpGrid(grid, bytesPerElement, type, step + 1);

	// special case: starting (must set four corners)
	if (s_gridSize - 1 == step) {
		// pick a non-zero (possibly negative) base elevation for testing
		float base = randomHeight(step / 2);

		convertFromFloat(grid, base, type);
		convertFromFloat(grid + step * bytesPerElement, base, type);
		convertFromFloat(grid + step * s_gridSize * bytesPerElement, base, type);
		convertFromFloat(grid + (step * s_gridSize + step) * bytesPerElement, base, type);
	}

	// determine elevation of each corner
	float c00 = convertToFloat(grid, type);
	float c01 = convertToFloat(grid + step * bytesPerElement, type);
	float c10 = convertToFloat(grid + (step * s_gridSize) * bytesPerElement, type);
	float c11 = convertToFloat(grid + (step * s_gridSize + step) * bytesPerElement, type);

	// set top middle
	updateHeight(grid + newStep * bytesPerElement, 0.5 * (c00 + c01) + randomHeight(step), type);

	// set left middle
	updateHeight(grid + (newStep * s_gridSize) * bytesPerElement, 0.5 * (c00 + c10) + randomHeight(step), type);

	// set right middle
	updateHeight(grid + (newStep * s_gridSize + step) * bytesPerElement, 0.5 * (c01 + c11) + randomHeight(step), type);

	// set bottom middle
	updateHeight(grid + (step * s_gridSize + newStep) * bytesPerElement, 0.5 * (c10 + c11) + randomHeight(step), type);

	// set middle
	updateHeight(grid + (newStep * s_gridSize + newStep) * bytesPerElement, 0.25 * (c00 + c01 + c10 + c11) + randomHeight(step), type);

//	std::cerr << "Computing grid with step = " << step << ": after\n";
//	dumpGrid(grid, bytesPerElement, type, step + 1);

	// terminate?
	if (newStep < 2) {
		return;
	}

	// recurse
	setFractal(grid, bytesPerElement, type, newStep);
	setFractal(grid + newStep * bytesPerElement, bytesPerElement, type, newStep);
	setFractal(grid + (newStep * s_gridSize) * bytesPerElement, bytesPerElement, type, newStep);
	setFractal(grid + ((newStep * s_gridSize) + newStep) * bytesPerElement, bytesPerElement, type, newStep);
}