Răsfoiți Sursa

Add Cylinder emit shape, new orientation modes

trethaller 7 ani în urmă
părinte
comite
9e81e2a95c
1 a modificat fișierele cu 74 adăugiri și 38 ștergeri
  1. 74 38
      hide/prefab/fx/Emitter.hx

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

@@ -3,13 +3,6 @@ import hide.prefab.Curve;
 import hide.prefab.fx.FX.ShaderAnimation;
 import hide.prefab.fx.FX.ShaderAnimation;
 using Lambda;
 using Lambda;
 
 
-enum StartDirection {
-	Fixed;
-	EmitPosition;
-	EmitSpeed;
-	Random;
-}
-
 enum AlignMode {
 enum AlignMode {
 	None;
 	None;
 	Screen;
 	Screen;
@@ -18,9 +11,16 @@ enum AlignMode {
 
 
 enum EmitShape {
 enum EmitShape {
 	Cone;
 	Cone;
-	Disc;
 	Sphere;
 	Sphere;
 	Box;
 	Box;
+	Cylinder;
+}
+
+enum Orientation {
+	Forward;
+	Normal;
+	Speed;
+	Random;
 }
 }
 
 
 typedef ParamDef = {
 typedef ParamDef = {
@@ -37,7 +37,6 @@ typedef InstanceDef = {
 	stretch: Value,
 	stretch: Value,
 	rotation: Value,
 	rotation: Value,
 	color: Value,
 	color: Value,
-	alignDirection: Bool
 }
 }
 
 
 typedef ShaderAnims = Array<ShaderAnimation>;
 typedef ShaderAnims = Array<ShaderAnimation>;
@@ -77,7 +76,7 @@ private class ParticleInstance extends h3d.scene.Object {
 			localSpeed.transform3x3(orientation.toMatrix());
 			localSpeed.transform3x3(orientation.toMatrix());
 		}
 		}
 		curVelocity = localSpeed.add(worldSpeed);
 		curVelocity = localSpeed.add(worldSpeed);
-		if(def.alignDirection && curVelocity.lengthSq() > 0.01) {
+		if(emitter.emitOrientation == Speed && curVelocity.lengthSq() > 0.01) {
 			getRotationQuat().initDirection(curVelocity);
 			getRotationQuat().initDirection(curVelocity);
 			posChanged = true;
 			posChanged = true;
 		}
 		}
@@ -136,13 +135,17 @@ class EmitterObject extends h3d.scene.Object {
 	public var particleTemplate : hide.prefab.Object3D;
 	public var particleTemplate : hide.prefab.Object3D;
 	public var maxCount = 20;
 	public var maxCount = 20;
 	public var lifeTime = 2.0;
 	public var lifeTime = 2.0;
-	public var emitShape : EmitShape = Disc;
+	public var emitShape : EmitShape = Cylinder;
+	public var emitOrientation : Orientation = Forward;
+	public var emitAngle : Float = 0.0;
+	public var emitRad1 : Float = 1.0;
+	public var emitRad2 : Float = 1.0;
+	public var emitSurface : Bool = false;
 
 
 	public var frameCount : Int = 0;
 	public var frameCount : Int = 0;
 	public var frameDivisionX : Int = 1;
 	public var frameDivisionX : Int = 1;
 	public var frameDivisionY : Int = 1;
 	public var frameDivisionY : Int = 1;
 	public var animationRepeat : Float = 1;
 	public var animationRepeat : Float = 1;
-	public var emitAngle : Float = 0.0;
 
 
 	public var alignMode : AlignMode;
 	public var alignMode : AlignMode;
 	public var alignAxis : h3d.Vector;
 	public var alignAxis : h3d.Vector;
@@ -204,20 +207,31 @@ class EmitterObject extends h3d.scene.Object {
 			var ctx = particleTemplate.makeInstance(context);
 			var ctx = particleTemplate.makeInstance(context);
 
 
 			var localQuat = getRotationQuat().clone();
 			var localQuat = getRotationQuat().clone();
+			tmpq.identity();
 
 
 			switch(emitShape) {
 			switch(emitShape) {
-				case Disc:
-					var dx = 0.0, dy = 0.0;
-					do {
-						dx = random.srand(1.0);
-						dy = random.srand(1.0);
-					}
-					while(dx * dx + dy * dy > 1.0);
-					offset.set(0, dx * 0.5, dy * 0.5);
-					tmpq.initRotation(0, -hxd.Math.atan2(dy, dx), Math.PI/2);
 				case Box:
 				case Box:
 					offset.set(random.srand(0.5), random.srand(0.5), random.srand(0.5));
 					offset.set(random.srand(0.5), random.srand(0.5), random.srand(0.5));
-					tmpq.identity();
+				case Cylinder:
+					var dx = 0.0, dy = 0.0;
+					if(emitSurface) {
+						var a = random.srand(Math.PI);
+						dx = Math.cos(a);
+						dy = Math.sin(a);
+					}
+					else {
+						do {
+							dx = random.srand(1.0);
+							dy = random.srand(1.0);
+						}
+						while(dx * dx + dy * dy > 1.0);
+					}
+					var x = random.rand();
+					offset.set(x - 0.5, dx * 0.5, dy * 0.5);
+					if(emitOrientation == Normal)
+						tmpq.initRotation(0, -hxd.Math.atan2(dy, dx), Math.PI/2);
+					offset.y *= hxd.Math.lerp(emitRad1, emitRad2, x);
+					offset.z *= hxd.Math.lerp(emitRad1, emitRad2, x);
 				case Sphere:
 				case Sphere:
 					do {
 					do {
 						offset.x = random.srand(1.0);
 						offset.x = random.srand(1.0);
@@ -225,10 +239,11 @@ class EmitterObject extends h3d.scene.Object {
 						offset.z = random.srand(1.0);
 						offset.z = random.srand(1.0);
 					}
 					}
 					while(offset.lengthSq() > 1.0);
 					while(offset.lengthSq() > 1.0);
+					if(emitSurface)
+						offset.normalize();
 					offset.scale3(0.5);
 					offset.scale3(0.5);
-					direction = offset.clone();
-					direction.normalizeFast();
-					tmpq.initDirection(direction);
+					if(emitOrientation == Normal)
+						tmpq.initDirection(offset);
 				case Cone:
 				case Cone:
 					offset.set(0, 0, 0);
 					offset.set(0, 0, 0);
 					var theta = random.rand() * Math.PI * 2;
 					var theta = random.rand() * Math.PI * 2;
@@ -240,6 +255,9 @@ class EmitterObject extends h3d.scene.Object {
 					tmpq.initDirection(direction);
 					tmpq.initDirection(direction);
 			}
 			}
 
 
+			if(emitOrientation == Random)
+				tmpq.initRotation(hxd.Math.srand(Math.PI), hxd.Math.srand(Math.PI), hxd.Math.srand(Math.PI));
+
 			localQuat.multiply(localQuat, tmpq);
 			localQuat.multiply(localQuat, tmpq);
 			part.setRotationQuat(localQuat);
 			part.setRotationQuat(localQuat);
 			part.orientation = localQuat.clone();
 			part.orientation = localQuat.clone();
@@ -349,13 +367,15 @@ class Emitter extends Object3D {
 		{ name: "maxCount", t: PInt(0, 100), def: 20, },
 		{ name: "maxCount", t: PInt(0, 100), def: 20, },
 		{ name: "emitShape", t: PEnum(EmitShape), def: EmitShape.Sphere, disp: "Emit Shape", },
 		{ name: "emitShape", t: PEnum(EmitShape), def: EmitShape.Sphere, disp: "Emit Shape", },
 		{ name: "emitAngle", t: PFloat(0, 360.0), disp: "Angle", },
 		{ name: "emitAngle", t: PFloat(0, 360.0), disp: "Angle", },
+		{ name: "emitRad1", t: PFloat(0, 1.0), def: 1.0, disp: "Radius 1", },
+		{ name: "emitRad2", t: PFloat(0, 1.0), def: 1.0, disp: "Radius 2", },
+		{ name: "emitSurface", t: PBool, def: false, disp: "Surface" },
 
 
+		{ name: "emitOrientation", t: PEnum(Orientation), def: Orientation.Forward, disp: "Orientation", },
 		{ name: "alignMode", t: PEnum(AlignMode), def: AlignMode.None, disp: "Alignment" },
 		{ name: "alignMode", t: PEnum(AlignMode), def: AlignMode.None, disp: "Alignment" },
 		{ name: "alignAxis", t: PVec(3, -1.0, 1.0), def: [0.,0.,0.], disp: "Axis" },
 		{ name: "alignAxis", t: PVec(3, -1.0, 1.0), def: [0.,0.,0.], disp: "Axis" },
 		{ name: "alignLockAxis", t: PVec(3, -1.0, 1.0), def: [0.,0.,0.], disp: "Lock Axis" },
 		{ name: "alignLockAxis", t: PVec(3, -1.0, 1.0), def: [0.,0.,0.], disp: "Lock Axis" },
 
 
-		{ name: "alignDirection", t: PBool, def: false, disp: "Align Direction" },
-
 		{ name: "frameCount", t: PInt(0), def: 0 },
 		{ name: "frameCount", t: PInt(0), def: 0 },
 		{ name: "frameDivisionX", t: PInt(1), def: 1 },
 		{ name: "frameDivisionX", t: PInt(1), def: 1 },
 		{ name: "frameDivisionY", t: PInt(1), def: 1 },
 		{ name: "frameDivisionY", t: PInt(1), def: 1 },
@@ -525,7 +545,6 @@ class Emitter extends Object3D {
 				stretch: makeParam(this, "instStretch"),
 				stretch: makeParam(this, "instStretch"),
 				rotation: makeParam(this, "instRotation"),
 				rotation: makeParam(this, "instRotation"),
 				color: makeColor(template, "color"),
 				color: makeColor(template, "color"),
-				alignDirection: getParamVal("alignDirection")
 			};
 			};
 
 
 			emitterObj.particleTemplate = template;
 			emitterObj.particleTemplate = template;
@@ -535,7 +554,11 @@ class Emitter extends Object3D {
 		emitterObj.maxCount = getParamVal("maxCount");
 		emitterObj.maxCount = getParamVal("maxCount");
 		emitterObj.emitRate = makeParam(this, "emitRate");
 		emitterObj.emitRate = makeParam(this, "emitRate");
 		emitterObj.emitShape = getParamVal("emitShape");
 		emitterObj.emitShape = getParamVal("emitShape");
+		emitterObj.emitOrientation = getParamVal("emitOrientation");
 		emitterObj.emitAngle = getParamVal("emitAngle");
 		emitterObj.emitAngle = getParamVal("emitAngle");
+		emitterObj.emitRad1 = getParamVal("emitRad1");
+		emitterObj.emitRad2 = getParamVal("emitRad2");
+		emitterObj.emitSurface = getParamVal("emitSurface");
 		emitterObj.alignMode = getParamVal("alignMode");
 		emitterObj.alignMode = getParamVal("alignMode");
 		emitterObj.alignAxis = getParamVal("alignAxis");
 		emitterObj.alignAxis = getParamVal("alignAxis");
 		emitterObj.alignLockAxis = getParamVal("alignLockAxis");
 		emitterObj.alignLockAxis = getParamVal("alignLockAxis");
@@ -545,7 +568,7 @@ class Emitter extends Object3D {
 		emitterObj.animationRepeat = getParamVal("animationRepeat");
 		emitterObj.animationRepeat = getParamVal("animationRepeat");
 
 
 		#if editor
 		#if editor
-		if(propName == null || propName == "emitShape" || propName == "emitAngle")
+		if(propName == null || ["emitShape", "emitAngle", "emitRad1", "emitRad2"].indexOf(propName) >= 0)
 			updateEmitShape(emitterObj);
 			updateEmitShape(emitterObj);
 		#end
 		#end
 	}
 	}
@@ -584,18 +607,18 @@ class Emitter extends Object3D {
 		}
 		}
 
 
 		var emitShape : EmitShape = getParamVal("emitShape");
 		var emitShape : EmitShape = getParamVal("emitShape");
-		switch(emitShape) {
-			case Cone:
-			default: removeParam("emitAngle");
+		if(emitShape != Cone)
+			removeParam("emitAngle");
+		if(emitShape != Cylinder) {
+			removeParam("emitRad1");
+			removeParam("emitRad2");
 		}
 		}
 
 
 		var alignMode : AlignMode = getParamVal("alignMode");
 		var alignMode : AlignMode = getParamVal("alignMode");
 		switch(alignMode) {
 		switch(alignMode) {
-			case None:
+			case None | Screen:
 				removeParam("alignAxis");
 				removeParam("alignAxis");
 				removeParam("alignLockAxis");
 				removeParam("alignLockAxis");
-			case Screen:
-				removeParam("alignLockAxis");
 			default:
 			default:
 		}
 		}
 
 
@@ -723,14 +746,27 @@ class Emitter extends Object3D {
 
 
 		var mesh : h3d.scene.Mesh = null;
 		var mesh : h3d.scene.Mesh = null;
 		switch(emitterObj.emitShape) {
 		switch(emitterObj.emitShape) {
-			case Disc: {
+			case Cylinder: {
+				var rad1 = getParamVal("emitRad1") * 0.5;
+				var rad2 = getParamVal("emitRad2") * 0.5;
 				var g = new h3d.scene.Graphics(debugShape);
 				var g = new h3d.scene.Graphics(debugShape);
 				g.lineStyle(1, 0xffffff);
 				g.lineStyle(1, 0xffffff);
 				circle(32, function(i, c, s) {
 				circle(32, function(i, c, s) {
 					if(i == 0)
 					if(i == 0)
-						g.moveTo(0, c * 0.5, s * 0.5);
+						g.moveTo(-0.5, c * rad1, s * rad1);
 					else
 					else
-						g.lineTo(0, c * 0.5, s * 0.5);
+						g.lineTo(-0.5, c * rad1, s * rad1);
+				});
+				circle(32, function(i, c, s) {
+					if(i == 0)
+						g.moveTo(0.5, c * rad2, s * rad2);
+					else
+						g.lineTo(0.5, c * rad2, s * rad2);
+				});
+				g.lineStyle(1, 0xffffff);
+				circle(8, function(i, c, s) {
+					g.moveTo(-0.5, c * rad1, s * rad1);
+					g.lineTo(0.5, c * rad2, s * rad2);
 				});
 				});
 				g.ignoreCollide = true;
 				g.ignoreCollide = true;
 				mesh = g;
 				mesh = g;