浏览代码

Update Terrain :
BugFix for brush
Add brush scale with drag

ShiroSmith 5 年之前
父节点
当前提交
3008d679cf
共有 4 个文件被更改,包括 104 次插入46 次删除
  1. 12 1
      hide/Scene.hx
  2. 52 35
      hide/prefab/terrain/Brush.hx
  3. 37 10
      hide/prefab/terrain/TerrainEditor.hx
  4. 3 0
      hrt/prefab/terrain/Terrain.hx

+ 12 - 1
hide/Scene.hx

@@ -1,7 +1,6 @@
 package hide;
 
 import h3d.scene.Interactive;
-import h3d.col.Sphere;
 import h3d.scene.RenderContext;
 
 class ChunkScene {
@@ -42,6 +41,10 @@ class ChunkScene {
 			if( gizmo != null ) 
 				continue;
 
+			var terrainBrushPreview = Std.downcast(obj, hide.prefab.terrain.Brush.BrushPreview);
+			if( terrainBrushPreview != null ) 
+				continue;
+
 			// Ignore animated objects
 			if( obj.currentAnimation == null ) {
 				var absPos = @:privateAccess obj.absPos.getPosition(tmpVec);
@@ -104,6 +107,14 @@ class ChunkScene {
 				chunkifyObjects(c, chunkOverride);
 			return;
 		}
+		
+		// Terrain  exception
+		var terrainBrushPreview = Std.downcast(obj, hide.prefab.terrain.Brush.BrushPreview);
+		if( terrainBrushPreview != null ) {
+			var gc = getGlobalChunk();
+			gc.addObject(obj, null);
+			return;
+		}
 
 		if( !obj.visible ) 
 			return;

+ 52 - 35
hide/prefab/terrain/Brush.hx

@@ -1,4 +1,5 @@
 package hide.prefab.terrain;
+import h3d.shader.pbr.AlphaMultiply;
 import h3d.shader.FixedColor;
 import h3d.mat.Stencil;
 import hrt.prefab.l3d.AdvancedDecal;
@@ -21,16 +22,18 @@ class Brush {
 		brushMode = new BrushMode();
 	}
 
-	public function isValid() : Bool{
-		return ( brushMode.mode == Delete || (bitmap != null && tex != null && name != null && step > 0.0 && texPath != null));
+	public function isValid() : Bool {
+		return ( brushMode.mode == Delete || (bitmap != null && tex != null && name != null && step > 0.0 && texPath != null) );
 	}
 
-	public function scaleForTex(tileSize : Float, texResolution : Float){
-		var scale = size / ((tileSize / texResolution) * tex.width);
-		bitmap.setScale(scale);
+	public function scaleForTex( tileSize : Float, texResolution : Float ) {
+		if( tex != null ) {
+			var scale = size / ((tileSize / texResolution) * tex.width);
+			bitmap.setScale(scale);
+		}
 	}
 
-	public function drawTo( target : h3d.mat.Texture, pos : h3d.Vector, tileSize : Float, ?offset = 0){
+	public function drawTo( target : h3d.mat.Texture, pos : h3d.Vector, tileSize : Float, ?offset = 0 ) {
 		var texSize = target.width + offset;
 		scaleForTex(tileSize, texSize);
 		bitmap.setPosition(
@@ -66,55 +69,69 @@ class BrushMode {
 	public function new(){}
 }
 
-class BrushPreview extends h3d.scene.Object {
+class AlphaMult extends hxsl.Shader {
+	static var SRC = {
+		@param var amount : Float;
+		var pixelColor : Vec4;
+		function fragment() {
+			pixelColor.a *= amount;
+		}
+	}
+}
+
+class BrushPreview extends h3d.scene.Mesh {
 
 	var terrain : hrt.prefab.terrain.TerrainMesh;
-	var mesh : h3d.scene.pbr.Decal;
-	var shader : h3d.shader.pbr.VolumeDecal.DecalOverlay;
+	var decalShader : h3d.shader.pbr.VolumeDecal.DecalOverlay;
+	public var opacity : Float = 1.0;
 
 	public function new( terrain : hrt.prefab.terrain.TerrainMesh ) {
-		super(terrain.getScene());
 		this.terrain = terrain;
-		mesh = new h3d.scene.pbr.Decal(h3d.prim.Cube.defaultUnitCube(), this);
-		shader = new h3d.shader.pbr.VolumeDecal.DecalOverlay();
-		mesh.material.mainPass.addShader(shader);
-		mesh.material.mainPass.setPassName("afterTonemappingDecal");
-		mesh.material.mainPass.depthWrite = false;
-		mesh.material.mainPass.depthTest = GreaterEqual;
-		mesh.material.mainPass.culling = Front;
-		mesh.material.shadows = false;
-		mesh.material.blendMode = Alpha;
-		mesh.scaleZ = 1000;
-		shader.fadeStart = 1;
-		shader.fadeEnd = 0;
-		shader.fadePower = 1;
-		shader.emissive = 0;
+		var material = h3d.mat.MaterialSetup.current.createMaterial();
+		material.props = material.getDefaultProps();
+		material.mainPass.removeShader(material.mainPass.getShader(h3d.shader.pbr.PropsValues));
+		material.mainPass.setPassName("afterTonemappingDecal");
+		material.mainPass.depthWrite = false;
+		material.mainPass.depthTest = GreaterEqual;
+		material.mainPass.culling = Front;
+		material.blendMode = Alpha;
+		material.shadows = false;
+		super(h3d.prim.Cube.defaultUnitCube(), material, terrain.getScene());
+		decalShader = new h3d.shader.pbr.VolumeDecal.DecalOverlay();
+		decalShader.fadeStart = 1;
+		decalShader.fadeEnd = 0;
+		decalShader.fadePower = 1;
+		decalShader.emissive = 0;
+		decalShader.CENTERED = true;
+		decalShader.GAMMA_CORRECT = false;
+		material.mainPass.addShader(decalShader);
 		var colorSet = new FixedColor();
 		colorSet.color.set(1,1,1,1);
 		colorSet.USE_ALPHA = false;
-		mesh.material.mainPass.addShader(colorSet);
-		shader.CENTERED = true;
+		material.mainPass.addShader(colorSet);
+		var am = new AlphaMult();
+		am.setPriority(-1);
+		am.amount = opacity;
+		material.mainPass.addShader(am);
 
 		// Only draw the preview on terrain
-		mesh.material.mainPass.stencil = new h3d.mat.Stencil();
-		mesh.material.mainPass.stencil.setFunc(Equal, 0x01, 0x01, 0x01);
-		mesh.material.mainPass.stencil.setOp(Keep, Keep, Keep);
-	}
-
-	public function setBrushTexture( texture : h3d.mat.Texture ) {
-		shader.colorTexture = texture;
+		material.mainPass.stencil = new h3d.mat.Stencil();
+		material.mainPass.stencil.setFunc(Equal, 0x01, 0x01, 0x01);
+		material.mainPass.stencil.setOp(Keep, Keep, Keep);
 	}
 
 	public function previewAt( brush : Brush, pos : h3d.Vector ) {
 		setPosition(pos.x, pos.y, pos.z);
-		setBrushTexture( brush.tex );
 		setScale(brush.size);
+		scaleZ = 1000;
+		decalShader.colorTexture = brush.tex;
+		material.mainPass.getShader(AlphaMult).amount = opacity;
 		visible = true;
 	}
 
 	public function reset() {
 		setPosition(0,0,0);
 		visible = false;
-		shader.colorTexture = null;
+		decalShader.colorTexture = null;
 	}
 }

+ 37 - 10
hide/prefab/terrain/TerrainEditor.hx

@@ -51,6 +51,8 @@ class TerrainEditor {
 	var interactive : h2d.Interactive;
 	var remainingDist = 0.0;
 	var lastPos : h3d.Vector;
+	var lastMousePos : h2d.col.Point;
+	var lastBrushSize : Float;
 	var heightStrokeBufferArray : hide.prefab.terrain.StrokeBuffer.StrokeBufferArray;
 	var weightStrokeBufferArray : hide.prefab.terrain.StrokeBuffer.StrokeBufferArray;
 	// Shader for edition
@@ -190,7 +192,10 @@ class TerrainEditor {
 		|| propName == "editor.currentSurface.maxHeight"
 		|| propName == "editor.currentSurface.parallaxAmount" )
 			terrainPrefab.terrain.updateSurfaceParams();
+
 		autoCreateTile = terrainPrefab.autoCreateTile;
+		brushPreview.opacity = terrainPrefab.brushOpacity;
+
 		if( propName == "editor.renderMode" ) updateRender();
 	}
 
@@ -758,6 +763,8 @@ class TerrainEditor {
 				var worldPos = getBrushPlanePos(s2d.mouseX, s2d.mouseY, ctx);
 				remainingDist = 0;
 				lastPos = null;
+				lastMousePos = null;
+				lastBrushSize = 0;
 				currentBrush.brushMode.lockAxe = NoLock;
 				currentBrush.firstClick = false;
 				applyStrokeBuffers();
@@ -767,9 +774,25 @@ class TerrainEditor {
 			};
 
 			interactive.onMove = function(e) {
+
+				// Brush Scale - Drag left/right
+				if( K.isDown(K.MOUSE_RIGHT) && K.isDown(K.CTRL) ) {
+					if( lastMousePos == null ) {
+						lastMousePos = new h2d.col.Point(s2d.mouseX, s2d.mouseY);
+						lastBrushSize = currentBrush.size;
+					}
+					e.propagate = false;
+					var newMousePos = new h2d.col.Point(s2d.mouseX, s2d.mouseY);
+					var dist = newMousePos.x - lastMousePos.x;
+					var sensibility = 0.5;
+					currentBrush.size = hxd.Math.max(0, lastBrushSize + sensibility * dist);
+					@:privateAccess Lambda.find(editContext.properties.fields, f->f.fname=="editor.currentBrush.size").range.value = currentBrush.size;
+					drawBrushPreview(getBrushPlanePos(lastMousePos.x, lastMousePos.y, ctx), ctx);
+					return;
+				}
+
 				currentBrush.brushMode.snapToGrid = K.isDown(K.CTRL);
 				var worldPos = getBrushPlanePos(s2d.mouseX, s2d.mouseY, ctx);
-
 				if( K.isDown( K.MOUSE_LEFT) ) {
 					currentBrush.firstClick = false;
 					e.propagate = false;
@@ -777,7 +800,6 @@ class TerrainEditor {
 					if( currentBrush.isValid() ) {
 						if( currentBrush.brushMode.lockDir ){
 							var dir = worldPos.sub(lastPos);
-							trace(dir);
 							if( currentBrush.brushMode.lockAxe == NoLock && dir.length() > 0.4 )
 								currentBrush.brushMode.lockAxe = hxd.Math.abs(dir.x) > hxd.Math.abs(dir.y) ? LockX : LockY;
 							if( currentBrush.brushMode.lockAxe == LockX ) {
@@ -802,7 +824,7 @@ class TerrainEditor {
 				drawBrushPreview(worldPos, ctx);
 			};
 		}
-		else{
+		else {
 			if( interactive != null ) interactive.remove();
 			brushPreview.reset();
 		}
@@ -1028,6 +1050,7 @@ class TerrainEditor {
 		<dt>Size</dt><dd><input type="range" min="0.01" max="50" field="editor.currentBrush.size"/></dd>
 		<dt>Strength</dt><dd><input type="range" min="0" max="1" field="editor.currentBrush.strength"/></dd>
 		<dt>Step</dt><dd><input type="range" min="0.01" max="10" field="editor.currentBrush.step"/></dd>
+		<dt>Opacity</dt><dd><input type="range" min="0" max="1" field="brushOpacity"/></dd>
 	</div>';
 
 	var surfaceParams =
@@ -1072,14 +1095,17 @@ class TerrainEditor {
 					currentBrush.texPath = ctx.ide.getPath(brush.texture);
 					currentBrush.tex = loadTexture(ctx, currentBrush.texPath);
 					currentBrush.name = brush.name;
-					if( currentBrush.bitmap != null ) {
-						currentBrush.bitmap.tile.dispose();
-						currentBrush.bitmap.tile = h2d.Tile.fromTexture(currentBrush.tex);
+					if( currentBrush.tex != null ) {
+						if( currentBrush.bitmap != null ) {
+							currentBrush.bitmap.tile.dispose();
+							currentBrush.bitmap.tile = h2d.Tile.fromTexture(currentBrush.tex);
+						}
+						else
+							currentBrush.bitmap = new h2d.Bitmap(h2d.Tile.fromTexture(currentBrush.tex));
+
+						currentBrush.bitmap.smooth = true;
+						currentBrush.bitmap.color = new h3d.Vector(currentBrush.strength);
 					}
-					else
-						currentBrush.bitmap = new h2d.Bitmap(h2d.Tile.fromTexture(currentBrush.tex));
-					currentBrush.bitmap.smooth = true;
-					currentBrush.bitmap.color = new h3d.Vector(currentBrush.strength);
 					refreshBrushes();
 				});
 				brushesContainer.append(brushElem);
@@ -1095,6 +1121,7 @@ class TerrainEditor {
 	}
 
 	function onSurfaceAdd( props : Element, ctx : EditContext, path : String ) {
+		editContext.scene.setCurrent();
 		terrainPrefab.modified = true;
 		if( path == null )
 			return;

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

@@ -47,6 +47,7 @@ class Terrain extends Object3D {
 	var cachedInstance : TerrainMesh;
 	public var showChecker = false;
 	public var autoCreateTile = false;
+	public var brushOpacity : Float;
 	#end
 
 	public function new( ?parent ) {
@@ -72,6 +73,7 @@ class Terrain extends Object3D {
 		#if editor
 		autoCreateTile = obj.autoCreateTile == null ? false : obj.autoCreateTile;
 		showChecker = obj.showChecker == null ? false : obj.showChecker;
+		brushOpacity = obj.brushOpacity == null ? 1.0 : obj.brushOpacity;
 		#end
 	}
 
@@ -117,6 +119,7 @@ class Terrain extends Object3D {
 		}
 
 		#if editor
+		obj.brushOpacity = brushOpacity;
 		obj.autoCreateTile = autoCreateTile;
 		if( terrain != null ) obj.showChecker = terrain.showChecker;
 		if( modified ) {