Kaynağa Gözat

[terrain] Forbid creation of disconnected tiles by default in editor

Clément Espeute 1 yıl önce
ebeveyn
işleme
3b910427c0

+ 7 - 2
hide/prefab/terrain/TerrainEditor.hx

@@ -42,6 +42,8 @@ class TerrainEditor {
 	public var currentSurface : hrt.prefab.terrain.Surface;
 	public var textureType = ["_Albedo", "_Normal", "_MetallicGlossAO"];
 	public var autoCreateTile = false;
+	public var allowDisconnectedTiles = false;
+
 	public var editContext : hide.prefab.EditContext;
 
 	// Debug
@@ -80,6 +82,7 @@ class TerrainEditor {
 		this.undo = undo;
 		renderMode = terrainPrefab.showChecker ? Checker : PBR;
 		autoCreateTile = terrainPrefab.autoCreateTile;
+		allowDisconnectedTiles = terrainPrefab.allowDisconnectedTiles;
 
 		brushPreview = new hide.prefab.terrain.Brush.BrushPreview(terrainPrefab.terrain);
 
@@ -110,6 +113,7 @@ class TerrainEditor {
 			terrainPrefab.terrain.updateSurfaceParams();
 
 		autoCreateTile = terrainPrefab.autoCreateTile;
+		allowDisconnectedTiles = terrainPrefab.allowDisconnectedTiles;
 		brushPreview.opacity = terrainPrefab.brushOpacity;
 
 		if( propName == "editor.renderMode" ) updateRender();
@@ -702,7 +706,7 @@ class TerrainEditor {
 		var brushWorldPos = uvTexPixels == null ? pos : getBrushWorldPosFromTex(pos);
 		if( brushWorldPos == null ) return;
 		var c = terrainPrefab.terrain.tiles.length;
-		var tiles = terrainPrefab.terrain.getTiles(brushWorldPos.x, brushWorldPos.y, currentBrush.size / 2.0, autoCreateTile);
+		var tiles = terrainPrefab.terrain.getTiles(brushWorldPos.x, brushWorldPos.y, currentBrush.size / 2.0, autoCreateTile, allowDisconnectedTiles);
 		if( c != terrainPrefab.terrain.tiles.length ) {
 			renderTerrainUV();
 			brushWorldPos = getBrushWorldPosFromTex(pos);
@@ -738,7 +742,7 @@ class TerrainEditor {
 		var brushWorldPos = uvTexPixels == null ? pos : getBrushWorldPosFromTex(pos);
 		if( brushWorldPos == null ) return;
 		var c = terrainPrefab.terrain.tiles.length;
-		var tiles = terrainPrefab.terrain.getTiles(brushWorldPos.x, brushWorldPos.y, currentBrush.size / 2.0, autoCreateTile);
+		var tiles = terrainPrefab.terrain.getTiles(brushWorldPos.x, brushWorldPos.y, currentBrush.size / 2.0, autoCreateTile, allowDisconnectedTiles);
 		if( c != terrainPrefab.terrain.tiles.length ) {
 			renderTerrainUV();
 			brushWorldPos = getBrushWorldPosFromTex(pos);
@@ -1104,6 +1108,7 @@ class TerrainEditor {
 			<i> Please select a tool </i>
 		</div>
 		<dt>AutoCreate</dt><dd><input type="checkbox" field="autoCreateTile"/></dd>
+		<dt title="Allow tiles to be created without being connected to another tile">Disconnect</dt><dd><input type="checkbox" field="allowDisconnectedTiles"/></dd>
 		<dt>Accumulate</dt><dd><input type="checkbox" field="editor.currentBrush.brushMode.accumulate"/></dd>
 	</div>';
 

+ 1 - 0
hrt/prefab/terrain/Terrain.hx

@@ -46,6 +46,7 @@ class Terrain extends Object3D {
 	var editor : hide.prefab.terrain.TerrainEditor;
 	@:s public var showChecker = false;
 	@:s public var autoCreateTile = false;
+	@:s public var allowDisconnectedTiles = false;
 	@:s public var brushOpacity : Float = 1.0;
 	#end
 

+ 36 - 9
hrt/prefab/terrain/TerrainMesh.hx

@@ -259,23 +259,50 @@ class TerrainMesh extends h3d.scene.Object {
 		return result == null ? createTile(tileX, tileY) : result;
 	}
 
-	public function getTiles( x : Float, y : Float, range : Float, ?create = false ) : Array<Tile> {
+	public function getTiles( x : Float, y : Float, range : Float, ?create = false, ?disconectedTiles = false ) : Array<Tile> {
 		var pos = toLocalPos(x, y);
 		if( create != null && create ) {
 			var maxTileX = Math.floor((pos.x + range)/ tileSize.x);
 			var minTileX = Math.floor((pos.x - range)/ tileSize.x);
 			var maxTileY = Math.floor((pos.y + range)/ tileSize.y);
 			var minTileY = Math.floor((pos.y - range)/ tileSize.y);
-			for( x in minTileX ... maxTileX + 1) {
-				for( y in minTileY...maxTileY + 1) {
-					var t = createTile(x, y);
-					#if editor
-					t.material.mainPass.stencil = new h3d.mat.Stencil();
-					t.material.mainPass.stencil.setFunc(Always, 0x01, 0x01, 0x01);
-					t.material.mainPass.stencil.setOp(Keep, Keep, Replace);
-					#end
+			var shouldCreate = disconectedTiles;
+			if (!shouldCreate && tiles.length == 0) {
+				// allow tile cration arount origin
+				shouldCreate = maxTileX >= 0 && minTileX<=0 && maxTileY>=0 && minTileY<=0;  
+			}
+			
+			// check if borders contains a tile
+			if (!shouldCreate) {
+				for (x in minTileX...maxTileX+1)
+				{
+					shouldCreate = getTile(x, maxTileY+1) != null || getTile(x, minTileY-1) != null;
+					if (shouldCreate)
+						break;
+				}
+			}
+			if (!shouldCreate) {
+				for (y in minTileY...maxTileY+1)
+				{
+					shouldCreate = getTile(maxTileX+1, y) != null || getTile(minTileX - 1, y) != null;
+					if (shouldCreate)
+						break;
 				}
 			}
+
+			if (shouldCreate) {
+				for( x in minTileX ... maxTileX + 1) {
+					for( y in minTileY...maxTileY + 1) {
+						var t = createTile(x, y);
+						#if editor
+						t.material.mainPass.stencil = new h3d.mat.Stencil();
+						t.material.mainPass.stencil.setFunc(Always, 0x01, 0x01, 0x01);
+						t.material.mainPass.stencil.setOp(Keep, Keep, Replace);
+						#end
+					}
+				}
+			}
+
 		}
 		var result : Array<Tile> = [];
 		for( tile in tiles)