Browse Source

Snap objects onto ground

trethaller 7 years ago
parent
commit
a6dccbcc4c

+ 3 - 0
bin/defaultProps.json

@@ -38,6 +38,9 @@
 	// paths to look files/shaders into - relative to project root
 	"haxe.classPath" : ["src"],
 
+	// l3d config
+	"l3d.groundLayer": "ground",
+	"l3d.cdbLevel": "level",
 
 	// reserved for internal ide usage
 	"hide" : {}

+ 2 - 2
hide/Renderer.hx

@@ -9,7 +9,7 @@ class MaterialSetup extends h3d.mat.MaterialSetup {
 class Renderer extends h3d.scene.DefaultRenderer {
 
 	override function render() {
-		renderPass(defaultPass, getSort("ground", true) );
+		renderPass(defaultPass, getSort("debuggeom", true) );
 		clear(null, 1.0);
 
 		if( has("shadow") )
@@ -24,7 +24,7 @@ class Renderer extends h3d.scene.DefaultRenderer {
 		renderPass(defaultPass, getSort("default", true) );
         renderPass(defaultPass, get("outline"));
 		renderPass(defaultPass, get("outlined"));
-		renderPass(defaultPass, getSort("ground_alpha"));
+		renderPass(defaultPass, getSort("debuggeom_alpha"));
 		renderPass(defaultPass, getSort("alpha") );
 		renderPass(defaultPass, get("additive") );
 		renderPass(defaultPass, getSort("ui", true));

+ 10 - 0
hide/prefab/Prefab.hx

@@ -166,4 +166,14 @@ class Prefab {
 	public function to<T:Prefab>( c : Class<T> ) : Null<T> {
 		return Std.instance(this, c);
 	}
+
+	public function getParent<T:Prefab>( c : Class<T> ) : Null<T> {
+		var p = parent;
+		while(p != null) {
+			var inst = Std.instance(p, c);
+			if(inst != null) return inst;
+			p = p.parent;
+		}
+		return null;
+	}
 }

+ 2 - 12
hide/prefab/l3d/Instance.hx

@@ -24,7 +24,7 @@ class Instance extends Object3D {
 	override function makeInstance(ctx:Context):Context {
 		#if editor
 		var ctx = super.makeInstance(ctx);
-		var parentLayer = getParentLayer();
+		var parentLayer = getParent(Layer);
 		if(parentLayer != null) {
 			var sheet = parentLayer.getCdbModel();			
 			if(sheet != null) {
@@ -78,7 +78,7 @@ class Instance extends Object3D {
 			</div>
 		'),this);
 
-		var parentLayer = getParentLayer();
+		var parentLayer = getParent(Layer);
 		if(parentLayer == null) return;
 
 		var sheet = parentLayer.getCdbModel();
@@ -97,16 +97,6 @@ class Instance extends Object3D {
 		}
 	}
 
-	function getParentLayer() {
-		var p = parent;
-		while(p != null) {
-			var layer = p.to(hide.prefab.l3d.Layer);
-			if(layer != null) return layer;
-			p = p.parent;			
-		}
-		return null;
-	}
-
 	override function getHideProps() {
 		return { icon : "circle", name : "Instance", fileSource : null };
 	}

+ 2 - 1
hide/prefab/l3d/Layer.hx

@@ -22,7 +22,8 @@ class Layer extends Object3D {
 	}
 
 	public function getLevelSheet() {
-		return hide.ui.Ide.inst.database.getSheet("level");
+		var ide = hide.ui.Ide.inst;
+		return ide.database.getSheet(ide.currentProps.get("l3d.cdbLevel", "level"));
 	}
 	
 	override function save() {

+ 11 - 4
hide/prefab/l3d/Polygon.hx

@@ -4,8 +4,14 @@ import h3d.col.Point;
 class Polygon extends Object3D {
 
 	var data : Array<Float> = null;
-	var mesh : h3d.scene.Mesh = null;
+	public var mesh(default, null) : h3d.scene.Mesh = null;
 
+	public function setColor(col: Int) {
+		if(mesh != null) {
+			mesh.material.color.setColor(col | (80 << 24));
+		}
+	}
+	
 	override function save() {
 		var obj : Dynamic = super.save();
 		obj.data = data;
@@ -19,6 +25,7 @@ class Polygon extends Object3D {
 
 	override function makeInstance(ctx:Context):Context {
 		ctx = ctx.clone(this);
+		var layer = getParent(Layer);
 		var points = [];
 		var d = this.data;
 		if(d == null) {
@@ -44,13 +51,13 @@ class Polygon extends Object3D {
 		var obj = new h3d.scene.Object(ctx.local3d);
 		mesh = new h3d.scene.Mesh(prim, obj);
 		var mat = mesh.material;
-		mat.color.setColor(0x40ff00ff);
+		mat.color.setColor(layer != null ? (layer.color | 0x40000000) : 0x40ff00ff);
 		mat.mainPass.culling = None;
-		mat.mainPass.setPassName("ground");
+		mat.mainPass.setPassName("debuggeom");
 		mat.mainPass.setBlendMode(Alpha);
 		mat.mainPass.depthWrite = true;
 
-		var alpha = mat.allocPass("ground_alpha");
+		var alpha = mat.allocPass("debuggeom_alpha");
 		alpha.setBlendMode(Alpha);
 		alpha.depthWrite = false;
 		mat.shadows = false;

+ 4 - 2
hide/ui/Props.hx

@@ -79,8 +79,10 @@ class Props {
 		}
 	}
 
-	public function get( key : String ) : Dynamic {
-		return Reflect.field(current,key);
+	public function get( key : String, ?defaultVal : Dynamic ) : Dynamic {
+		var val = Reflect.field(current,key);
+		if(val != null) return val;
+		return defaultVal; 
 	}
 
 	public static function loadForProject( projectPath : String, resourcePath : String ) {

+ 3 - 2
hide/view/l3d/Gizmo.hx

@@ -29,13 +29,14 @@ class Gizmo extends h3d.scene.Object {
 
 	var updateFunc: Float -> Void;
 
-	public var onStartMove: Void -> Void;
+	public var onStartMove: TransformMode -> Void;
 	public var onMove: h3d.Vector -> h3d.Quat -> h3d.Vector -> Void;
 	public var onFinishMove: Void -> Void;
 	public var moving(default, null): Bool;
 
 	var debug: h3d.scene.Graphics;
 	var isScaling = false;
+	var snapGround = false;
 	var intOverlay : h2d.Interactive;
 
 	public function new(scene: hide.comp.Scene) {
@@ -95,7 +96,7 @@ class Gizmo extends h3d.scene.Object {
 
 	public function startMove(mode: TransformMode, ?duplicating=false) {
 		moving = true;
-		if(onStartMove != null) onStartMove();
+		if(onStartMove != null) onStartMove(mode);
 		var startMat = getAbsPos().clone();
 		var startPos = getAbsPos().pos().toPoint();
 		var dragPlane = null;

+ 38 - 11
hide/view/l3d/Level3D.hx

@@ -204,7 +204,7 @@ class Level3D extends FileView {
 
 	function setupGizmo() {
 		if(curEdit == null) return;
-		gizmo.onStartMove = function() {
+		gizmo.onStartMove = function(mode) {
 			var objects = curEdit.rootObjects;
 			var pivotPt = getPivot(objects);
 			var pivot = new h3d.Matrix();
@@ -220,7 +220,7 @@ class Level3D extends FileView {
 
 			var objects3d = [for(e in curEdit.elements) e.to(Object3D)];
 			var prevState = [for(o in objects3d) o.save()];			
-			
+			var snapGround = mode == MoveXY;
 			gizmo.onMove = function(translate: h3d.Vector, rot: h3d.Quat, scale: h3d.Vector) {
 				var transf = new h3d.Matrix();
 				transf.identity();
@@ -232,6 +232,9 @@ class Level3D extends FileView {
 					var newMat = localMats[i].clone();
 					newMat.multiply(newMat, transf);
 					newMat.multiply(newMat, pivot);
+					if(snapGround) {
+						newMat.tz = getZ(newMat.tx, newMat.ty);
+					}
 					var invParent = objects[i].parent.getAbsPos().clone();
 					invParent.invert();
 					newMat.multiply(newMat, invParent);
@@ -316,9 +319,9 @@ class Level3D extends FileView {
 			targetPt = curEdit.rootObjects[0].getAbsPos().pos().toPoint();
 		}
 		if(top) 
-			cameraController.set(50, Math.PI/2, 0.001, targetPt);
+			cameraController.set(200, Math.PI/2, 0.001, targetPt);
 		else
-			cameraController.set(50, -4.7, 0.8, targetPt);
+			cameraController.set(200, -4.7, 0.8, targetPt);
 		cameraController.toTarget();
 	}
 
@@ -1015,17 +1018,19 @@ class Level3D extends FileView {
 		}
 		var layer = p.to(hide.prefab.l3d.Layer);
 		if(layer != null) {
-			var boxes = layer.getAll(hide.prefab.Box);
-			for(box in boxes) {
+			var obj3ds = layer.getAll(hide.prefab.Object3D);
+			for(obj in obj3ds) {
+				var i = interactives.get(obj);
+				if(i != null) i.visible = !layer.locked;
+			}
+			for(box in layer.getAll(hide.prefab.Box)) {
 				box.setColor(layer.color);
-				interactives.get(box).visible = !layer.locked;				
 			}
-
-			var models = layer.getAll(hide.prefab.Model);
-			for(m in models) {
-				interactives.get(m).visible = !layer.locked;
+			for(poly in layer.getAll(hide.prefab.l3d.Polygon)) {
+				poly.setColor(layer.color);
 			}
 		}
+
 		var model = p.to(hide.prefab.Model);
 		if(model != null && pname == "source") {
 			refresh();
@@ -1036,6 +1041,28 @@ class Level3D extends FileView {
 		updateTreeStyle(p, el);
 	}
 
+	function getZ(x: Float, y: Float) {
+		var gname = props.get("l3d.groundLayer");
+		var groundLayer = data.get(Layer, gname);
+		var polygons = groundLayer.getAll(hide.prefab.l3d.Polygon);
+		var offset = 1000;
+		var ray = h3d.col.Ray.fromValues(x, y, offset, 0, 0, -1);
+		var topPoly = null;
+		var topDist = 1e10;
+		for(polygon in polygons) {
+			var collider = polygon.mesh.getGlobalCollider();
+			var d = collider.rayIntersection(ray, true);
+			if(d > 0 && d < topDist) {
+				topDist = d;
+				topPoly = polygon;
+			}
+		}
+		if(topPoly != null) {
+			return offset - topDist;
+		}
+		return 0.;
+	}
+
 	static function worldMat(obj: Object) {
 		if(obj.defaultTransform != null) {
 			var m = obj.defaultTransform.clone();