Browse Source

more prefab work: added resource, group, unknown, in-place reload

ncannasse 7 years ago
parent
commit
b7ac104088
9 changed files with 170 additions and 27 deletions
  1. 2 1
      .gitignore
  2. 10 0
      haxelib.json
  3. 18 0
      hide/prefab/Group.hx
  4. 8 0
      hide/prefab/Library.hx
  5. 50 21
      hide/prefab/Noise.hx
  6. 35 3
      hide/prefab/Prefab.hx
  7. 16 0
      hide/prefab/Resource.hx
  8. 22 0
      hide/prefab/Unknown.hx
  9. 9 2
      hide/view/Prefab.hx

+ 2 - 1
.gitignore

@@ -2,4 +2,5 @@
 /bin/*.min.css
 /dump
 /bin/*.json
-/bin/hide.js
+/bin/hide.js
+*.lnk

+ 10 - 0
haxelib.json

@@ -0,0 +1,10 @@
+{
+	"name" : "hide",
+	"url" : "https://github.com/heapsio/hide",
+	"license" : "BSD",
+    "description" : "Heaps IDE",
+    "version" : "0.1.0",
+	"releasenote" : "",
+	"contributors" : ["ncannasse"],
+	"dependencies" : { "heaps" : "" }
+}

+ 18 - 0
hide/prefab/Group.hx

@@ -0,0 +1,18 @@
+package hide.prefab;
+
+class Group extends Prefab {
+
+	override function load(v:Dynamic) {
+	}
+
+	override function save() {
+		return {};
+	}
+
+	override function getHideProps():HideProps {
+		return { name : "Group", icon : "folder" };
+	}
+
+	static var _ = Library.register("group", Group);
+
+}

+ 8 - 0
hide/prefab/Library.hx

@@ -12,12 +12,20 @@ class Library extends Prefab {
 	// hacks to use directly non-recursive api
 
 	override function load( obj : Dynamic ) {
+		if( inRec )
+			return;
 		var children : Array<Dynamic> = obj.children;
 		if( children != null )
 			for( v in children )
 				Prefab.loadRec(v, this);
 	}
 
+	override function reload(v:Dynamic) {
+		inRec = true;
+		super.reload(v);
+		inRec = false;
+	}
+
 	override function save() {
 		if( inRec )
 			return {};

+ 50 - 21
hide/prefab/NoiseGen.hx → hide/prefab/Noise.hx

@@ -1,8 +1,8 @@
 package hide.prefab;
 
-class NoiseGen extends Prefab {
+class Noise extends Prefab {
 
-	static var DEFAULT_SEED = 42;
+	public var seed : Int = Std.random(10000);
 
 	public var scale : Float = 1.;
 	public var channels : Int = 1;
@@ -19,26 +19,32 @@ class NoiseGen extends Prefab {
 	public var offset : Float = 0.5;
 	public var turbulence : Float = 0.;
 	public var turbulenceScale : Float = 1.;
+	public var inverse : Bool;
+
+	var tex : h3d.mat.Texture;
 
 	override public function load(v:Dynamic) {
+		this.seed = v.seed;
 		this.size = v.size;
 		this.scale = v.scale;
-		if( v.channels != null ) this.channels = v.channels;
+		if( v.channels != null ) this.channels = v.channels else this.channels = 1;
 		this.octaves = v.octaves;
 		this.persist = v.persist;
 		this.lacunarity = v.lacunarity;
 		this.ridged = v.ridged;
 		if( v.gain != null ) this.gain = v.gain;
 		if( v.offset != null ) this.offset = v.offset;
-		if( v.contrast != null ) this.contrast = v.contrast;
-		if( v.brightness != null ) this.brightness = v.brightness;
-		if( v.normals != null ) this.normals = v.normals;
-		if( v.turbulence != null ) this.turbulence = v.turbulence;
+		if( v.contrast != null ) this.contrast = v.contrast else this.contrast = 0;
+		if( v.brightness != null ) this.brightness = v.brightness else this.brightness = 0;
+		if( v.normals != null ) this.normals = v.normals else this.normals = false;
+		if( v.turbulence != null ) this.turbulence = v.turbulence else this.turbulence = 0;
 		if( v.turbulenceScale != null ) this.turbulenceScale = v.turbulenceScale;
+		if( v.inverse != null ) this.inverse = v.inverse else this.inverse = false;
 	}
 
 	override function save() {
 		var o : Dynamic = {
+			seed : seed,
 			size : size,
 			scale : scale,
 			octaves : octaves,
@@ -62,10 +68,12 @@ class NoiseGen extends Prefab {
 			o.turbulence = turbulence;
 			o.turbulenceScale = turbulenceScale;
 		}
+		if( inverse )
+			o.inverse = inverse;
 		return o;
 	}
 
-	public function updateTexture( t : h3d.mat.Texture, seed : Int ) {
+	public function updateTexture( t : h3d.mat.Texture ) {
 		var e = h3d.Engine.getCurrent();
 		e.pushTarget(t);
 		@:privateAccess e.flushTarget();
@@ -85,6 +93,7 @@ class NoiseGen extends Prefab {
 		pass.shader.contrast = contrast;
 		pass.shader.brightness = brightness;
 		pass.shader.normals = normals;
+		pass.shader.inverse = inverse ? 1 : 0;
 
 		pass.shader.turbulence = turbulence * 16 / size;
 		pass.shader.turbulenceScale = turbulenceScale;
@@ -94,12 +103,19 @@ class NoiseGen extends Prefab {
 		e.popTarget();
 	}
 
-	public function makeTexture( ?size, ?seed ) {
-		if( seed == null ) seed = DEFAULT_SEED;
-		if( size == null ) size = this.size;
-		var t = new h3d.mat.Texture(size, size, [Target]);
-		updateTexture(t, seed);
-		return t;
+	public function toTexture() {
+		if( tex != null )
+			return tex;
+		tex = new h3d.mat.Texture(size, size, [Target]);
+		if( !tex.flags.has(IsNPOT) ) tex.wrap = Repeat;
+		updateTexture(tex);
+		tex.realloc = function() updateTexture(tex);
+		return tex;
+	}
+
+	override function reload(p:Dynamic) {
+		if( tex != null ) tex.dispose();
+		super.reload(p);
 	}
 
 	function makeTile( tex : h3d.mat.Texture ) {
@@ -111,10 +127,14 @@ class NoiseGen extends Prefab {
 	}
 
 	override function makeInstance( ctx : Context ) {
-		var tex = makeTexture();
+		var tex = new h3d.mat.Texture(size, size, [Target]);
+		updateTexture(tex);
 		ctx = ctx.clone(this);
 		var bmp = new h2d.Bitmap(makeTile(tex), ctx.local2d);
 		bmp.tileWrap = !tex.flags.has(IsNPOT);
+		bmp.visible = false;
+		bmp.x = -size >> 1;
+		bmp.y = -size >> 1;
 		ctx.local2d = bmp;
 		ctx.shared.cleanups.push(tex.dispose);
 		return ctx;
@@ -154,9 +174,11 @@ class NoiseGen extends Prefab {
 			<dl>
 				<dt>Contrast</dt><dd><input type="range" min="-1" max="1" field="contrast"/></dd>
 				<dt>Brightness</dt><dd><input type="range" min="-1" max="1" field="brightness"/></dd>
+				<dt>Inverse</dt><dd><input type="checkbox" field="inverse"/></dd>
 			</dl>
 			<br/>
 			<dl>
+				<dt>Seed</dt><dd><input type="range" step="1" min="0" max="9999" field="seed"/></dd>
 				<dt>&nbsp;</dt><dd><input type="button" value="Download" name="dl"/></dd>
 			</dl>
 		'),this,function(_) {
@@ -166,9 +188,14 @@ class NoiseGen extends Prefab {
 				tex.resize(size, size);
 				bmp.tile = makeTile(tex);
 				bmp.tileWrap = !tex.flags.has(IsNPOT);
+				bmp.x = -size >> 1;
+				bmp.y = -size >> 1;
 			}
-			updateTexture(tex, DEFAULT_SEED);
+			updateTexture(tex);
 		});
+		var bmp = cast(ctx.getContext(this).local2d, h2d.Bitmap);
+		bmp.visible = true;
+		ctx.cleanups.push(function() bmp.visible = false);
 		e.find("[name=dl]").click(function(_) {
 			ctx.ide.chooseFileSave("noise.png", function(f) if( f != null ) {
 				try {
@@ -182,7 +209,7 @@ class NoiseGen extends Prefab {
 		#end
 	}
 
-	static var _ = Library.register("noise", NoiseGen);
+	static var _ = Library.register("noise", Noise);
 
 }
 
@@ -194,23 +221,23 @@ class NoiseShader extends h3d.shader.ScreenShader {
 
 		@const var channels : Int = 1;
 		@const var octaves : Int = 1;
+		@const var ridged : Bool;
+		@const var normals : Bool;
 
 		@param var seed : Int;
 		@param var scale : Float = 8;
 		@param var persist : Float = 0.5;
 		@param var lacunarity : Float = 2.0;
 
-		@const var ridged : Bool;
 		@param var gain : Float;
 		@param var offset : Float;
+		@param var inverse : Float;
 
 		@param var contrast : Float;
 		@param var brightness : Float;
 		@param var turbulence : Float;
 		@param var turbulenceScale : Float;
 
-		@const var normals : Bool;
-
 		function perturb( uv : Vec2, scale : Float, seed : Int ) : Vec2 {
 			if( turbulence > 0. ) {
 				var turbScaleRepeat = int(scale * turbulenceScale * 0.5) * 2.;
@@ -266,7 +293,9 @@ class NoiseShader extends h3d.shader.ScreenShader {
 					scale *= lacunarity;
 				}
 			}
-			return (v * (1 + contrast) + 1) * 0.5 + brightness;
+			v = (v * (1 + contrast) + 1) * 0.5 + brightness;
+			if( inverse > 0 ) v = 1 - v;
+			return v;
 		}
 
 		function calcNormal() : Vec3 {

+ 35 - 3
hide/prefab/Prefab.hx

@@ -66,9 +66,34 @@ class Prefab {
 		return obj;
 	}
 
+	public function reload( p : Dynamic ) {
+		load(p);
+		var childData : Array<Dynamic> = p.children;
+		if( childData == null ) {
+			if( this.children.length > 0 ) this.children = [];
+			return;
+		}
+		var curChild = new Map();
+		for( c in children )
+			curChild.set(c.name, c);
+		var newchild = [];
+		for( v in childData ) {
+			var name : String = v.name;
+			var prev = curChild.get(name);
+			if( prev != null && prev.type == v.type ) {
+				curChild.remove(name);
+				prev.reload(v);
+				newchild.push(prev);
+			} else {
+				newchild.push(loadRec(v,this));
+			}
+		}
+		children = newchild;
+	}
+
 	public static function loadRec( v : Dynamic, ?parent : Prefab ) {
 		var pcl = @:privateAccess Library.registeredElements.get(v.type);
-		if( pcl == null ) throw "Unregistered prefab " + v.type;
+		if( pcl == null ) pcl = hide.prefab.Unknown;
 		var p = Type.createInstance(pcl, [parent]);
 		p.type = v.type;
 		p.name = v.name;
@@ -103,15 +128,22 @@ class Prefab {
 		return null;
 	}
 
-	public function get<T:Prefab>( cl : Class<T>, ?name : String ) : T {
+	public function getOpt<T:Prefab>( cl : Class<T>, ?name : String ) : T {
 		for( c in children ) {
 			if( (name == null || c.name == name) && Std.is(c, cl) )
 				return cast c;
-			var p = c.get(cl, name);
+			var p = c.getOpt(cl, name);
 			if( p != null )
 				return p;
 		}
 		return null;
 	}
 
+	public function get<T:Prefab>( cl : Class<T>, ?name : String ) : T {
+		var v = getOpt(cl, name);
+		if( v == null )
+			throw "Missing prefab " + (name == null ? Type.getClassName(cl) : (cl == null ? name : name+"(" + Type.getClassName(cl) + ")"));
+		return v;
+	}
+
 }

+ 16 - 0
hide/prefab/Resource.hx

@@ -0,0 +1,16 @@
+package hide.prefab;
+
+class Resource extends hxd.res.Resource {
+
+	var lib : Library;
+
+	public function load() : Library {
+		if( lib != null )
+			return lib;
+		lib = new Library();
+		lib.load(haxe.Json.parse(entry.getText()));
+		watch(function() lib.reload(haxe.Json.parse(entry.getText())));
+		return lib;
+	}
+
+}

+ 22 - 0
hide/prefab/Unknown.hx

@@ -0,0 +1,22 @@
+package hide.prefab;
+
+class Unknown extends Prefab {
+
+	var data : Dynamic;
+
+	override function load(v:Dynamic) {
+		this.data = v;
+	}
+
+	override function save() {
+		return data;
+	}
+
+	override function edit(ctx:EditContext) {
+		#if editor
+		ctx.properties.add(new hide.Element('<font color="red">Unknown prefab $type</font>'));
+		#end
+	}
+
+	// do not register
+}

+ 9 - 2
hide/view/Prefab.hx

@@ -116,8 +116,8 @@ class Prefab extends FileView {
 
 	function resetCamera() {
 		var bounds = context.shared.root2d.getBounds();
-		context.shared.root2d.x = -(Std.int(bounds.width) >> 1);
-		context.shared.root2d.y = -(Std.int(bounds.height) >> 1);
+		context.shared.root2d.x = -Std.int(bounds.xMin + bounds.width * 0.5);
+		context.shared.root2d.y = -Std.int(bounds.yMin + bounds.height * 0.5);
 		scene.resetCamera(context.shared.root3d, 1.5);
 		control.loadFromCamera();
 	}
@@ -272,8 +272,15 @@ class Prefab extends FileView {
 				} },
 			]);
 		});
+		tree.allowRename = true;
 		tree.init();
 		tree.onClick = selectObject;
+		tree.onRename = function(e, name) {
+			var oldName = e.name;
+			e.name = name;
+			undo.change(Field(e, "name", oldName), function() tree.refresh());
+			return true;
+		};
 		scene.onResize = function() {
 			scene.s2d.x = scene.s2d.width >> 1;
 			scene.s2d.y = scene.s2d.height >> 1;