Explorar o código

Update FXEditor and Emitter

ShiroSmith %!s(int64=6) %!d(string=hai) anos
pai
achega
920bea6da1

+ 5 - 1
hide/prefab/fx/Emitter.hx

@@ -186,6 +186,8 @@ private class ParticleInstance extends h3d.scene.Object {
 @:allow(hide.prefab.fx.Emitter)
 class EmitterObject extends h3d.scene.Object {
 
+	public var enable : Bool;
+
 	public var particleTemplate : hide.prefab.Object3D;
 	public var maxCount = 20;
 	public var lifeTime = 2.0;
@@ -232,6 +234,7 @@ class EmitterObject extends h3d.scene.Object {
 	var instances : Array<ParticleInstance> = [];
 
 	public function reset() {
+		enable = true;
 		random.init(randomSeed);
 		curTime = 0.0;
 		lastTime = 0.0;
@@ -385,7 +388,8 @@ class EmitterObject extends h3d.scene.Object {
 
 		var emitTarget = evaluator.getSum(emitRate, curTime);
 		var delta = hxd.Math.ceil(emitTarget - emitCount);
-		doEmit(delta);
+		if(enable)
+			doEmit(delta);
 
 		var i = instances.length;
 		while (i-- > 0) {

+ 41 - 16
hide/prefab/fx/FX.hx

@@ -47,14 +47,20 @@ typedef ObjectAnimation = {
 
 class FXAnimation extends h3d.scene.Object {
 
+	public var onEnd : Void -> Void;
+
+	public var playSpeed : Float;
+	public var localTime(default, null) : Float = 0.0;
+	public var worldTime(default, null) : Float = 0.0;
 	public var duration : Float;
+
 	public var loopAnims : Bool;
 	public var objects: Array<ObjectAnimation> = [];
 	public var shaderAnims : Array<ShaderAnimation> = [];
 	public var emitters : Array<hide.prefab.fx.Emitter.EmitterObject> = [];
 	public var contraints : Array<hide.prefab.Constraint> = [];
-	public var currentTime(default, null) : Float = 0.0;
 	public var script : hide.prefab.fx.FXScript;
+
 	var evaluator : Evaluator;
 	var random : hxd.Rand;
 
@@ -63,6 +69,7 @@ class FXAnimation extends h3d.scene.Object {
 		random = new hxd.Rand(Std.random(0xFFFFFF));
 		evaluator = new Evaluator(random);
 		name = "FXAnimation";
+		setTime(0,0);
 	}
 
 	override function onRemove() {
@@ -80,20 +87,33 @@ class FXAnimation extends h3d.scene.Object {
 		}
 	}
 
+	override function sync( ctx : h3d.scene.RenderContext ) {
+		super.sync(ctx);
+		#if !editor
+		worldTime += ctx.elapsedTime;
+		localTime += ctx.elapsedTime * playSpeed;
+		setTime(localTime, worldTime);
+
+		if(localTime >duration && duration != 0 /*Infinite*/) {
+			if(onEnd != null )
+				onEnd();
+		}
+		#end
+	}
+
 	static var tempMat = new h3d.Matrix();
-	public function setTime(time: Float) {
-		currentTime = time;
+	public function setTime( localTime : Float, worldTime : Float ) {
 		for(anim in objects) {
 			var m = tempMat;
 			if(anim.scale != null) {
-				var scale = evaluator.getVector(anim.scale, time);
+				var scale = evaluator.getVector(anim.scale, localTime);
 				m.initScale(scale.x, scale.y, scale.z);
 			}
 			else
 				m.identity();
 
 			if(anim.rotation != null) {
-				var rotation = evaluator.getVector(anim.rotation, time);
+				var rotation = evaluator.getVector(anim.rotation, localTime);
 				rotation.scale3(Math.PI / 180.0);
 				m.rotate(rotation.x, rotation.y, rotation.z);
 			}
@@ -105,14 +125,14 @@ class FXAnimation extends h3d.scene.Object {
 			m.translate(offset.x, offset.y, offset.z);
 
 			if(anim.position != null) {
-				var pos = evaluator.getVector(anim.position, time);
+				var pos = evaluator.getVector(anim.position, localTime);
 				m.translate(pos.x, pos.y, pos.z);
 			}
 
 			anim.obj.setTransform(m);
 
 			if(anim.visibility != null)
-				anim.obj.visible = anim.elt.visible && evaluator.getFloat(anim.visibility, time) > 0.5;
+				anim.obj.visible = anim.elt.visible && evaluator.getFloat(anim.visibility, localTime) > 0.5;
 
 			if(anim.color != null) {
 				var mesh = Std.instance(anim.obj, h3d.scene.Mesh);
@@ -120,16 +140,16 @@ class FXAnimation extends h3d.scene.Object {
 					var mat = mesh.material;
 					switch(anim.color) {
 						case VCurve(a):
-							mat.color.a = evaluator.getFloat(anim.color, time);
+							mat.color.a = evaluator.getFloat(anim.color, localTime);
 						default:
-							mat.color = evaluator.getVector(anim.color, time);
+							mat.color = evaluator.getVector(anim.color, localTime);
 					}
 				}
 			}
 		}
 
 		for(anim in shaderAnims) {
-			anim.setTime(time);
+			anim.setTime(localTime);
 		}
 
 		function setAnimFrame(object : h3d.scene.Object, time : Float){
@@ -147,14 +167,15 @@ class FXAnimation extends h3d.scene.Object {
 			for(i in 0...object.numChildren)
 				setAnimFrame(object.getChildAt(i), time);
 		}
-		setAnimFrame(this, time);
+		setAnimFrame(this, localTime);
 
 		for(em in emitters) {
 			if(em.visible)
-				em.setTime(time);
+				em.setTime(worldTime);
 		}
 
-		script.eval();
+		if(script != null)
+			script.eval();
 	}
 
 	public function resolveContraints( caster : h3d.scene.Object ) {
@@ -401,10 +422,14 @@ class FX extends hxd.prefab.Library {
 		getObjAnimations(ctx, this, fxanim.objects);
 		getShaderAnims(ctx, this, fxanim.shaderAnims);
 		getEmitters(ctx, this, fxanim.emitters);
-		var parser = new FXScriptParser();
-		var fxScript = parser.createFXScript(script, fxanim);
-		fxanim.script = fxScript;
 
+		if(script != ""){
+			var parser = new FXScriptParser();
+			var fxScript = parser.createFXScript(script, fxanim);
+			fxanim.script = fxScript;
+		}
+
+		fxanim.playSpeed = 1.0;
 
 		return ctx;
 	}

+ 24 - 7
hide/prefab/fx/FXScript.hx

@@ -36,7 +36,7 @@ class FXScript {
 	public function new(){
 	}
 
-	public function getGetter( p : String ) {
+	public function getGetter( p : String ) : Void -> Float {
 		var names = p.split('.');
 		var i = 0;
 		var root : h3d.scene.Object = fx;
@@ -54,18 +54,26 @@ class FXScript {
 			field += names[index];
 
 		return switch(field){
+			case "x": function(){ return curObj.x; };
+			case "y": function(){ return curObj.y; };
+			case "z": function(){ return curObj.z; };
+			case "visible": function(){ return curObj.visible ? 1.0 : 0.0; };
 			case "rotationX": function(){
 				return curObj.getRotationQuat().toEuler().x;}
 			case "rotationY": function(){
 				return curObj.getRotationQuat().toEuler().y;}
 			case "rotationZ": function(){
 				return curObj.getRotationQuat().toEuler().z;}
-			default:// function(){ if(Reflect.hasField(curObj, field)) Reflect.getProperty(curObj, field); };
-				return function(){ return 0.0; };
+			default: return function(){
+				if(Reflect.hasField(curObj, field)){
+					var p = Reflect.getProperty(curObj, field);
+					return cast(p, Float);
+				}
+				else return 0.0;};
 		}
 	}
 
-	public function getSetter( p : String ) {
+	public function getSetter( p : String ) : Float -> Void {
 		var names = p.split('.');
 		var i = 0;
 		var root : h3d.scene.Object = fx;
@@ -83,26 +91,35 @@ class FXScript {
 			field += names[index];
 
 		return switch(field){
+			case "x": function(v){ curObj.x = v; };
+			case "y": function(v){ curObj.y = v; };
+			case "z": function(v){ curObj.z = v; };
+			case "visible": function(v){ curObj.visible = v > 0; };
 			case "rotationX": function(v){
 				var euler = curObj.getRotationQuat().toEuler();
-				curObj.setRotation(v, euler.y, euler.z);};
+				curObj.setRotation(v, euler.y, euler.z); };
 			case "rotationY": function(v){
 				var euler = curObj.getRotationQuat().toEuler();
 				curObj.setRotation(euler.x, v, euler.z); };
 			case "rotationZ": function(v){
 				var euler = curObj.getRotationQuat().toEuler();
-				curObj.setRotation(euler.x, euler.y, v);};
-			default: function(v){ if(Reflect.hasField(curObj, field)) Reflect.setProperty(curObj, field, v); };
+				curObj.setRotation(euler.x, euler.y, v); };
+			default: function(v){
+				if(Reflect.hasField(curObj, field))
+					Reflect.setProperty(curObj, field, v); };
 		}
 	}
 
 	public function getVar( n : String ) : Float {
 		if(!myVars.exists(n))
 			return 0.0;
+		if(myVars[n] == null)
+			return 0.0;
 		return switch myVars[n]{
 			case Float(value): value;
 			case Int(value): value;
 			case Bool(value): value ? 1.0 : 0.0;
+			default : 0.0;
 		}
 	}
 

+ 10 - 5
hide/prefab/fx/FXScriptParser.hx

@@ -108,22 +108,26 @@ class FXScriptParser {
 						case "-": return Op( convert(e1), convert(e2), function(a,b) { return a - b; });
 						case "=": 	switch(getExpr(e1)){
 											case EIdent(v): return Set(function(val){ script.setVar(v, val); }, convert(e2));
-											case EField(e,f): return Set( getSetField(e), convert(e2));
+											case EField(e,f): return Set( getSetField(e1), convert(e2));
 											default: return null;
 										}
 						case "+=":  switch(getExpr(e1)){
 										case EIdent(v): return Set(function(val){ script.setVar(v, val); }, Op( convert(e1), convert(e2), function(a,b) { return a + b; }));
-										case EField(e,f): return Set( getSetField(e), Op( convert(e1), convert(e2), function(a,b) { return a + b; }));
+										case EField(e,f): return Set( getSetField(e1), Op( convert(e1), convert(e2), function(a,b) { return a + b; }));
 										default: return null;
 									}
 
 						case "-=":	switch(getExpr(e1)){
 										case EIdent(v): return Set(function(val){ script.setVar(v, val); }, Op( convert(e1), convert(e2), function(a,b) { return a - b; }));
-										case EField(e,f): return Set( getSetField(e), Op( convert(e1), convert(e2), function(a,b) { return a - b; }));
+										case EField(e,f): return Set( getSetField(e1), Op( convert(e1), convert(e2), function(a,b) { return a - b; }));
 										default: return null;
 									}
 						case "==": return Op( convert(e1), convert(e2), function(a,b) { return a == b ? 1.0 : 0.0; });
 						case "!=": return Op( convert(e1), convert(e2), function(a,b) { return a != b ? 1.0 : 0.0; });
+						case ">": return Op( convert(e1), convert(e2), function(a,b) { return a > b ? 1.0 : 0.0; });
+						case "<": return Op( convert(e1), convert(e2), function(a,b) { return a < b ? 1.0 : 0.0; });
+						case ">=": return Op( convert(e1), convert(e2), function(a,b) { return a >= b ? 1.0 : 0.0; });
+						case "<=": return Op( convert(e1), convert(e2), function(a,b) { return a <= b ? 1.0 : 0.0; });
 						default: return null;
 					}
 
@@ -368,8 +372,10 @@ class FXScriptParser {
 	public function generateUI( s : FXScript, editor : hide.view.FXEditor ){
 		var elem = editor.element.find(".fx-scriptParams");
 		elem.empty();
+		if(s == null) return;
 		var root = new Element('<div class="group" name="Params"></div>');
 		for(p in s.params){
+			if(p == null) continue;
 			switch(p){
 				case Float(name, value, options):
 					var sliderMin = 0.0;
@@ -400,7 +406,6 @@ class FXScriptParser {
 			}
 		}
 		elem.append(root);
-
 	}
 
 	function createSlider( s : FXScript, name : String, min : Float, max : Float, step : Float, defaultVal : Float ) : Element {
@@ -416,7 +421,7 @@ class FXScriptParser {
 	}
 
 	function createChekbox( s : FXScript, name : String, defaultVal : Bool ) : Element {
-		var root = new Element('<div class="fx-slider"></div>');
+		var root = new Element('<div class="fx-chekcBox"></div>');
 		var label = new Element('<label> $name : </label>');
 		var checkbox = new Element('<input type="checkbox" value="$defaultVal"/>');
 		root.append(label);

+ 1 - 1
hide/view/FXEditor.hx

@@ -973,7 +973,7 @@ class FXEditor extends FileView {
 		}
 
 		if(anim != null) {
-			anim.setTime(currentTime);
+			anim.setTime(currentTime, currentTime);
 		}
 
 		if(statusText != null) {