forked from MagicBane/Server
Prepare for terrain
This commit is contained in:
@@ -36,10 +36,7 @@ public class HeightMap {
|
|||||||
|
|
||||||
public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>();
|
public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>();
|
||||||
|
|
||||||
public static final HashMap<Integer, byte[][]> _pixelData = new HashMap<>();
|
public static final HashMap<Integer, short[][]> _pixelData = new HashMap<>();
|
||||||
|
|
||||||
// Heightmap data for all zones.
|
|
||||||
public static float SCALEVALUE = 1.0f / 255;
|
|
||||||
|
|
||||||
// Bootstrap Tracking
|
// Bootstrap Tracking
|
||||||
public static int heightMapsCreated = 0;
|
public static int heightMapsCreated = 0;
|
||||||
@@ -52,16 +49,17 @@ public class HeightMap {
|
|||||||
public final int fullExtentsY;
|
public final int fullExtentsY;
|
||||||
public final int zoneLoadID;
|
public final int zoneLoadID;
|
||||||
public BufferedImage heightmapImage;
|
public BufferedImage heightmapImage;
|
||||||
public float bucketWidthX;
|
public float cell_size_x;
|
||||||
public float bucketWidthY;
|
public float cell_size_y;
|
||||||
public float seaLevel = 0;
|
public float seaLevel = 0;
|
||||||
public int[][] pixelColorValues;
|
public short[][] pixelColorValues;
|
||||||
public int bucketCountX;
|
public int cell_count_x;
|
||||||
public int bucketCountY;
|
public int cell_count_y;
|
||||||
|
|
||||||
public float zone_minBlend;
|
public float zone_minBlend;
|
||||||
public float zone_maxBlend;
|
public float zone_maxBlend;
|
||||||
|
|
||||||
|
public float terrain_scale;
|
||||||
|
|
||||||
public HeightMap(ResultSet rs) throws SQLException {
|
public HeightMap(ResultSet rs) throws SQLException {
|
||||||
|
|
||||||
this.heightMapID = rs.getInt("heightMapID");
|
this.heightMapID = rs.getInt("heightMapID");
|
||||||
@@ -97,11 +95,13 @@ public class HeightMap {
|
|||||||
|
|
||||||
// Calculate the data we do not load from table
|
// Calculate the data we do not load from table
|
||||||
|
|
||||||
bucketCountX = this.heightmapImage.getWidth() - 1;
|
this.cell_count_x = this.heightmapImage.getWidth() - 1;
|
||||||
this.bucketWidthX = this.fullExtentsX / (float) bucketCountX;
|
this.cell_size_x = this.fullExtentsX / (float) cell_count_x;
|
||||||
|
|
||||||
bucketCountY = this.heightmapImage.getHeight() - 1;
|
this.cell_count_y = this.heightmapImage.getHeight() - 1;
|
||||||
this.bucketWidthY = this.fullExtentsY / (float) bucketCountY;
|
this.cell_size_y = this.fullExtentsY / (float) cell_count_y;
|
||||||
|
|
||||||
|
this.terrain_scale = this.maxHeight / 255f;
|
||||||
|
|
||||||
// Generate pixel array from image data
|
// Generate pixel array from image data
|
||||||
|
|
||||||
@@ -133,10 +133,10 @@ public class HeightMap {
|
|||||||
|
|
||||||
// Calculate the data we do not load from table
|
// Calculate the data we do not load from table
|
||||||
|
|
||||||
this.bucketWidthX = halfExtentsX;
|
this.cell_size_x = halfExtentsX;
|
||||||
this.bucketWidthY = halfExtentsY;
|
this.cell_size_y = halfExtentsY;
|
||||||
|
|
||||||
this.pixelColorValues = new int[this.fullExtentsX][this.fullExtentsY];
|
this.pixelColorValues = new short[this.fullExtentsX][this.fullExtentsY];
|
||||||
|
|
||||||
for (int y = 0; y < this.fullExtentsY; y++) {
|
for (int y = 0; y < this.fullExtentsY; y++) {
|
||||||
for (int x = 0; x < this.fullExtentsX; x++) {
|
for (int x = 0; x < this.fullExtentsX; x++) {
|
||||||
@@ -144,8 +144,9 @@ public class HeightMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketCountX = this.pixelColorValues.length - 1;
|
cell_count_x = this.pixelColorValues.length - 1;
|
||||||
bucketCountY = this.pixelColorValues[0].length - 1;
|
cell_count_y = this.pixelColorValues[0].length - 1;
|
||||||
|
this.terrain_scale = this.maxHeight / 255f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeightMap(Zone zone) {
|
public HeightMap(Zone zone) {
|
||||||
@@ -166,10 +167,10 @@ public class HeightMap {
|
|||||||
|
|
||||||
// Calculate the data we do not load from table
|
// Calculate the data we do not load from table
|
||||||
|
|
||||||
this.bucketWidthX = halfExtentsX;
|
this.cell_size_x = halfExtentsX;
|
||||||
this.bucketWidthY = halfExtentsY;
|
this.cell_size_y = halfExtentsY;
|
||||||
|
|
||||||
this.pixelColorValues = new int[this.fullExtentsX][this.fullExtentsY];
|
this.pixelColorValues = new short[this.fullExtentsX][this.fullExtentsY];
|
||||||
|
|
||||||
for (int y = 0; y < this.fullExtentsY; y++) {
|
for (int y = 0; y < this.fullExtentsY; y++) {
|
||||||
for (int x = 0; x < this.fullExtentsX; x++) {
|
for (int x = 0; x < this.fullExtentsX; x++) {
|
||||||
@@ -177,8 +178,9 @@ public class HeightMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketCountX = this.pixelColorValues.length - 1;
|
cell_count_x = this.pixelColorValues.length - 1;
|
||||||
bucketCountY = this.pixelColorValues[0].length - 1;
|
cell_count_y = this.pixelColorValues[0].length - 1;
|
||||||
|
this.terrain_scale = this.maxHeight / 255f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GeneratePlayerCityHeightMap() {
|
public static void GeneratePlayerCityHeightMap() {
|
||||||
@@ -239,13 +241,13 @@ public class HeightMap {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static float getWorldHeight(Vector3fImmutable worldLoc) {
|
public static float getWorldHeight(Vector3fImmutable worldLoc) {
|
||||||
|
|
||||||
Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
|
Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
|
||||||
|
|
||||||
if (currentZone == null)
|
if (currentZone == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return getWorldHeight(currentZone, worldLoc);
|
return getWorldHeight(currentZone, worldLoc);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -260,12 +262,6 @@ public class HeightMap {
|
|||||||
|
|
||||||
HeightMap.GeneratePlayerCityHeightMap();
|
HeightMap.GeneratePlayerCityHeightMap();
|
||||||
|
|
||||||
// Clear all heightmap image data as it's no longer needed.
|
|
||||||
|
|
||||||
for (HeightMap heightMap : HeightMap.heightmapByLoadNum.values()) {
|
|
||||||
heightMap.heightmapImage = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info(HeightMap.heightmapByLoadNum.size() + " Heightmaps cached.");
|
Logger.info(HeightMap.heightmapByLoadNum.size() + " Heightmaps cached.");
|
||||||
|
|
||||||
// Load pixel data for heightmaps
|
// Load pixel data for heightmaps
|
||||||
@@ -282,13 +278,13 @@ public class HeightMap {
|
|||||||
// Generate pixel data for this heightmap. RPG channels are all the same
|
// Generate pixel data for this heightmap. RPG channels are all the same
|
||||||
// in this greyscale TGA heightmap. We will choose red.
|
// in this greyscale TGA heightmap. We will choose red.
|
||||||
|
|
||||||
byte[][] colorData = new byte[heightmapImage.getWidth()][heightmapImage.getHeight()];
|
short[][] colorData = new short[heightmapImage.getWidth()][heightmapImage.getHeight()];
|
||||||
|
|
||||||
for (int y = 0; y < heightmapImage.getHeight(); y++)
|
for (int y = 0; y < heightmapImage.getHeight(); y++)
|
||||||
for (int x = 0; x < heightmapImage.getWidth(); x++) {
|
for (int x = 0; x < heightmapImage.getWidth(); x++) {
|
||||||
|
|
||||||
Color color = new Color(heightmapImage.getRGB(x, y));
|
Color color = new Color(heightmapImage.getRGB(x, y));
|
||||||
colorData[x][y] = (byte) color.getRed();
|
colorData[x][y] = (short) color.getRed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert color data into lookup table
|
// Insert color data into lookup table
|
||||||
@@ -315,13 +311,13 @@ public class HeightMap {
|
|||||||
|
|
||||||
// Generate altitude lookup table for this heightmap
|
// Generate altitude lookup table for this heightmap
|
||||||
|
|
||||||
heightMap.pixelColorValues = new int[heightMap.heightmapImage.getWidth()][heightMap.heightmapImage.getHeight()];
|
heightMap.pixelColorValues = new short[heightMap.heightmapImage.getWidth()][heightMap.heightmapImage.getHeight()];
|
||||||
|
|
||||||
for (int y = 0; y < heightMap.heightmapImage.getHeight(); y++) {
|
for (int y = 0; y < heightMap.heightmapImage.getHeight(); y++) {
|
||||||
for (int x = 0; x < heightMap.heightmapImage.getWidth(); x++) {
|
for (int x = 0; x < heightMap.heightmapImage.getWidth(); x++) {
|
||||||
|
|
||||||
color = new Color(heightMap.heightmapImage.getRGB(x, y));
|
color = new Color(heightMap.heightmapImage.getRGB(x, y));
|
||||||
heightMap.pixelColorValues[x][y] = color.getRed();
|
heightMap.pixelColorValues[x][y] = (short) color.getRed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,28 +325,31 @@ public class HeightMap {
|
|||||||
|
|
||||||
public Vector2f getGridSquare(Vector2f zoneLoc) {
|
public Vector2f getGridSquare(Vector2f zoneLoc) {
|
||||||
|
|
||||||
// Clamp values.
|
float xBucket = zoneLoc.x / this.cell_size_x;
|
||||||
|
float yBucket = zoneLoc.y / this.cell_size_y;
|
||||||
|
|
||||||
float xBucket = zoneLoc.x / this.bucketWidthX;
|
// Clamp values when standing directly on max pole
|
||||||
float yBucket = zoneLoc.y / this.bucketWidthY;
|
|
||||||
|
|
||||||
if (xBucket >= this.bucketCountX)
|
if (xBucket >= this.cell_count_x)
|
||||||
xBucket = xBucket - 1;
|
xBucket = xBucket - 1;
|
||||||
|
|
||||||
if (yBucket >= this.bucketCountY)
|
if (yBucket >= this.cell_count_y)
|
||||||
yBucket = xBucket - 1;
|
yBucket = xBucket - 1;
|
||||||
|
|
||||||
return new Vector2f(xBucket, yBucket);
|
return new Vector2f(xBucket, yBucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getInterpolatedTerrainHeight(Vector2f zoneLoc) {
|
public float getInterpolatedTerrainHeight(Vector2f terrainLoc) {
|
||||||
|
|
||||||
float interpolatedHeight;
|
float interpolatedHeight;
|
||||||
|
|
||||||
Vector2f gridSquare = getGridSquare(zoneLoc);
|
Vector2f gridSquare = getGridSquare(terrainLoc);
|
||||||
|
|
||||||
int gridX = (int) gridSquare.x;
|
int gridX = (int) Math.floor(gridSquare.x);
|
||||||
int gridY = (int) gridSquare.y;
|
int gridY = (int) Math.floor(gridSquare.y);
|
||||||
|
|
||||||
|
float offsetX = gridSquare.x % 1;
|
||||||
|
float offsetY = gridSquare.y % 1;
|
||||||
|
|
||||||
//get 4 surrounding vertices from the pixel array.
|
//get 4 surrounding vertices from the pixel array.
|
||||||
|
|
||||||
@@ -366,15 +365,12 @@ public class HeightMap {
|
|||||||
|
|
||||||
// Interpolate between the 4 vertices
|
// Interpolate between the 4 vertices
|
||||||
|
|
||||||
float offsetX = (gridSquare.x - gridX);
|
|
||||||
float offsetY = gridSquare.y - gridY;
|
|
||||||
|
|
||||||
interpolatedHeight = topRightHeight * (1 - offsetY) * (offsetX);
|
interpolatedHeight = topRightHeight * (1 - offsetY) * (offsetX);
|
||||||
interpolatedHeight += (bottomRightHeight * offsetY * offsetX);
|
interpolatedHeight += (bottomRightHeight * offsetY * offsetX);
|
||||||
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
|
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
|
||||||
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
|
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
|
||||||
|
|
||||||
interpolatedHeight *= (float) this.maxHeight * SCALEVALUE; // Scale height
|
interpolatedHeight *= this.terrain_scale; // Scale height
|
||||||
|
|
||||||
return interpolatedHeight;
|
return interpolatedHeight;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ public class ZoneInfoCmd extends AbstractDevCmd {
|
|||||||
if (zone.getHeightMap() != null) {
|
if (zone.getHeightMap() != null) {
|
||||||
output += "HeightMap ID: " + zone.getHeightMap().heightMapID;
|
output += "HeightMap ID: " + zone.getHeightMap().heightMapID;
|
||||||
output += newline;
|
output += newline;
|
||||||
output += "Bucket Width X : " + zone.getHeightMap().bucketWidthX;
|
output += "Bucket Width X : " + zone.getHeightMap().cell_size_x;
|
||||||
output += newline;
|
output += newline;
|
||||||
output += "Bucket Width Y : " + zone.getHeightMap().bucketWidthY;
|
output += "Bucket Width Y : " + zone.getHeightMap().cell_size_y;
|
||||||
|
|
||||||
}
|
}
|
||||||
output += "radius: x: " + zone.bounds.getHalfExtents().x + ", z: " + zone.bounds.getHalfExtents().y;
|
output += "radius: x: " + zone.bounds.getHalfExtents().x + ", z: " + zone.bounds.getHalfExtents().y;
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ public class WorldServer {
|
|||||||
|
|
||||||
for (Zone zone : ZoneManager.getAllZones()) {
|
for (Zone zone : ZoneManager.getAllZones()) {
|
||||||
if (zone.getHeightMap() != null) {
|
if (zone.getHeightMap() != null) {
|
||||||
if (zone.getHeightMap().bucketWidthX == 0) {
|
if (zone.getHeightMap().cell_size_x == 0) {
|
||||||
System.out.println("Zone load num: " + zone.template + " has no bucket width");
|
System.out.println("Zone load num: " + zone.template + " has no bucket width");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user