forked from MagicBane/Server
Blend function installed
This commit is contained in:
@@ -16,18 +16,22 @@ import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static java.lang.Math.PI;
|
||||
|
||||
public class Terrain {
|
||||
|
||||
// Class variables
|
||||
|
||||
public static final HashMap<Integer, short[][]> _heightmap_pixel_cache = new HashMap<>();
|
||||
Zone zone;
|
||||
public short[][] terrain_pixel_data;
|
||||
public Vector2f terrain_size = new Vector2f();
|
||||
public Vector2f cell_size = new Vector2f();
|
||||
public Vector2f cell_count = new Vector2f();
|
||||
public float terrain_scale;
|
||||
public float min_blend;
|
||||
public float max_blend;
|
||||
public int heightmap;
|
||||
Zone zone;
|
||||
|
||||
public Terrain(Zone zone) {
|
||||
|
||||
@@ -54,6 +58,9 @@ public class Terrain {
|
||||
this.cell_size.x = terrain_size.x / this.cell_count.x;
|
||||
this.cell_size.y = terrain_size.y / this.cell_count.y;
|
||||
|
||||
this.max_blend = this.zone.max_blend / this.zone.major_radius;
|
||||
this.min_blend = this.zone.min_blend / this.zone.minor_radius;
|
||||
|
||||
this.terrain_scale = this.zone.terrain_max_y / 255f;
|
||||
|
||||
}
|
||||
@@ -80,22 +87,34 @@ public class Terrain {
|
||||
public static float getWorldHeight(Zone currentZone, Vector3fImmutable worldLoc) {
|
||||
|
||||
Zone terrainZone;
|
||||
Zone parentZone;
|
||||
|
||||
// Retrieve the next zone with a heightmap attached.
|
||||
// Zones without a heightmap use the next zone up the
|
||||
// tree to calculate heights from.
|
||||
|
||||
terrainZone = getNextZoneWithTerrain(currentZone);
|
||||
parentZone = getNextZoneWithTerrain(currentZone.parent);
|
||||
|
||||
// Transform world loc into zone space coordinate system
|
||||
|
||||
Vector2f terrainLoc = ZoneManager.worldToZoneSpace(worldLoc, terrainZone);
|
||||
Vector2f parentLoc = ZoneManager.worldToZoneSpace(worldLoc, parentZone);
|
||||
|
||||
// Interpolate height for this position using pixel array.
|
||||
// Interpolate height for this position in terrain
|
||||
|
||||
float interpolatedTerrainHeight = terrainZone.terrain.getInterpolatedTerrainHeight(terrainLoc);
|
||||
interpolatedTerrainHeight += terrainZone.worldAltitude;
|
||||
|
||||
// Interpolate height for this position in parent
|
||||
|
||||
float interpolatedParentTerrainHeight = parentZone.terrain.getInterpolatedTerrainHeight(parentLoc);
|
||||
interpolatedParentTerrainHeight += parentZone.worldAltitude;
|
||||
|
||||
// Blend between heights
|
||||
|
||||
interpolatedTerrainHeight = interpolatedTerrainHeight + interpolatedParentTerrainHeight * (1 - terrainZone.terrain.heightBlend(terrainLoc));
|
||||
|
||||
return interpolatedTerrainHeight;
|
||||
|
||||
}
|
||||
@@ -161,4 +180,47 @@ public class Terrain {
|
||||
|
||||
return interpolatedHeight;
|
||||
}
|
||||
|
||||
public float heightBlend(Vector2f terrainLoc) {
|
||||
|
||||
// Normalize terrain loc
|
||||
|
||||
Vector2f normalizedLoc = new Vector2f(terrainLoc.x / this.terrain_size.x,
|
||||
terrainLoc.y / terrain_size.y);
|
||||
|
||||
float minp = this.zone.min_blend / this.zone.major_radius;
|
||||
float maxp = this.zone.max_blend / this.zone.major_radius;
|
||||
|
||||
float xval;
|
||||
|
||||
if (minp > 0.4f)
|
||||
xval = minp;
|
||||
else
|
||||
xval = Math.min(maxp, 0.4f);
|
||||
|
||||
float minpy = this.zone.min_blend / this.zone.minor_radius;
|
||||
float maxpy = this.zone.max_blend / this.zone.minor_radius;
|
||||
|
||||
float yval;
|
||||
|
||||
if (minpy > 0.4f)
|
||||
yval = minpy;
|
||||
else
|
||||
yval = Math.min(maxpy, 0.4f);
|
||||
|
||||
float value;
|
||||
|
||||
if (normalizedLoc.x <= 1 - xval || normalizedLoc.x <= normalizedLoc.y) {
|
||||
|
||||
if (normalizedLoc.x < 1 - yval)
|
||||
return 1;
|
||||
|
||||
value = (normalizedLoc.y - (1 - yval)) / yval;
|
||||
} else
|
||||
value = (normalizedLoc.x - (1 - xval)) / xval;
|
||||
|
||||
value = (float) Math.atan((0.5f - value) * PI);
|
||||
|
||||
return (value + 1) * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user