2
0
Эх сурвалжийг харах

a more options on particles

ncannasse 11 жил өмнө
parent
commit
3dd15d7b93

+ 19 - 3
h3d/parts/Data.hx

@@ -8,7 +8,7 @@ enum Value {
 	VCos( freq : Float, ampl :  Float, offset : Float );
 	VPoly( values : Array<Float>, points : Array<Float> );
 	VRandom( start : Float, len : Float, converge : Converge );
-	VCustom( lifeToValue : Float -> (Void -> Float) -> Float ); // time -> random -> value
+	VCustom( p : Particle -> Float );
 }
 
 enum Converge {
@@ -77,6 +77,7 @@ class State {
 	public var blendMode : BlendMode;
 	public var sortMode : SortMode;
 	public var is3D : Bool;
+	public var isAlphaMap : Bool;
 	
 	// emit
 	public var loop	: Bool;
@@ -118,6 +119,7 @@ class State {
 	
 	// extra
 	public var delay : Float;
+	public var update : Particle -> Void;
 	
 	public function new() {
 	}
@@ -129,6 +131,7 @@ class State {
 		blendMode = SoftAdd;
 		sortMode = Back;
 		is3D = false;
+		isAlphaMap = false;
 		// emit
 		loop = true;
 		emitRate = VConst(100);
@@ -162,7 +165,20 @@ class State {
 		delay = 0.;
 	}
 	
-	public inline function eval( v : Value, time : Float, rand : Void -> Float ) : Float {
+	public function scale( val : Value, v : Float ) {
+		return switch( val ) {
+		case VConst(c): VConst(c * v);
+		case VRandom(start, len, c): VRandom(start * v, len * v, c);
+		case VLinear(start, len): VLinear(start * v, len * v);
+		case VPow(start, len, p): VPow(start * v, len * v, p);
+		case VSin(f, a, o): VSin(f, a * v, o * v);
+		case VCos(f, a, o): VCos(f, a * v, o * v);
+		case VPoly(values, points): VPoly([for( v2 in values ) v * v2], [for( i in 0...points.length ) { var p = points[i]; if( i & 1 == 0 ) p else p * v; } ]);
+		case VCustom(f): VCustom(function(p) return f(p) * v);
+		}
+	}
+	
+	public inline function eval( v : Value, time : Float, rand : Void -> Float, p ) : Float {
 		return switch( v ) {
 		case VConst(c): c;
 		case VRandom(s, l, c): s + (switch( c ) { case No: l; case Start: l * time; case End: l * (1 - time); }) * rand();
@@ -178,7 +194,7 @@ class State {
 				j--;
 			}
 			y;
-		case VCustom(f): f(time, rand);
+		case VCustom(f): f(p);
 		}
 	}
 

+ 2 - 2
h3d/parts/Editor.hx

@@ -790,8 +790,8 @@ class Editor extends h2d.Sprite {
 		}
 		for( x in 0...width ) {
 			var px = x / (width - 1);
-			var py0 = state.eval(curve.value, px, function() return 0.);
-			var py1 = state.eval(curve.value, px, function() return 1.);
+			var py0 = state.eval(curve.value, px, function() return 0., null);
+			var py1 = state.eval(curve.value, px, function() return 1., null);
 			var iy0 = posY(py0);
 			if( py0 != py1 ) {
 				var iy1 = posY(py1);

+ 9 - 1
h3d/parts/Emitter.hx

@@ -20,6 +20,7 @@ class Emitter extends h3d.scene.Object {
 	
 	var tmp : h3d.Vector;
 	var tmpBuf : hxd.FloatBuffer;
+	var curPart : Particle;
 	
 	public function new(?state,?parent) {
 		super(parent);
@@ -79,13 +80,14 @@ class Emitter extends h3d.scene.Object {
 	}
 	
 	inline function eval(v,time,rnd) {
-		return state.eval(v,time,rnd);
+		return state.eval(v,time,rnd, curPart);
 	}
 	
 	public function update(dt:Float) {
 		var s = state;
 		var old = time;
 		if( posChanged ) syncPos();
+		curPart = null;
 		time += dt * eval(s.globalSpeed, time, rand) / s.globalLife;
 		var et = (time - old) * s.globalLife;
 		if( time >= 1 && s.loop )
@@ -105,9 +107,11 @@ class Emitter extends h3d.scene.Object {
 		var p = head;
 		while( p != null ) {
 			var n = p.next;
+			curPart = p;
 			updateParticle(p, et);
 			p = n;
 		}
+		curPart = null;
 	}
 	
 	inline function rand() {
@@ -318,6 +322,9 @@ class Emitter extends h3d.scene.Object {
 			if( f < 0 ) f += 1;
 			p.frame = Std.int(f * state.frames.length);
 		}
+		
+		if( state.update != null )
+			state.update(p);
 	}
 	
 	override function sync( ctx : h3d.scene.RenderContext ) {
@@ -567,6 +574,7 @@ class Emitter extends h3d.scene.Object {
 			material.pshader.partSize = new h3d.Vector(size, size * ctx.engine.width / ctx.engine.height);
 		}
 		material.pshader.hasColor = hasColor;
+		material.pshader.isAlphaMap = state.isAlphaMap;
 		
 		ctx.engine.selectMaterial(material);
 		ctx.engine.renderQuadBuffer(buffer);

+ 6 - 0
h3d/parts/Material.hx

@@ -20,6 +20,8 @@ private class PartShader extends h3d.impl.Shader {
 		
 		var hasColor : Bool;
 		var is3D : Bool;
+		
+		var isAlphaMap : Bool;
 
 		function vertex( mpos : M34, mproj : Matrix ) {
 			var tpos = input.pos.xyzw;
@@ -47,6 +49,10 @@ private class PartShader extends h3d.impl.Shader {
 		function fragment( tex : Texture ) {
 			var c = tex.get(tuv.xy);
 			if( hasColor ) c *= tcolor;
+			if( isAlphaMap ) {
+				c.a *= c.rgb.dot([1 / 3, 1 / 3, 1 / 3]);
+				c.rgb = [1, 1, 1];
+			}
 			out = c;
 		}