Parcourir la source

Update FX Editor
Update ProbeBakerProcess

ShiroSmith il y a 6 ans
Parent
commit
812b5c348e
4 fichiers modifiés avec 119 ajouts et 25 suppressions
  1. 3 2
      hide/prefab/Constraint.hx
  2. 38 11
      hide/prefab/fx/Emitter.hx
  3. 74 10
      hide/prefab/fx/FX.hx
  4. 4 2
      hide/view/l3d/ProbeBakerProcess.hx

+ 3 - 2
hide/prefab/Constraint.hx

@@ -2,8 +2,8 @@ package hide.prefab;
 
 class Constraint extends Prefab {
 
-	var object : String;
-	var target : String;
+	public var object(default,null) : String;
+	public var target(default,null) : String;
 
 	override public function load(v:Dynamic) {
 		object = v.object;
@@ -45,6 +45,7 @@ class Constraint extends Prefab {
 			makeInstance(ctx.rootContext);
 			curObj = ctx.rootContext.locateObject(object);
 		});
+
 		for( select in [props.find("[field=object]"), props.find("[field=target]")] ) {
 			for( path in ctx.getNamedObjects() ) {
 				var parts = path.split(".");

+ 38 - 11
hide/prefab/fx/Emitter.hx

@@ -3,6 +3,11 @@ import hide.prefab.Curve;
 import hide.prefab.fx.FX.ShaderAnimation;
 using Lambda;
 
+enum SimulationSpace {
+	Local;
+	World;
+}
+
 enum AlignMode {
 	None;
 	Screen;
@@ -57,7 +62,10 @@ private class ParticleInstance extends h3d.scene.Object {
 	var childMat = new h3d.Matrix();
 
 	public function new(emitter: EmitterObject, def: InstanceDef) {
-		super(emitter.parent);
+		switch(emitter.simulationSpace){
+			case Local:super(emitter.parent);
+			case World:super(emitter.getScene());
+		}
 		this.def = def;
 		this.emitter = emitter;
 		this.evaluator = new Evaluator(emitter.random);
@@ -125,7 +133,10 @@ private class ParticleInstance extends h3d.scene.Object {
 				case Screen: {
 					var mat = ctx.camera.mcam.clone();
 					mat.invert();
-					mat.multiply3x4(mat, emitter.invTransform);
+					switch(emitter.simulationSpace){
+						case Local:mat.multiply3x4(mat, emitter.invTransform);
+						case World:
+					}
 					var q = new h3d.Quat();
 					q.initRotateMatrix(mat);
 					setRotationQuat(q);
@@ -180,6 +191,7 @@ class EmitterObject extends h3d.scene.Object {
 	public var lifeTime = 2.0;
 	public var emitShape : EmitShape = Cylinder;
 	public var emitOrientation : Orientation = Forward;
+	public var simulationSpace : SimulationSpace = Local;
 	public var emitAngle : Float = 0.0;
 	public var emitRad1 : Float = 1.0;
 	public var emitRad2 : Float = 1.0;
@@ -219,7 +231,7 @@ class EmitterObject extends h3d.scene.Object {
 	var evaluator : Evaluator;
 	var instances : Array<ParticleInstance> = [];
 
-	function reset() {
+	public function reset() {
 		random.init(randomSeed);
 		curTime = 0.0;
 		lastTime = 0.0;
@@ -304,13 +316,26 @@ class EmitterObject extends h3d.scene.Object {
 			if(emitOrientation == Random)
 				tmpq.initRotation(hxd.Math.srand(Math.PI), hxd.Math.srand(Math.PI), hxd.Math.srand(Math.PI));
 
-			localQuat.multiply(localQuat, tmpq);
-			part.setRotationQuat(localQuat);
-			part.orientation = localQuat.clone();
-			offset.transform(localMat);
-			part.setPosition(offset.x, offset.y, offset.z);
-			part.baseMat = particleTemplate.getTransform();
-			part.baseMat.tx = part.baseMat.ty = part.baseMat.tz = 0; // Kill translation to make edition easier
+			switch(simulationSpace){
+				case Local:
+					offset.transform(localMat);
+					part.setPosition(offset.x, offset.y, offset.z);
+					part.baseMat = particleTemplate.getTransform();
+					part.baseMat.tx = part.baseMat.ty = part.baseMat.tz = 0; // Kill translation to make edition easier
+					localQuat.multiply(localQuat, tmpq);
+					part.setRotationQuat(localQuat);
+					part.orientation = localQuat.clone();
+				case World:
+					var worldPos = localToGlobal(offset.clone());
+					part.setPosition(worldPos.x, worldPos.y, worldPos.z);
+					part.baseMat = particleTemplate.getTransform();
+					part.baseMat.tx = part.baseMat.ty = part.baseMat.tz = 0; // Kill translation to make edition easier
+					var worldQuat = new h3d.Quat();
+					worldQuat.initRotateMatrix(getAbsPos());
+					tmpq.multiply(tmpq, worldQuat);
+					part.setRotationQuat(tmpq);
+					part.orientation = tmpq.clone();
+			}
 
 			// Setup mats.
 			// Should we do this manually here or make a recursive makeInstance on the template?
@@ -411,6 +436,7 @@ class Emitter extends Object3D {
 	}
 
 	public static var emitterParams : Array<ParamDef> = [
+		{ name: "simulationSpace", t: PEnum(SimulationSpace), def: SimulationSpace.Local, disp: "Simulation Space", },
 		{ name: "emitRate", t: PInt(0, 100), def: 5, disp: "Rate", animate: true },
 		{ name: "lifeTime", t: PFloat(0, 10), def: 1.0 },
 		{ name: "maxCount", t: PInt(0, 100), def: 20, },
@@ -600,6 +626,7 @@ class Emitter extends Object3D {
 			emitterObj.particleTemplate = template;
 		}
 
+		emitterObj.simulationSpace = getParamVal("simulationSpace");
 		emitterObj.lifeTime = getParamVal("lifeTime");
 		emitterObj.maxCount = getParamVal("maxCount");
 		emitterObj.emitRate = makeParam(this, "emitRate");
@@ -774,7 +801,7 @@ class Emitter extends Object3D {
 			return;
 		var debugShape : h3d.scene.Object = emitterObj.find(c -> if(c.name == "_highlight") c else null);
 		if(debugShape != null)
-			debugShape.visible = b;		
+			debugShape.visible = b;
 	}
 
 	function updateEmitShape(emitterObj: EmitterObject) {

+ 74 - 10
hide/prefab/fx/FX.hx

@@ -59,6 +59,17 @@ class FXAnimation extends h3d.scene.Object {
 		super(parent);
 		random = new hxd.Rand(Std.random(0xFFFFFF));
 		evaluator = new Evaluator(random);
+		name = "FXAnimation";
+	}
+
+	override function onRemove() {
+		super.onRemove();
+		for(obj in objects){
+			obj.obj.remove();
+		}
+		for(emitter in emitters){
+			emitter.reset();
+		}
 	}
 
 	public function setRandSeed(seed: Int) {
@@ -88,7 +99,7 @@ class FXAnimation extends h3d.scene.Object {
 
 			var baseMat = anim.elt.getTransform();
 			var offset = baseMat.getPosition();
-			baseMat.tx = baseMat.ty = baseMat.tz = 0.0;  // Ignore 
+			baseMat.tx = baseMat.ty = baseMat.tz = 0.0;  // Ignore
 			m.multiply(baseMat, m);
 			m.translate(offset.x, offset.y, offset.z);
 
@@ -98,7 +109,7 @@ class FXAnimation extends h3d.scene.Object {
 			}
 
 			anim.obj.setTransform(m);
-	
+
 			if(anim.visibility != null)
 				anim.obj.visible = anim.elt.visible && evaluator.getFloat(anim.visibility, time) > 0.5;
 
@@ -120,15 +131,17 @@ class FXAnimation extends h3d.scene.Object {
 			anim.setTime(time);
 		}
 
-		for(i in 0...numChildren) {
-			var child = getChildAt(i);
-			if(child.currentAnimation != null) {
-				var anim = child.currentAnimation;
+		function setAnimFrame(object : h3d.scene.Object, time : Float){
+			var anim = object.currentAnimation;
+			if(object.currentAnimation != null){
 				anim.loop = false;
 				anim.pause = true;
-				anim.setFrame(hxd.Math.clamp(time * anim.sampling * anim.speed, 0, anim.frameCount));
+				anim.setFrame( hxd.Math.clamp(time * anim.sampling * anim.speed, 0, anim.frameCount) );
 			}
+			for(i in 0...object.numChildren)
+				setAnimFrame(object.getChildAt(i), time);
 		}
+		setAnimFrame(this, time);
 
 		for(em in emitters) {
 			if(em.visible)
@@ -303,14 +316,65 @@ class FX extends hxd.prefab.Library {
 		}
 	}
 
-	override function makeInstance(ctx:Context):Context {
-		if( inRec )
-			return ctx;
+	function getFXRoot( ctx : Context, elt : PrefabElement ) : PrefabElement {
+		if( elt.name == "FXRoot" )
+			return elt;
+		else {
+			for(c in elt.children) {
+				var elt = getFXRoot(ctx, c);
+				if(elt != null) return elt;
+			}
+		}
+		return null;
+	}
+
+	function getContraints( ctx : Context, elt : PrefabElement, contraints : Array<hide.prefab.Constraint> ){
+		var co = Std.instance(elt, hide.prefab.Constraint);
+		if(co != null)
+			contraints.push(co);
+		else
+			for(c in elt.children)
+				getContraints(ctx, c, contraints);
+	}
+
+	function resolveContraints( ctx : Context , contraints : Array<hide.prefab.Constraint> ){
+		var parent = ctx.local3d.parent;
+		for(co in contraints){
+			var objectName = co.object.split(".").pop();
+			var targetName = co.target.split(".").pop();
+			trace(co.object + " on " + co.target);
+			var srcObj = objectName == "FXRoot" ? ctx.local3d : parent.getObjectByName(objectName);
+			var targetObj = parent.getObjectByName(targetName);
+			if( srcObj != null && targetObj != null ) srcObj.follow = targetObj;
+		}
+	}
+
+	override function makeInstance( ctx : Context ) : Context {
+		if( inRec ) return ctx;
+
 		ctx = ctx.clone(this);
 		var fxanim = new FXAnimation(ctx.local3d);
 		fxanim.duration = duration;
 		ctx.local3d = fxanim;
+
+		#if editor
 		super.makeInstance(ctx);
+		#else
+		var root = getFXRoot(ctx, this);
+		if(root != null){
+			for( c in root.children ){
+				var co = Std.instance(c , Constraint);
+				if(co == null) c.makeInstanceRec(ctx);
+			}
+			var contraints : Array<hide.prefab.Constraint> = [];
+			getContraints(ctx, root, contraints);
+			resolveContraints(ctx, contraints);
+			getObjAnimations(ctx, this, fxanim.objects);
+		}
+		else
+			super.makeInstance(ctx);
+		#end
+
 		getObjAnimations(ctx, this, fxanim.objects);
 		getShaderAnims(ctx, this, fxanim.shaderAnims);
 		getEmitters(ctx, this, fxanim.emitters);

+ 4 - 2
hide/view/l3d/ProbeBakerProcess.hx

@@ -8,12 +8,14 @@ class ProbeBakerProcess {
 	var volumetricLightmap : hide.prefab.l3d.VolumetricLightmap;
 	var s3d : h3d.scene.Scene;
 	var bakeTime : Float;
+	var resolution : Int;
 
-	public function new(s3d, volumetricLightmap, bakeTime : Float = 0.08 ){
+	public function new(s3d, volumetricLightmap, res, bakeTime : Float = 0.08 ){
 		progress = 0;
 		this.s3d = s3d;
 		this.bakeTime = bakeTime;
 		this.volumetricLightmap = volumetricLightmap;
+		this.resolution = res;
 
 		lightProbeBaker = new h3d.scene.pbr.LightProbeBaker();
 		lightProbeBaker.useGPU = false;
@@ -27,7 +29,7 @@ class ProbeBakerProcess {
 	}
 
 	public function update(dt:Float) {
-		lightProbeBaker.bake(s3d.renderer, s3d, volumetricLightmap.volumetricLightmap, 32, bakeTime);
+		lightProbeBaker.bake(s3d, volumetricLightmap.volumetricLightmap, resolution, bakeTime);
 		volumetricLightmap.createDebugPreview();
 		progress = (volumetricLightmap.volumetricLightmap.lastBakedProbeIndex +1.0) / volumetricLightmap.volumetricLightmap.getProbeCount();
 		if( progress == 1 ) {