浏览代码

various fixes for meshpray + added set to ground and orient terrain config

Nicolas Cannasse 4 年之前
父节点
当前提交
c441653d09
共有 1 个文件被更改,包括 66 次插入34 次删除
  1. 66 34
      hrt/prefab/l3d/MeshSpray.hx

+ 66 - 34
hrt/prefab/l3d/MeshSpray.hx

@@ -87,6 +87,7 @@ typedef MeshSprayConfig = {
 	var rotationOffset : Float;
 	var zOffset: Float;
 	var dontRepeatMesh : Bool;
+	var orientTerrain : Float;
 }
 
 
@@ -221,6 +222,11 @@ class MeshSpray extends Object3D {
 	}
 
 	override function save() {
+
+		// prevent saving preview
+		if( previewModels.length > 0 )
+			sceneEditor.deleteElements(previewModels, () -> { }, false);
+
 		var obj : Dynamic = super.save();
 		obj.meshes = meshes;
 		obj.currentPresetName = currentPresetName;
@@ -240,7 +246,8 @@ class MeshSpray extends Object3D {
 			rotation: 184,
 			rotationOffset: 0,
 			zOffset: 0,
-			dontRepeatMesh: true
+			dontRepeatMesh: true,
+			orientTerrain : 0,
 		};
 	}
 
@@ -270,27 +277,42 @@ class MeshSpray extends Object3D {
 		sys.io.File.saveContent(MESH_SPRAY_CONFIG_PATH, hide.Ide.inst.toJSON(allSetGroups));
 	}
 
+	function setGroundPos( ectx : EditContext, obj : Object3D ) {
+		var pos = obj.getAbsPos();
+		var config = currentConfig;
+		var tz = ectx.positionToGroundZ(pos.tx, pos.ty);
+		var mz = config.zOffset + tz - pos.tz;
+		obj.z += mz;
+		var orient = config.orientTerrain;
+
+		var r = config.radius * 0.2;
+		inline function getPoint(dx,dy) {
+			var dz = ectx.positionToGroundZ(pos.tx + r * dx, pos.ty + r * dy) - tz;
+			return new h3d.col.Point(r * dx, r * dy, dz * orient);
+		}
+
+		var px0 = getPoint(-1,0);
+		var py0 = getPoint(0, -1);
+		var px1 = getPoint(1, 0);
+		var py1 = getPoint(0, 1);
+		var n = px1.cross(py1).add(py1.cross(px0)).add(px0.cross(py0)).add(py0.cross(px1)).normalized();
+		var q = new h3d.Quat();
+		q.initNormal(n);
+		var m = q.toMatrix();
+		m.prependRotation(0,0,  (config.rotation + (Std.random(2) == 0 ? -1 : 1) * Math.round(Math.random() * config.rotationOffset)) * Math.PI / 180);
+		var a = m.getEulerAngles();
+		obj.rotationX = hxd.Math.fmt(a.x * 180 / Math.PI);
+		obj.rotationY = hxd.Math.fmt(a.y * 180 / Math.PI);
+		obj.rotationZ = hxd.Math.fmt(a.z * 180 / Math.PI);
+	}
+
 	var wasEdited = false;
 	var previewModels : Array<hrt.prefab.Prefab> = [];
 	override function edit( ectx : EditContext ) {
-		if ( x != 0 || y != 0 ) {
-			// move meshSpray to origin
-			for (c in this.children) {
-				var obj3d = Std.downcast(c, Object3D);
-				if (obj3d != null) {
-					obj3d.x += x;
-					obj3d.y += y;
-					obj3d.updateInstance(ectx.getContext(obj3d));
-				}
-			}
-			x = 0;
-			y = 0;
-			updateInstance(ectx.getContext(this));
-		}
-		if (invParent == null) {
-			invParent = getTransform().clone();
-			invParent.invert();
-		}
+
+		invParent = getAbsPos().clone();
+		invParent.invert();
+
 		if (defaultConfig == null) defaultConfig = getDefaultConfig();
 		if (sceneEditor == null) {
 			allSetGroups = if( sys.FileSystem.exists(MESH_SPRAY_CONFIG_PATH) )
@@ -548,6 +570,7 @@ class MeshSpray extends Object3D {
 				<input type="button" value="Add" id="add"/>
 				<input type="button" value="Remove" id="remove"/>
 				<input type="button" value="Remove all meshes" id="clean"/>
+				<input type="button" value="Set to Ground" id="toground"/>
 			</div>
 			<p align="center">
 				<label><input type="checkbox" id="repeatMesh" style="margin-right: 5px;"/> Don\'t repeat same mesh in a row</label>
@@ -579,6 +602,17 @@ class MeshSpray extends Object3D {
 				}
 			});
 		});
