Merge pull request 't3du (Repe) - New Particle Nodes!' (#54) from Onek8/LNXSDK:main into main
Reviewed-on: #54
This commit is contained in:
commit
f450c00ff1
@ -775,6 +775,7 @@ class Scene {
|
||||
// Attach particle systems
|
||||
#if lnx_particles
|
||||
if (o.particle_refs != null) {
|
||||
cast(object, MeshObject).render_emitter = o.render_emitter;
|
||||
for (ref in o.particle_refs) cast(object, MeshObject).setupParticleSystem(sceneName, ref);
|
||||
}
|
||||
#end
|
||||
|
@ -21,6 +21,7 @@ class MeshObject extends Object {
|
||||
public var particleChildren: Array<MeshObject> = null;
|
||||
public var particleOwner: MeshObject = null; // Particle object
|
||||
public var particleIndex = -1;
|
||||
public var render_emitter = true;
|
||||
#end
|
||||
public var cameraDistance: Float;
|
||||
public var screenSize = 0.0;
|
||||
@ -255,11 +256,11 @@ class MeshObject extends Object {
|
||||
particleSystems[i].update(particleChildren[i], this);
|
||||
}
|
||||
}
|
||||
if (particleSystems != null && particleSystems.length > 0 && !raw.render_emitter) return;
|
||||
if (particleSystems != null && particleSystems.length > 0 && !render_emitter) return;
|
||||
if (particleSystems == null && cullMaterial(context)) return;
|
||||
#else
|
||||
if (cullMaterial(context)) return;
|
||||
#end
|
||||
|
||||
if (cullMaterial(context)) return;
|
||||
|
||||
// Get lod
|
||||
var mats = materials;
|
||||
var lod = this;
|
||||
|
@ -18,29 +18,29 @@ class ParticleSystem {
|
||||
public var speed = 1.0;
|
||||
var particles: Array<Particle>;
|
||||
var ready: Bool;
|
||||
var frameRate = 24;
|
||||
var lifetime = 0.0;
|
||||
var animtime = 0.0;
|
||||
var time = 0.0;
|
||||
var spawnRate = 0.0;
|
||||
public var frameRate = 24;
|
||||
public var lifetime = 0.0;
|
||||
public var animtime = 0.0;
|
||||
public var time = 0.0;
|
||||
public var spawnRate = 0.0;
|
||||
var seed = 0;
|
||||
|
||||
var r: TParticleData;
|
||||
var gx: Float;
|
||||
var gy: Float;
|
||||
var gz: Float;
|
||||
var alignx: Float;
|
||||
var aligny: Float;
|
||||
var alignz: Float;
|
||||
public var r: TParticleData;
|
||||
public var gx: Float;
|
||||
public var gy: Float;
|
||||
public var gz: Float;
|
||||
public var alignx: Float;
|
||||
public var aligny: Float;
|
||||
public var alignz: Float;
|
||||
var dimx: Float;
|
||||
var dimy: Float;
|
||||
var tilesx: Int;
|
||||
var tilesy: Int;
|
||||
var tilesFramerate: Int;
|
||||
|
||||
var count = 0;
|
||||
var lap = 0;
|
||||
var lapTime = 0.0;
|
||||
public var count = 0;
|
||||
public var lap = 0;
|
||||
public var lapTime = 0.0;
|
||||
var m = Mat4.identity();
|
||||
|
||||
var ownerLoc = new Vec4();
|
||||
@ -149,7 +149,7 @@ class ParticleSystem {
|
||||
// GPU particles transform is attached to owner object
|
||||
}
|
||||
|
||||
function setupGeomGpu(object: MeshObject, owner: MeshObject) {
|
||||
public function setupGeomGpu(object: MeshObject, owner: MeshObject) {
|
||||
var instancedData = new Float32Array(particles.length * 6);
|
||||
var i = 0;
|
||||
|
||||
|
99
leenkx/Sources/leenkx/logicnode/AddParticleToObjectNode.hx
Normal file
99
leenkx/Sources/leenkx/logicnode/AddParticleToObjectNode.hx
Normal file
@ -0,0 +1,99 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.data.SceneFormat.TSceneFormat;
|
||||
import iron.data.Data;
|
||||
import iron.object.Object;
|
||||
|
||||
class AddParticleToObjectNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
#if lnx_particles
|
||||
|
||||
if (property0 == 'Scene Active'){
|
||||
var objFrom: Object = inputs[1].get();
|
||||
var slot: Int = inputs[2].get();
|
||||
var objTo: Object = inputs[3].get();
|
||||
|
||||
if (objFrom == null || objTo == null) return;
|
||||
|
||||
var mobjFrom = cast(objFrom, iron.object.MeshObject);
|
||||
|
||||
var psys = mobjFrom.particleSystems != null ? mobjFrom.particleSystems[slot] :
|
||||
mobjFrom.particleOwner != null && mobjFrom.particleOwner.particleSystems != null ? mobjFrom.particleOwner.particleSystems[slot] : null;
|
||||
|
||||
if (psys == null) return;
|
||||
|
||||
var mobjTo = cast(objTo, iron.object.MeshObject);
|
||||
|
||||
mobjTo.setupParticleSystem(iron.Scene.active.raw.name, {name: 'LnxPS', seed: 0, particle: psys.r.name});
|
||||
|
||||
mobjTo.render_emitter = inputs[4].get();
|
||||
|
||||
iron.Scene.active.spawnObject(psys.data.raw.instance_object, null, function(o: Object) {
|
||||
if (o != null) {
|
||||
var c: iron.object.MeshObject = cast o;
|
||||
if (mobjTo.particleChildren == null) mobjTo.particleChildren = [];
|
||||
mobjTo.particleChildren.push(c);
|
||||
c.particleOwner = mobjTo;
|
||||
c.particleIndex = mobjTo.particleChildren.length - 1;
|
||||
}
|
||||
});
|
||||
|
||||
var oslot: Int = mobjTo.particleSystems.length-1;
|
||||
var opsys = mobjTo.particleSystems[oslot];
|
||||
opsys.setupGeomGpu(mobjTo.particleChildren[oslot], mobjTo);
|
||||
|
||||
} else {
|
||||
var sceneName: String = inputs[1].get();
|
||||
var objectName: String = inputs[2].get();
|
||||
var slot: Int = inputs[3].get();
|
||||
|
||||
var mobjTo: Object = inputs[4].get();
|
||||
var mobjTo = cast(mobjTo, iron.object.MeshObject);
|
||||
|
||||
#if lnx_json
|
||||
sceneName += ".json";
|
||||
#elseif lnx_compress
|
||||
sceneName += ".lz4";
|
||||
#end
|
||||
|
||||
Data.getSceneRaw(sceneName, (rawScene: TSceneFormat) -> {
|
||||
|
||||
for (obj in rawScene.objects) {
|
||||
if (obj.name == objectName) {
|
||||
mobjTo.setupParticleSystem(sceneName, obj.particle_refs[slot]);
|
||||
mobjTo.render_emitter = inputs[5].get();
|
||||
|
||||
iron.Scene.active.spawnObject(rawScene.particle_datas[slot].instance_object, null, function(o: Object) {
|
||||
if (o != null) {
|
||||
var c: iron.object.MeshObject = cast o;
|
||||
if (mobjTo.particleChildren == null) mobjTo.particleChildren = [];
|
||||
mobjTo.particleChildren.push(c);
|
||||
c.particleOwner = mobjTo;
|
||||
c.particleIndex = mobjTo.particleChildren.length - 1;
|
||||
}
|
||||
}, true, rawScene);
|
||||
|
||||
var oslot: Int = mobjTo.particleSystems.length-1;
|
||||
var opsys = mobjTo.particleSystems[oslot];
|
||||
opsys.setupGeomGpu(mobjTo.particleChildren[oslot], mobjTo);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
66
leenkx/Sources/leenkx/logicnode/GetParticleDataNode.hx
Normal file
66
leenkx/Sources/leenkx/logicnode/GetParticleDataNode.hx
Normal file
@ -0,0 +1,66 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
class GetParticleDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var slot: Int = inputs[1].get();
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
#if lnx_particles
|
||||
|
||||
var mo = cast(object, iron.object.MeshObject);
|
||||
|
||||
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
|
||||
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null;
|
||||
|
||||
if (psys == null) return null;
|
||||
|
||||
return switch (from) {
|
||||
case 0:
|
||||
psys.r.name;
|
||||
case 1:
|
||||
psys.r.particle_size;
|
||||
case 2:
|
||||
psys.r.frame_start;
|
||||
case 3:
|
||||
psys.r.frame_end;
|
||||
case 4:
|
||||
psys.lifetime;
|
||||
case 5:
|
||||
psys.r.lifetime;
|
||||
case 6:
|
||||
psys.r.emit_from;
|
||||
case 7:
|
||||
new iron.math.Vec3(psys.alignx*2, psys.aligny*2, psys.alignz*2);
|
||||
case 8:
|
||||
psys.r.factor_random;
|
||||
case 9:
|
||||
new iron.math.Vec3(psys.gx, psys.gy, psys.gz);
|
||||
case 10:
|
||||
psys.r.weight_gravity;
|
||||
case 11:
|
||||
psys.speed;
|
||||
case 12:
|
||||
psys.time;
|
||||
case 13:
|
||||
psys.lap;
|
||||
case 14:
|
||||
psys.lapTime;
|
||||
case 15:
|
||||
psys.count;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
#end
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
38
leenkx/Sources/leenkx/logicnode/GetParticleNode.hx
Normal file
38
leenkx/Sources/leenkx/logicnode/GetParticleNode.hx
Normal file
@ -0,0 +1,38 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
class GetParticleNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
#if lnx_particles
|
||||
|
||||
var mo = cast(object, iron.object.MeshObject);
|
||||
|
||||
switch (from) {
|
||||
case 0:
|
||||
var names: Array<String> = [];
|
||||
if (mo.particleSystems != null)
|
||||
for (psys in mo.particleSystems)
|
||||
names.push(psys.r.name);
|
||||
return names;
|
||||
case 1:
|
||||
return mo.particleSystems != null ? mo.particleSystems.length : 0;
|
||||
case 2:
|
||||
return mo.render_emitter;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
#end
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
class RemoveParticleFromObjectNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
#if lnx_particles
|
||||
var object: Object = inputs[1].get();
|
||||
|
||||
if (object == null) return;
|
||||
|
||||
var mo = cast(object, iron.object.MeshObject);
|
||||
|
||||
if (mo.particleSystems == null) return;
|
||||
|
||||
if (property0 == 'All'){
|
||||
mo.particleSystems = null;
|
||||
for (c in mo.particleChildren) c.remove();
|
||||
mo.particleChildren = null;
|
||||
mo.particleOwner = null;
|
||||
mo.render_emitter = true;
|
||||
}
|
||||
else {
|
||||
|
||||
var slot: Int = -1;
|
||||
if (property0 == 'Name'){
|
||||
var name: String = inputs[2].get();
|
||||
for (i => psys in mo.particleSystems){
|
||||
if (psys.r.name == name){ slot = i; break; }
|
||||
}
|
||||
}
|
||||
else slot = inputs[2].get();
|
||||
|
||||
if (mo.particleSystems.length > slot){
|
||||
for (i in slot+1...mo.particleSystems.length){
|
||||
var mi = cast(mo.particleChildren[i], iron.object.MeshObject);
|
||||
mi.particleIndex = mi.particleIndex - 1;
|
||||
}
|
||||
mo.particleSystems.splice(slot, 1);
|
||||
mo.particleChildren[slot].remove();
|
||||
mo.particleChildren.splice(slot, 1);
|
||||
}
|
||||
|
||||
if (slot == 0){
|
||||
mo.particleSystems = null;
|
||||
mo.particleChildren = null;
|
||||
mo.particleOwner = null;
|
||||
mo.render_emitter = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
75
leenkx/Sources/leenkx/logicnode/SetParticleDataNode.hx
Normal file
75
leenkx/Sources/leenkx/logicnode/SetParticleDataNode.hx
Normal file
@ -0,0 +1,75 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
class SetParticleDataNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
#if lnx_particles
|
||||
var object: Object = inputs[1].get();
|
||||
var slot: Int = inputs[2].get();
|
||||
|
||||
if (object == null) return;
|
||||
|
||||
var mo = cast(object, iron.object.MeshObject);
|
||||
|
||||
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
|
||||
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null; if (psys == null) return;
|
||||
|
||||
switch (property0) {
|
||||
case 'Particle Size':
|
||||
psys.r.particle_size = inputs[3].get();
|
||||
case 'Frame Start':
|
||||
psys.r.frame_start = inputs[3].get();
|
||||
psys.animtime = (psys.r.frame_end - psys.r.frame_start) / psys.frameRate;
|
||||
psys.spawnRate = ((psys.r.frame_end - psys.r.frame_start) / psys.count) / psys.frameRate;
|
||||
case 'Frame End':
|
||||
psys.r.frame_end = inputs[3].get();
|
||||
psys.animtime = (psys.r.frame_end - psys.r.frame_start) / psys.frameRate;
|
||||
psys.spawnRate = ((psys.r.frame_end - psys.r.frame_start) / psys.count) / psys.frameRate;
|
||||
case 'Lifetime':
|
||||
psys.lifetime = inputs[3].get() / psys.frameRate;
|
||||
case 'Lifetime Random':
|
||||
psys.r.lifetime_random = inputs[3].get();
|
||||
case 'Emit From':
|
||||
var emit_from: Int = inputs[3].get();
|
||||
if (emit_from == 0 || emit_from == 1 || emit_from == 2) {
|
||||
psys.r.emit_from = emit_from;
|
||||
psys.setupGeomGpu(mo.particleChildren != null ? mo.particleChildren[slot] : cast(iron.Scene.active.getChild(psys.data.raw.instance_object), iron.object.MeshObject), mo);
|
||||
}
|
||||
case 'Velocity':
|
||||
var vel: iron.math.Vec3 = inputs[3].get();
|
||||
psys.alignx = vel.x / 2;
|
||||
psys.aligny = vel.y / 2;
|
||||
psys.alignz = vel.z / 2;
|
||||
case 'Velocity Random':
|
||||
psys.r.factor_random = inputs[3].get();
|
||||
case 'Weight Gravity':
|
||||
psys.r.weight_gravity = inputs[3].get();
|
||||
if (iron.Scene.active.raw.gravity != null) {
|
||||
psys.gx = iron.Scene.active.raw.gravity[0] * psys.r.weight_gravity;
|
||||
psys.gy = iron.Scene.active.raw.gravity[1] * psys.r.weight_gravity;
|
||||
psys.gz = iron.Scene.active.raw.gravity[2] * psys.r.weight_gravity;
|
||||
}
|
||||
else {
|
||||
psys.gx = 0;
|
||||
psys.gy = 0;
|
||||
psys.gz = -9.81 * psys.r.weight_gravity;
|
||||
}
|
||||
case 'Speed':
|
||||
psys.speed = inputs[3].get();
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
class SetParticleRenderEmitterNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
#if lnx_particles
|
||||
var object: Object = inputs[1].get();
|
||||
|
||||
if (object == null) return;
|
||||
|
||||
cast(object, iron.object.MeshObject).render_emitter = inputs[2].get();
|
||||
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
@ -11,13 +11,16 @@ class SetParticleSpeedNode extends LogicNode {
|
||||
override function run(from: Int) {
|
||||
#if lnx_particles
|
||||
var object: Object = inputs[1].get();
|
||||
var speed: Float = inputs[2].get();
|
||||
var slot: Int = inputs[2].get();
|
||||
var speed: Float = inputs[3].get();
|
||||
|
||||
if (object == null) return;
|
||||
|
||||
var mo = cast(object, iron.object.MeshObject);
|
||||
var psys = mo.particleSystems.length > 0 ? mo.particleSystems[0] : null;
|
||||
if (psys == null) mo.particleOwner.particleSystems[0];
|
||||
var psys = mo.particleSystems != null ? mo.particleSystems[slot] :
|
||||
mo.particleOwner != null && mo.particleOwner.particleSystems != null ? mo.particleOwner.particleSystems[slot] : null;
|
||||
|
||||
if (psys == null) return;
|
||||
|
||||
psys.speed = speed;
|
||||
|
||||
|
@ -47,7 +47,8 @@ def init_categories():
|
||||
lnx_nodes.add_category('Navmesh', icon='UV_VERTEXSEL', section="motion")
|
||||
lnx_nodes.add_category('Transform', icon='TRANSFORM_ORIGINS', section="motion")
|
||||
lnx_nodes.add_category('Physics', icon='PHYSICS', section="motion")
|
||||
|
||||
lnx_nodes.add_category('Particle', icon='PARTICLE_DATA', section="motion")
|
||||
|
||||
lnx_nodes.add_category('Array', icon='MOD_ARRAY', section="values")
|
||||
lnx_nodes.add_category('Map', icon='SHORTDISPLAY', section="values")
|
||||
lnx_nodes.add_category('Database', icon='MESH_CYLINDER', section="values")
|
||||
|
@ -0,0 +1,41 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class AddParticleToObjectNode(LnxLogicTreeNode):
|
||||
"""Sets the speed of the given particle source."""
|
||||
bl_idname = 'LNAddParticleToObjectNode'
|
||||
bl_label = 'Add Particle To Object'
|
||||
lnx_version = 1
|
||||
|
||||
def remove_extra_inputs(self, context):
|
||||
while len(self.inputs) > 1:
|
||||
self.inputs.remove(self.inputs[-1])
|
||||
if self.property0 == 'Scene':
|
||||
self.add_input('LnxStringSocket', 'Scene From Name')
|
||||
self.add_input('LnxStringSocket', 'Object From Name')
|
||||
else:
|
||||
self.add_input('LnxNodeSocketObject', 'Object From')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxNodeSocketObject', 'Object To')
|
||||
self.add_input('LnxBoolSocket', 'Render Emitter', default_value = True)
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Scene Active', 'Scene Active', 'Scene Active'),
|
||||
('Scene', 'Scene', 'Scene')],
|
||||
name='', default='Scene Active', update=remove_extra_inputs)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object From')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxNodeSocketObject', 'Object To')
|
||||
self.add_input('LnxBoolSocket', 'Render Emitter', default_value = True)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
14
leenkx/blender/lnx/logicnode/particle/LN_get_particle.py
Normal file
14
leenkx/blender/lnx/logicnode/particle/LN_get_particle.py
Normal file
@ -0,0 +1,14 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetParticleNode(LnxLogicTreeNode):
|
||||
"""Returns the Particle Systems of an object."""
|
||||
bl_idname = 'LNGetParticleNode'
|
||||
bl_label = 'Get Particle'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketObject', 'Object')
|
||||
|
||||
self.outputs.new('LnxNodeSocketArray', 'Names')
|
||||
self.outputs.new('LnxIntSocket', 'Length')
|
||||
self.outputs.new('LnxBoolSocket', 'Render Emitter')
|
@ -0,0 +1,31 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetParticleDataNode(LnxLogicTreeNode):
|
||||
"""Returns the data of the given Particle System."""
|
||||
bl_idname = 'LNGetParticleDataNode'
|
||||
bl_label = 'Get Particle Data'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketObject', 'Object')
|
||||
self.inputs.new('LnxIntSocket', 'Slot')
|
||||
|
||||
self.outputs.new('LnxStringSocket', 'Name')
|
||||
self.outputs.new('LnxFloatSocket', 'Particle Size')
|
||||
self.outputs.new('LnxIntSocket', 'Frame Start')
|
||||
self.outputs.new('LnxIntSocket', 'Frame End')
|
||||
self.outputs.new('LnxIntSocket', 'Lifetime')
|
||||
self.outputs.new('LnxFloatSocket', 'Lifetime Random')
|
||||
self.outputs.new('LnxIntSocket', 'Emit From')
|
||||
|
||||
self.outputs.new('LnxVectorSocket', 'Velocity')
|
||||
self.outputs.new('LnxFloatSocket', 'Velocity Random')
|
||||
self.outputs.new('LnxVectorSocket', 'Gravity')
|
||||
self.outputs.new('LnxFloatSocket', 'Weight Gravity')
|
||||
|
||||
self.outputs.new('LnxFloatSocket', 'Speed')
|
||||
|
||||
self.outputs.new('LnxFloatSocket', 'Time')
|
||||
self.outputs.new('LnxFloatSocket', 'Lap')
|
||||
self.outputs.new('LnxFloatSocket', 'Lap Time')
|
||||
self.outputs.new('LnxIntSocket', 'Count')
|
@ -0,0 +1,33 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class RemoveParticleFromObjectNode(LnxLogicTreeNode):
|
||||
"""Remove Particle From Object."""
|
||||
bl_idname = 'LNRemoveParticleFromObjectNode'
|
||||
bl_label = 'Remove Particle From Object'
|
||||
lnx_version = 1
|
||||
|
||||
def remove_extra_inputs(self, context):
|
||||
while len(self.inputs) > 2:
|
||||
self.inputs.remove(self.inputs[-1])
|
||||
if self.property0 == 'Slot':
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
if self.property0 == 'Name':
|
||||
self.add_input('LnxStringSocket', 'Name')
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Slot', 'Slot', 'Slot'),
|
||||
('Name', 'Name', 'Name'),
|
||||
('All', 'All', 'All')],
|
||||
name='', default='Slot', update=remove_extra_inputs)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
@ -0,0 +1,58 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetParticleDataNode(LnxLogicTreeNode):
|
||||
"""Sets the parameters of the given particle system."""
|
||||
bl_idname = 'LNSetParticleDataNode'
|
||||
bl_label = 'Set Particle Data'
|
||||
lnx_version = 1
|
||||
|
||||
def remove_extra_inputs(self, context):
|
||||
while len(self.inputs) > 3:
|
||||
self.inputs.remove(self.inputs[-1])
|
||||
if self.property0 == 'Particle Size':
|
||||
self.add_input('LnxFloatSocket', 'Particle Size')
|
||||
if self.property0 == 'Frame End':
|
||||
self.add_input('LnxIntSocket', 'Frame End')
|
||||
if self.property0 == 'Frame Start':
|
||||
self.add_input('LnxIntSocket', 'Frame Start')
|
||||
if self.property0 == 'Lifetime':
|
||||
self.add_input('LnxIntSocket', 'Lifetime')
|
||||
if self.property0 == 'Lifetime Random':
|
||||
self.add_input('LnxFloatSocket', 'Lifetime Random')
|
||||
if self.property0 == 'Emit From':
|
||||
self.add_input('LnxIntSocket', 'Emit From')
|
||||
if self.property0 == 'Velocity':
|
||||
self.add_input('LnxVectorSocket', 'Velocity')
|
||||
if self.property0 == 'Velocity Random':
|
||||
self.add_input('LnxFloatSocket', 'Velocity Random')
|
||||
if self.property0 == 'Weight Gravity':
|
||||
self.add_input('LnxFloatSocket', 'Weight Gravity')
|
||||
if self.property0 == 'Speed':
|
||||
self.add_input('LnxFloatSocket', 'Speed')
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Particle Size', 'Particle Size', 'for the system'),
|
||||
('Frame Start', 'Frame Start', 'for the system'),
|
||||
('Frame End', 'Frame End', 'for the system'),
|
||||
('Lifetime', 'Lifetime', 'for the instance'),
|
||||
('Lifetime Random', 'Lifetime Random', 'for the system'),
|
||||
('Emit From', 'Emit From', 'for the system (Vertices:0 Faces:1 Volume: 2)'),
|
||||
('Velocity', 'Velocity', 'for the instance'),
|
||||
('Velocity Random', 'Velocity Random', 'for the system'),
|
||||
('Weight Gravity', 'Weight Gravity', 'for the instance'),
|
||||
('Speed', 'Speed', 'for the instance')],
|
||||
name='', default='Speed', update=remove_extra_inputs)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
@ -1,14 +1,22 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetParticleSpeedNode(LnxLogicTreeNode):
|
||||
"""Sets the speed of the given particle source."""
|
||||
bl_idname = 'LNSetParticleSpeedNode'
|
||||
bl_label = 'Set Particle Speed'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetParticleSpeedNode(LnxLogicTreeNode):
|
||||
"""Sets the speed of the given particle source."""
|
||||
bl_idname = 'LNSetParticleSpeedNode'
|
||||
bl_label = 'Set Particle Speed'
|
||||
lnx_version = 2
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
|
||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||
if self.lnx_version not in (0, 1):
|
||||
raise LookupError()
|
||||
|
||||
return NodeReplacement.Identity(self)
|
3
leenkx/blender/lnx/logicnode/particle/__init__.py
Normal file
3
leenkx/blender/lnx/logicnode/particle/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from lnx.logicnode.lnx_nodes import add_node_section
|
||||
|
||||
add_node_section(name='default', category='Particle')
|
Loading…
x
Reference in New Issue
Block a user