1 package tim.prune.threedee;
3 public class TerrainPatch
5 private int _gridSize = 0;
6 private double[] _altitudes = null;
7 private int[] _tempDists = null;
11 * @param inGridSize size of grid edge
13 public TerrainPatch(int inGridSize)
15 _gridSize = inGridSize;
16 int numNodes = inGridSize * inGridSize;
17 _altitudes = new double[numNodes];
18 _tempDists = new int[numNodes];
22 * Add an altitude interpolation to the mix
23 * @param inPointIndex point index to array
24 * @param inValue altitude value in metres
25 * @param inGapIndex index of point within gap, from 1 to gapLength-1
26 * @param inGapLength length of gap, minimum 2
28 public void addAltitude(int inPointIndex, double inValue, int inGapIndex, int inGapLength)
30 final int dist = Math.min(inGapIndex, inGapLength-inGapIndex);
31 if (_tempDists[inPointIndex] == 0)
33 if (_altitudes[inPointIndex] > 0.0) System.err.println("Altitude shouldn't be 0 if dist is 0!");
35 _altitudes[inPointIndex] = inValue;
36 _tempDists[inPointIndex] = dist;
41 final double firstValue = _altitudes[inPointIndex];
42 final int firstDist = _tempDists[inPointIndex];
43 final double firstWeight = dist * 1.0 / (dist + firstDist);
44 final double secondWeight= firstDist * 1.0 / (dist + firstDist);
45 _altitudes[inPointIndex] = firstWeight * firstValue + secondWeight * inValue;
46 _tempDists[inPointIndex] = 0;
51 * Smooth the patch to reduce blockiness
55 double[] altCopy = new double[_altitudes.length];
56 for (int i=0; i<_gridSize; i++)
58 for (int j=0; j<_gridSize; j++)
60 if (hasAltitude(i, j) && hasAltitude(i-1, j) && hasAltitude(i+1, j)
61 && hasAltitude(i, j+1) && hasAltitude(i-1, j+1) && hasAltitude(i+1, j+1)
62 && hasAltitude(i, j-1) && hasAltitude(i-1, j-1) && hasAltitude(i+1, j-1))
64 // got a 3x3 square, can do a blur
65 double alt = (getAltitude(i, j) + getAltitude(i-1, j) + getAltitude(i+1, j)
66 + getAltitude(i, j+1) + getAltitude(i-1, j+1) + getAltitude(i+1, j+1)
67 + getAltitude(i, j-1) + getAltitude(i-1, j-1) + getAltitude(i+1, j-1)) / 9.0;
68 altCopy[i * _gridSize + j] = alt;
73 for (int k=0; k<altCopy.length; k++)
77 _altitudes[k] = altCopy[k];
83 * @param inI first index
84 * @param inJ second index
85 * @return true if there is an altitude in the patch in this position
87 private boolean hasAltitude(int inI, int inJ)
89 return inI >= 0 && inI < _gridSize && inJ >= 0 && inJ < _gridSize
90 && _altitudes[inI * _gridSize + inJ] > 0.0;
94 * @param inI first index
95 * @param inJ second index
96 * @return true if there is an altitude in the patch in this position
98 private double getAltitude(int inI, int inJ)
100 if (inI >= 0 && inI < _gridSize && inJ >= 0 && inJ < _gridSize)
102 return _altitudes[inI * _gridSize + inJ];
108 * @param inPointIndex point index
109 * @return altitude value
111 public double getAltitude(int inPointIndex)
113 if (_tempDists[inPointIndex] != 0) System.err.println("Dists should be 0 if we're retrieving!");
114 return _altitudes[inPointIndex];