+
+		options.find("#toground").click(function(_) {
+			for( c in children ) {
+				var obj = c.to(Object3D);
+				if( obj == null ) continue;
+				setGroundPos(ectx, obj);
+				var ctx = ectx.getContext(obj);
+				if( ctx != null ) obj.applyTransform(ctx.local3d);
+			}
+		});
+
 		options.find("#remove").click(function(_) {
 			var options = selectElement.children().elements();
 			for (opt in options) {
@@ -614,13 +648,16 @@ class MeshSpray extends Object3D {
 				{ name: "scaleOffset", t: PFloat(0, 1), def: currentConfig.scaleOffset },
 				{ name: "rotation", t: PFloat(0, 180), def: currentConfig.rotation },
 				{ name: "rotationOffset", t: PFloat(0, 30), def: currentConfig.rotationOffset },
-				{ name: "zOffset", t: PFloat(0, 10), def: currentConfig.zOffset }
+				{ name: "zOffset", t: PFloat(0, 10), def: currentConfig.zOffset },
+				{ name: "orientTerrain", t: PFloat(0, 1), def: currentConfig.orientTerrain },
 			]));
 		ectx.properties.add(optionsGroup, this, function(pname) {
 			var value = sceneEditor.properties.element.find("input[field="+ pname + "]").val();
 			Reflect.setField(currentConfig, pname, Std.parseFloat(value));
 			saveConfigMeshBatch();
 		});
+
+		super.edit(ectx);
 	}
 
 	function updateConfig() {
@@ -721,14 +758,12 @@ class MeshSpray extends Object3D {
 		}
 		lastPos = point;
 		if (nbMeshesToPlace > 0) {
-			var random = new hxd.Rand(Std.random(0xFFFFFF));
-
 			while (nbMeshesToPlace-- > 0) {
 				var nbTry = 5;
 				var position : h3d.col.Point;
 				do {
-					var randomRadius = CONFIG.radius*Math.sqrt(random.rand());
-					var angle = random.rand() * 2*Math.PI;
+					var randomRadius = CONFIG.radius*Math.sqrt(Math.random());
+					var angle = Math.random() * 2*Math.PI;
 
 					position = new h3d.col.Point(point.x + randomRadius*Math.cos(angle), point.y + randomRadius*Math.sin(angle), 0);
 					var vecRelat = position.toVector();
@@ -746,12 +781,6 @@ class MeshSpray extends Object3D {
 					}
 				} while (nbTry-- > 0);
 
-				var randRotationOffset = random.rand() * CONFIG.rotationOffset;
-				if (Std.random(2) == 0) {
-					randRotationOffset *= -1;
-				}
-				var rotationZ = ((CONFIG.rotation  + randRotationOffset) % 360)/360 * 2*Math.PI;
-
 				var meshId = 0;
 				if(currentMeshes.length > 1) {
 					do
@@ -780,21 +809,22 @@ class MeshSpray extends Object3D {
 
 				newPrefab.name = extractMeshName(meshUsed.path);
 
-				localMat.initRotationZ(rotationZ);
+				localMat.identity();
 
-				var randScaleOffset = random.rand() * CONFIG.scaleOffset;
+				var randScaleOffset = Math.random() * CONFIG.scaleOffset;
 				if (Std.random(2) == 0) {
 					randScaleOffset *= -1;
 				}
-				var currentScale = (CONFIG.scale + randScaleOffset);
+				var currentScale = hxd.Math.fmt(CONFIG.scale + randScaleOffset);
 
 				localMat.scale(currentScale, currentScale, currentScale);
 
 				position.z = ectx.positionToGroundZ(position.x, position.y) + CONFIG.zOffset;
-				localMat.setPosition(new Vector(position.x, position.y, position.z));
+				localMat.setPosition(new Vector(hxd.Math.fmt(position.x), hxd.Math.fmt(position.y), position.z));
 				localMat.multiply(localMat, invParent);
 
 				newPrefab.setTransform(localMat);
+				setGroundPos(ectx, newPrefab);
 
 				previewModels.push(newPrefab);
 				currentPivots.push(new h2d.col.Point(newPrefab.x, newPrefab.y));
@@ -844,11 +874,13 @@ class MeshSpray extends Object3D {
 			gBrushes = [];
 			var gBrush = new h3d.scene.Mesh(makePrimCircle(32, 0.95), ctx.local3d);
 			gBrush.scaleX = gBrush.scaleY = radius;
+			gBrush.ignoreParentTransform = true;
 			gBrush.material.mainPass.setPassName("overlay");
 			gBrush.material.shadows = false;
 			gBrush.material.color = newColor;
 			gBrushes.push(gBrush);
 			gBrush = new h3d.scene.Mesh(new h3d.prim.Sphere(Math.min(radius*0.05, 0.35)), ctx.local3d);
+			gBrush.ignoreParentTransform = true;
 			gBrush.material.mainPass.setPassName("overlay");
 			gBrush.material.shadows = false;
 			gBrush.material.color = newColor;