浏览代码

Update Terrain
Update Prefab data savepath

ShiroSmith 7 年之前
父节点
当前提交
a8ed789558

+ 12 - 0
h3d/scene/pbr/terrain/Terrain.hx

@@ -29,6 +29,16 @@ class Terrain extends Object {
 		copyPass = new h3d.pass.Copy();
 	}
 
+	public function getHeight(pos : h3d.Vector) : Float {
+		var z = 0.0;
+		var t = getTileAtWorldPos(pos);
+		if(t != null){
+			var pos = t.globalToLocal(pos.clone());
+			z = t.getHeight(pos.x / tileSize, pos.y / tileSize);
+		}
+		return z;
+	}
+
 	public function getSurface(i : Int) : Surface{
 		if(i < surfaces.length)
 				return surfaces[i];
@@ -169,6 +179,7 @@ class Terrain extends Object {
 	}
 
 	public function getTileAtWorldPos(pos : h3d.Vector) : Tile {
+		var pos = globalToLocal(pos.clone());
 		var result : Tile = null;
 		var tileX = Math.floor(pos.x / tileSize);
 		var tileY = Math.floor(pos.y / tileSize);
@@ -178,6 +189,7 @@ class Terrain extends Object {
 	}
 
 	public function createTileAtWorldPos(pos : h3d.Vector) : Tile {
+		var pos = globalToLocal(pos.clone());
 		var tileX = Math.floor(pos.x / tileSize);
 		var tileY = Math.floor(pos.y / tileSize);
 		var result = getTile(tileX, tileY);

+ 33 - 17
h3d/scene/pbr/terrain/Tile.hx

@@ -111,7 +111,7 @@ class Tile extends h3d.scene.Mesh {
 			}
 		}
 
-		if(surfaceWeights.length != getTerrain().surfaces.length || surfaceWeights[0].width != getTerrain().weightMapResolution){
+		if( getTerrain().surfaces.length > 0 && (surfaceWeights.length != getTerrain().surfaces.length || surfaceWeights[0].width != getTerrain().weightMapResolution)){
 			var oldArray = surfaceWeights;
 			surfaceWeights = new Array<h3d.mat.Texture>();
 			surfaceWeights = [for (i in 0...getTerrain().surfaces.length) null];
@@ -449,22 +449,27 @@ class Tile extends h3d.scene.Mesh {
 	public function getHeight(u : Float, v : Float){
 		var pixels = getHeightPixels();
 		if(heightMap.filter == Linear){
-			var coordsX = hxd.Math.max(0, u * (heightMap.width - 1) - 0.5);
-			var coordsY =  hxd.Math.max(0, v * (heightMap.width - 1) - 0.5);
-			var x = hxd.Math.floor(coordsX);
-			var y = hxd.Math.floor(coordsY);
-			var ratioX = coordsX - x;
-			var ratioY = coordsY - y;
-			var oppositeU = 1 - ratioX;
-			var oppositeV = 1 - ratioY;
-			var result = (pixels.getPixelF(x, y).r * oppositeU + pixels.getPixelF( Std.int(hxd.Math.min(x + 1, pixels.width)), y).r * ratioX) * oppositeV +
-                   (pixels.getPixelF(x,  Std.int(hxd.Math.min(y + 1, pixels.height))).r * oppositeU +
-				   pixels.getPixelF(Std.int(hxd.Math.min(x + 1, pixels.width)), Std.int(hxd.Math.min(y + 1, pixels.height))).r * ratioX) * ratioY;
-			return result;
+			inline function getPix(u, v){
+				return pixels.getPixelF(Std.int(hxd.Math.clamp(u, 0, pixels.width - 1)), Std.int(hxd.Math.clamp(v, 0, pixels.height - 1))).r;
+			}
+			var px = u * (heightMap.width - 1) + 0.5;
+            var py = v * (heightMap.width - 1) + 0.5;
+			var pxi = hxd.Math.floor(px);
+            var pyi = hxd.Math.floor(py);
+			var c00 = getPix(pxi, pyi);
+			var c10 = getPix(pxi + 1, pyi);
+			var c01 = getPix(pxi, pyi + 1);
+			var c11 = getPix(pxi + 1, pyi + 1);
+			var wx = px - pxi;
+			var wy = py - pyi;
+			var a = c00 * (1 - wx) + c10 * wx;
+			var b = c01 * (1 - wx) + c11 * wx;
+			return a * (1 - wy) + b * wy;
+
 		}
 		else{
-			var x = hxd.Math.floor(u * (heightMap.width - 2));
-			var y = hxd.Math.floor(v * (heightMap.height - 2));
+			var x = hxd.Math.floor(u * (heightMap.width - 1) + 0.5);
+			var y = hxd.Math.floor(v * (heightMap.height - 1) + 0.5);
 			return pixels.getPixelF(x, y).r;
 		}
 	}
@@ -477,7 +482,7 @@ class Tile extends h3d.scene.Mesh {
 	}
 
 	override function emit(ctx:RenderContext){
-		if( getTerrain().surfaceArray == null || getTerrain().surfaces.length == 0) return;
+		if(!isReady()) return;
 		var bounds = getBounds();
 		bounds.zMax = 10000;
 		bounds.zMin = -10000;
@@ -489,7 +494,7 @@ class Tile extends h3d.scene.Mesh {
 	}
 
 	override function sync(ctx:RenderContext) {
-		if( getTerrain().surfaceArray == null || getTerrain().surfaces.length == 0) return;
+		if(!isReady()) return;
 
 		shader.SHOW_GRID = getTerrain().showGrid;
 		shader.SURFACE_COUNT = getTerrain().surfaces.length;
@@ -516,4 +521,15 @@ class Tile extends h3d.scene.Mesh {
 		shader.heightBlendStrength = getTerrain().heightBlendStrength;
 		shader.heightBlendSharpness = getTerrain().heightBlendSharpness;
 	}
+
+	function isReady(){
+		if( getTerrain().surfaceArray == null || getTerrain().surfaces.length == 0 || surfaceWeights.length != getTerrain().surfaces.length)
+			return false;
+		if(heightMap == null)
+			return false;
+		for(i in 0 ... surfaceWeights.length)
+			if(surfaceWeights[i] == null)
+				return false;
+		return true;
+	}
 }

+ 2 - 1
h3d/shader/pbr/Terrain.hx

@@ -40,8 +40,9 @@ class Terrain extends hxsl.Shader {
 		var occlusionValue : Float;
 
 		function vertex() {
-			terrainUV = input.position.xy / primSize * (heightMapSize - 1) / heightMapSize + 0.5 / heightMapSize;
 			calculatedUV = input.position.xy / primSize;
+			var terrainUV = (calculatedUV * (heightMapSize - 1)) / heightMapSize;
+			terrainUV += 0.5 / heightMapSize;
 			transformedPosition += (vec3(0,0, heightMap.get(terrainUV).r) * global.modelView.mat3());
 			TBN = mat3(normalize(cross(transformedNormal, vec3(0,1,0))), normalize(cross(transformedNormal,vec3(-1,0,0))), transformedNormal);
 		}

+ 5 - 0
hxd/fs/BytesFileSystem.hx

@@ -113,4 +113,9 @@ class BytesFileSystem implements FileSystem {
 	public function dispose() {
 	}
 
+	public function dir( path : String ) : Array<FileEntry> {
+		throw "Not implemented";
+		return null;
+	}
+
 }

+ 6 - 0
hxd/fs/EmbedFileSystem.hx

@@ -288,4 +288,10 @@ class EmbedFileSystem #if !macro implements FileSystem #end {
 	public function dispose() {
 	}
 
+	public function dir( path : String ) : Array<FileEntry> {
+		if( !isDirectory(path) )
+			throw new NotFound(path);
+		return subFiles(path)
+	}
+
 }

+ 1 - 0
hxd/fs/FileSystem.hx

@@ -5,4 +5,5 @@ interface FileSystem {
 	public function get( path : String ) : FileEntry;
 	public function exists( path : String ) : Bool;
 	public function dispose() : Void;
+	public function dir( path : String ) : Array<FileEntry> ;
 }

+ 17 - 0
hxd/fs/LocalFileSystem.hx

@@ -550,6 +550,20 @@ class LocalFileSystem implements FileSystem {
 		updateTime();
 	}
 
+	public function dir( path : String ) : Array<FileEntry> {
+		#if flash
+		throw "Not Supported";
+		return null;
+		#end
+		if( !sys.FileSystem.exists(baseDir + path) || !sys.FileSystem.isDirectory(baseDir + path) )
+			throw new NotFound(baseDir + path);
+		var files = sys.FileSystem.readDirectory(baseDir + path);
+		var r : Array<FileEntry> = [];
+		for(f in files)
+			r.push(new LocalEntry(this, f, path + "/" + f, baseDir + path + "/" + f));
+		return r;
+	}
+
 }
 
 #else
@@ -581,6 +595,9 @@ class LocalFileSystem implements FileSystem {
 	public function dispose() {
 	}
 
+	public function dir( path : String ) : Array<hxd.res.Any> {
+		return null;
+	}
 }
 
 #end

+ 20 - 0
hxd/prefab/ContextShared.hx

@@ -47,6 +47,26 @@ class ContextShared {
 		return ret;
 	}
 
+	public function loadDir(p : hide.prefab.Prefab, ?dir : String ) : Array<hxd.res.Any> {
+		var datPath = new haxe.io.Path(currentPath);
+		datPath.ext = "dat";
+		var path = datPath.toString() + "/" + p.name;
+		if(dir != null) path += "/" + dir;
+		return try hxd.res.Loader.currentInstance.dir(path) catch( e : hxd.res.NotFound ) null;
+	}
+
+	public function loadPrefabDat(file : String, ext : String, p : hide.prefab.Prefab) : hxd.res.Any {
+		var datPath = new haxe.io.Path(currentPath);
+		datPath.ext = "dat";
+		var path = new haxe.io.Path(datPath.toString() + "/" + p.name + "/" + file);
+		path.ext = ext;
+		return try hxd.res.Loader.currentInstance.load(path.toString()) catch( e : hxd.res.NotFound ) null;
+	}
+
+	public function savePrefabDat(file : String, ext : String, p : hide.prefab.Prefab, bytes : haxe.io.Bytes ) {
+		throw "Not implemented";
+	}
+
 	public function loadPrefab( path : String ) : Prefab {
 		throw "Not implemented";
 	}

+ 9 - 1
hxd/res/Loader.hx

@@ -20,6 +20,14 @@ class Loader {
 		cache = new Map();
 	}
 
+	public function dir( path : String ) : Array<Any> {
+		var r : Array<Any> = [];
+		var entries = fs.dir(path);
+		for(e in entries)
+			r.push(new Any(this, e));
+		return r;
+	}
+
 	public function exists( path : String ) : Bool {
 		return fs.exists(path);
 	}
@@ -40,7 +48,7 @@ class Loader {
 		} else {
 			if( Std.instance(res,c) == null )
 				throw path+" has been reintrepreted from "+Type.getClass(res)+" to "+c;
-		}			
+		}
 		return res;
 	}