Clément Espeute 1 mesiac pred
rodič
commit
664a63ebab

+ 1 - 1
hide/tools/ThumbnailGenerator.hx

@@ -280,7 +280,7 @@ class ThumbnailGenerator {
 						// Forward the animations a little bit to show something more usefull
 						if (fxAnim != null) {
 							var duration = fxAnim.duration;
-							fxAnim.setTime(duration * 0.25);
+							fxAnim.setTime(duration * 0.25, 0, true, true);
 						}
 					}
 				}

+ 8 - 7
hide/view/FXEditor.hx

@@ -1756,14 +1756,15 @@ class FXEditor extends hide.view.FileView {
 			var hasJumped = currentTime != lastTime ;
 
 			if(!pauseButton.isDown() || hasJumped) {
-				if (currentTime + scene.speed * dt >= previewMax) {
-					fx.seek(previewMin);
-					fx.setRandSeed(Std.random(0xFFFFFF));
-				} else if (hasJumped) {
-					fx.seek(currentTime + scene.speed * dt);
-				} else {
-					fx.update(scene.speed * dt);
+				var localDt = scene.speed * dt;
+				var nextTime = currentTime + localDt;
+				if (nextTime > fx.duration) {
+					nextTime = 0;
+					localDt = 0;
+					hasJumped = true;
+					fx.reset();
 				}
+				@:privateAccess fx.setTime(nextTime, localDt, hasJumped);
 
 				currentTime = fx.localTime;
 				lastTime = currentTime;

+ 3 - 1
hide/view/shadereditor/ShaderEditor.hx

@@ -1469,7 +1469,9 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 
 		var anims = meshPreviewRoot3d.findAll((f) -> Std.downcast(f, hrt.prefab.fx.FX.FXAnimation));
 		for (anim in anims) {
-			@:privateAccess anim.setTime(meshPreviewScene.s3d.renderer.ctx.time % anim.duration, true);
+			if (@:privateAccess anim.parentFX != null) {
+				@:privateAccess anim.setTime(meshPreviewScene.s3d.renderer.ctx.time % anim.duration, meshPreviewScene.s3d.renderer.ctx.elapsedTime, false);
+			}
 		}
 	}
 

+ 22 - 11
hrt/prefab/fx/Emitter.hx

@@ -787,14 +787,19 @@ class EmitterObject extends h3d.scene.Object {
 		super.onRemove();
 	}
 
-	public function reset() {
-		numInstances = 0;
+
+	public function softReset() {
+		totalBurstCount = 0;
 		enable = true;
+	}
+
+	public function reset() {
+		softReset();
 		random.init(randomSeed);
+		numInstances = 0;
 		curTime = 0.0;
 		emitCount = 0;
 		emitTarget = 0;
-		totalBurstCount = 0;
 		listHead = null;
 
 		if(randomValues != null) {
@@ -1475,9 +1480,20 @@ class EmitterObject extends h3d.scene.Object {
 	public var tickTime : Float = 0;
 	#end
 
-	public function setTime(time: Float) {
-		time = time * speedFactor + warmUpTime;
-		time = Math.max(0, time - delay * speedFactor);
+	public function setTime(parentTime: Float, dt: Float, seek: Bool) {
+		var time : Float = if (!seek) {
+			if (parentTime < curTime) {
+				softReset();
+			}
+			curTime + dt * speedFactor;
+		} else {
+			if (parentTime < curTime) {
+				reset();
+				updateMeshBatch();  // Make sure mesh batch is reset even when no tick is called()
+			}
+			var time = parentTime * speedFactor + warmUpTime;
+			Math.max(0, time - delay * speedFactor);
+		}
 
 		if(hxd.Math.abs(time - curTime) < 1e-6) {  // Time imprecisions can occur during accumulation
 			updateAlignment();
@@ -1487,11 +1503,6 @@ class EmitterObject extends h3d.scene.Object {
 			return;
 		}
 
-		if(time < curTime) {
-			reset();
-			updateMeshBatch();  // Make sure mesh batch is reset even when no tick is called()
-		}
-
 		var abs = this.getAbsPos();
 		baseEmitterShader.emitPosition.set(abs.tx, abs.ty, abs.tz);
 

+ 60 - 83
hrt/prefab/fx/FX.hx

@@ -257,8 +257,10 @@ class FXAnimation extends h3d.scene.Object {
 		if(playSpeed > 0 || firstSync) {
 			// This is done in syncRec() to make sure time and events are updated regarless of culling state,
 			// so we restore FX in correct state when unculled
-			if (parentFX == null)
-				setTime(curTime + ctx.elapsedTime * playSpeed, fullSync);
+			if (parentFX == null) {
+				var dt = ctx.elapsedTime * playSpeed;
+				setTime(curTime + dt, dt, false, fullSync);
+			}
 		}
 
 		for (t in trails) {
@@ -284,69 +286,58 @@ class FXAnimation extends h3d.scene.Object {
 		ctx.visibleFlag = old;
 	}
 
-	public function seek(time: Float) {
-		setTimeInternal(time, false);
-	}
-
-	public function update(dt: Float) {
-		setTimeInternal(dt, true);
-	}
-
 	static var closest : Map<h3d.scene.Object, {instance: EventInstance, distance: Float, jumpTo: Float}> = [];
 
 	/**
-		If continuous, timeParam is relative to localTime, else it's absolute
+		newTime is the new time to set, relative to the "parent" timeline
+		dt is the relative delta of time since the last "parent" update
+		Depending on how the parent loops, `newTime != lastTime + dt`, that's why the two arguments exists
 	**/
-	function setTimeInternal(timeParam:Float, continuous:Bool ) {
-		var newTime = continuous ? localTime + timeParam : timeParam;
+	public function setTime(newTimeParent:Float, dt: Float, isSeek: Bool, fullSync: Bool = true) {
 
-		if (continuous) {
-			if (playState == Start) {
-				if (newTime >= loopStart) {
-					playState = Loop;
-				}
-			}
+		var oldLocalTime = localTime;
+		localTime = newTimeParent - startDelay;
 
-			if (playState == Loop) {
-				newTime = ((newTime - loopStart) % (loopEnd - loopStart)) + loopStart;
+		if (playState == Start) {
+			if (localTime >= loopStart) {
+				playState = Loop;
 			}
 		}
-		else {
-			if (loop) {
-				if (newTime < loopStart) {
-					playState = Start;
-				} else if (newTime >= loopEnd) {
-					playState = End;
-				} else {
-					playState = Loop;
-				}
-			} else {
+
+		if (playState == Loop && isSeek) {
+			if (localTime >= loopEnd) {
 				playState = End;
+			} else if (localTime < loopStart) {
+				playState = Start;
 			}
 		}
 
-		var oldTime = localTime;
-		localTime = newTime;
+		if (playState == Loop) {
+			localTime = oldLocalTime + dt;
+			localTime = ((localTime - loopStart) % (loopEnd - loopStart)) + loopStart;
+		}
+
+		visible = localTime >= 0;
 
 		for (subFX in subFXs) {
-			if (continuous) {
-				subFX.update(timeParam);
-			} else {
-				subFX.seek(newTime);
-			}
+			subFX.setTime(localTime, dt, isSeek, fullSync);
 		}
 
-		syncAnims(newTime);
-		syncParticles(timeParam, continuous);
+		if (fullSync) {
+			syncAnims(localTime, dt);
+			syncParticles(localTime, dt, isSeek);
 
-		for (t in trails) {
-			t.update(hxd.Math.max(newTime - oldTime, 0.0));
-		}
+			for (t in trails) {
+				t.update(hxd.Math.max(dt, 0.0));
+			}
 
-		Event.updateEvents(events, newTime, oldTime, duration);
+			Event.updateEvents(events, localTime, oldLocalTime, duration);
 
-		if (!continuous) {
-			fixEventSeek();
+			#if editor
+			if (isSeek || hxd.Math.abs(dt) > hxd.Timer.dt * 1.5) {
+				fixEventSeek();
+			}
+			#end
 		}
 	}
 
@@ -400,49 +391,35 @@ class FXAnimation extends h3d.scene.Object {
 		}
 	}
 
-	function syncParticles(timeParam: Float, continuous: Bool) {
+	function syncParticles(newTime: Float, dt: Float, seek: Bool) {
 		if(emitters != null) {
 			for(em in emitters) {
 				if(em.visible)
 				{
-					if (continuous) {
-						em.setTime(@:privateAccess em.curTime + timeParam);
-					} else {
-						em.setTime(timeParam);
-					}
+					em.setTime(newTime, dt, seek);
 				}
 			}
 		}
-
-
 	}
 
 	static var tempMat = new h3d.Matrix();
 	static var tempTransform = new h3d.Matrix();
 	static var tempVec = new h3d.Vector4();
 
-	/** Use seek or update depending on what you want to do instead of this function**/
-	@:deprecated
-	public function setTime( time : Float, fullSync=true) {
-		// broken heuristic for back-compat
-		var continuous = time - localTime < hxd.Timer.dt * 1.5;
-		setTimeInternal(continuous ? time - localTime : time, continuous);
-	}
-
-	function syncAnims(time: Float) {
+	function syncAnims(newTime: Float, dt: Float) {
 		if(objAnims != null) {
 			for(anim in objAnims) {
 				if(anim.scale != null || anim.rotation != null || anim.position != null) {
 					var m = tempMat;
 					if(anim.scale != null) {
-						var scale = evaluator.getVector(anim.scale, time, tempVec);
+						var scale = evaluator.getVector(anim.scale, newTime, tempVec);
 						m.initScale(scale.x, scale.y, scale.z);
 					}
 					else
 						m.identity();
 
 					if(anim.rotation != null) {
-						var rotation = evaluator.getVector(anim.rotation, time, tempVec);
+						var rotation = evaluator.getVector(anim.rotation, newTime, tempVec);
 						rotation.scale3(Math.PI / 180.0);
 						m.rotate(rotation.x, rotation.y, rotation.z);
 					}
@@ -454,7 +431,7 @@ 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, tempVec);
+						var pos = evaluator.getVector(anim.position, newTime, tempVec);
 						m.translate(pos.x, pos.y, pos.z);
 					}
 
@@ -474,13 +451,13 @@ class FXAnimation extends h3d.scene.Object {
 						var m = tempMat;
 
 						if(anim.localRotation != null) {
-							var localRotation = evaluator.getVector(anim.localRotation, time, tempVec);
+							var localRotation = evaluator.getVector(anim.localRotation, newTime, tempVec);
 							localRotation.scale3(Math.PI / 180.0);
 							m.rotate(localRotation.x, localRotation.y, localRotation.z);
 						}
 
 						if(anim.localPosition != null) {
-							var localPosition = evaluator.getVector(anim.localPosition, time, tempVec);
+							var localPosition = evaluator.getVector(anim.localPosition, newTime, tempVec);
 							m.translate(localPosition.x, localPosition.y, localPosition.z);
 						}
 
@@ -495,17 +472,17 @@ class FXAnimation extends h3d.scene.Object {
 					var editor = anim.elt.shared.editor;
 					visible = visible && (editor?.isVisible(anim.elt) ?? true);
 					#end
-					anim.obj.visible = visible && evaluator.getFloat(anim.visibility, time) > 0.5;
+					anim.obj.visible = visible && evaluator.getFloat(anim.visibility, newTime) > 0.5;
 				}
 
 				if(anim.color != null) {
 					switch(anim.color) {
 						case VCurve(a):
 							for(mat in anim.obj.getMaterials())
-								mat.color.a = evaluator.getFloat(anim.color, time);
+								mat.color.a = evaluator.getFloat(anim.color, newTime);
 						default:
 							for(mat in anim.obj.getMaterials())
-								mat.color.load(evaluator.getVector(anim.color, time, tempVec));
+								mat.color.load(evaluator.getVector(anim.color, newTime, tempVec));
 					}
 				}
 
@@ -516,33 +493,33 @@ class FXAnimation extends h3d.scene.Object {
 							var l = Std.downcast(anim.obj, h3d.scene.pbr.PointLight);
 							if( l != null ) {
 								if( color != null ) {
-									var v = evaluator.getVector(color, time, tempVec);
+									var v = evaluator.getVector(color, newTime, tempVec);
 									l.color.set(v.x, v.y, v.z);
 								}
-								if( power != null ) l.power = evaluator.getFloat(power, time);
-								if( size != null ) l.size = evaluator.getFloat(size, time);
-								if( range != null ) l.range = evaluator.getFloat(range, time);
+								if( power != null ) l.power = evaluator.getFloat(power, newTime);
+								if( size != null ) l.size = evaluator.getFloat(size, newTime);
+								if( range != null ) l.range = evaluator.getFloat(range, newTime);
 							}
 						case DirLight(color, power):
 							var l = Std.downcast(anim.obj, h3d.scene.pbr.DirLight);
 							if( l != null ) {
 								if( color != null ) {
-									var v = evaluator.getVector(color, time, tempVec);
+									var v = evaluator.getVector(color, newTime, tempVec);
 									l.color.set(v.x, v.y, v.z);
 								}
-								if( power != null ) l.power = evaluator.getFloat(power, time);
+								if( power != null ) l.power = evaluator.getFloat(power, newTime);
 							}
 						case SpotLight(color, power, range, angle, fallOff):
 							var l = Std.downcast(anim.obj, h3d.scene.pbr.SpotLight);
 							if( l != null ) {
 								if( color != null ) {
-									var v = evaluator.getVector(color, time, tempVec);
+									var v = evaluator.getVector(color, newTime, tempVec);
 									l.color.set(v.x, v.y, v.z);
 								}
-								if( power != null ) l.power = evaluator.getFloat(power, time);
-								if( range != null ) l.range = evaluator.getFloat(range, time);
-								if( angle != null ) l.angle = evaluator.getFloat(angle, time);
-								if( fallOff != null ) l.fallOff = evaluator.getFloat(fallOff, time);
+								if( power != null ) l.power = evaluator.getFloat(power, newTime);
+								if( range != null ) l.range = evaluator.getFloat(range, newTime);
+								if( angle != null ) l.angle = evaluator.getFloat(angle, newTime);
+								if( fallOff != null ) l.fallOff = evaluator.getFloat(fallOff, newTime);
 							}
 					}
 				}
@@ -560,7 +537,7 @@ class FXAnimation extends h3d.scene.Object {
 		this.onEnd = onEnd;
 		playState = End;
 		if (instant == true) {
-			setTime(duration);
+			setTime(duration, 0, true, true);
 		}
 	}