forked from LeenkxTeam/LNXSDK
Repe [T3DU] Update - 31f26d171bba0355ce2a77031e3aad4c64dbc7e9
This commit is contained in:
12
leenkx/Sources/leenkx/logicnode/ActiveSceneObjectNode.hx
Normal file
12
leenkx/Sources/leenkx/logicnode/ActiveSceneObjectNode.hx
Normal file
@ -0,0 +1,12 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class ActiveSceneObjectNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return iron.Scene.active.root.getChild(iron.Scene.active.raw.name);
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,8 @@ package leenkx.logicnode;
|
||||
import iron.data.SceneFormat.TSceneFormat;
|
||||
import iron.data.Data;
|
||||
import iron.object.Object;
|
||||
import iron.object.MeshObject;
|
||||
import iron.Scene;
|
||||
|
||||
class AddParticleToObjectNode extends LogicNode {
|
||||
|
||||
@ -22,22 +24,22 @@ class AddParticleToObjectNode extends LogicNode {
|
||||
|
||||
if (objFrom == null || objTo == null) return;
|
||||
|
||||
var mobjFrom = cast(objFrom, iron.object.MeshObject);
|
||||
var mobjFrom = cast(objFrom, 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: @:privateAccess psys.r.name});
|
||||
var mobjTo = cast(objTo, MeshObject);
|
||||
|
||||
mobjTo.setupParticleSystem(Scene.active.raw.name, {name: 'LnxPS', seed: 0, particle: @:privateAccess psys.r.name});
|
||||
|
||||
mobjTo.render_emitter = inputs[4].get();
|
||||
|
||||
iron.Scene.active.spawnObject(psys.data.raw.instance_object, null, function(o: Object) {
|
||||
Scene.active.spawnObject(psys.data.raw.instance_object, null, function(o: Object) {
|
||||
if (o != null) {
|
||||
var c: iron.object.MeshObject = cast o;
|
||||
var c: MeshObject = cast o;
|
||||
if (mobjTo.particleChildren == null) mobjTo.particleChildren = [];
|
||||
mobjTo.particleChildren.push(c);
|
||||
c.particleOwner = mobjTo;
|
||||
@ -55,7 +57,7 @@ class AddParticleToObjectNode extends LogicNode {
|
||||
var slot: Int = inputs[3].get();
|
||||
|
||||
var mobjTo: Object = inputs[4].get();
|
||||
var mobjTo = cast(mobjTo, iron.object.MeshObject);
|
||||
var mobjTo = cast(mobjTo, MeshObject);
|
||||
|
||||
#if lnx_json
|
||||
sceneName += ".json";
|
||||
@ -65,28 +67,34 @@ class AddParticleToObjectNode extends LogicNode {
|
||||
|
||||
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();
|
||||
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);
|
||||
for (i => ps in rawScene.particle_datas)
|
||||
if (obj.particle_refs[slot].particle == ps.name){
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
|
||||
var oslot: Int = mobjTo.particleSystems.length-1;
|
||||
var opsys = mobjTo.particleSystems[oslot];
|
||||
@:privateAccess opsys.setupGeomGpu(mobjTo.particleChildren[oslot]);
|
||||
Scene.active.spawnObject(rawScene.particle_datas[slot].instance_object, null, function(o: Object) {
|
||||
if (o != null) {
|
||||
var c: MeshObject = cast o;
|
||||
if (mobjTo.particleChildren == null) mobjTo.particleChildren = [];
|
||||
mobjTo.particleChildren.push(c);
|
||||
c.particleOwner = mobjTo;
|
||||
c.particleIndex = mobjTo.particleChildren.length - 1;
|
||||
}
|
||||
}, true, rawScene);
|
||||
|
||||
break;
|
||||
var oslot: Int = mobjTo.particleSystems.length-1;
|
||||
var opsys = mobjTo.particleSystems[oslot];
|
||||
@:privateAccess opsys.setupGeomGpu(mobjTo.particleChildren[oslot]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -111,7 +111,9 @@ class AddPhysicsConstraintNode extends LogicNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
pivotObject.addTrait(con);
|
||||
con.name = property0;
|
||||
|
||||
pivotObject.addTrait(con);
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
|
||||
46
leenkx/Sources/leenkx/logicnode/AddPhysicsHookNode.hx
Normal file
46
leenkx/Sources/leenkx/logicnode/AddPhysicsHookNode.hx
Normal file
@ -0,0 +1,46 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
#if lnx_bullet
|
||||
import leenkx.trait.physics.bullet.PhysicsHook;
|
||||
#end
|
||||
|
||||
class AddPhysicsHookNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var obj: Object = inputs[1].get();
|
||||
var target: Object = inputs[2].get();
|
||||
var inputVerts: Dynamic = inputs[3].get();
|
||||
|
||||
var flattenedVerts: Array<Float> = [];
|
||||
|
||||
if (Std.isOfType(inputVerts, Array)) {
|
||||
var vArray: Array<Dynamic> = cast inputVerts;
|
||||
for (v in vArray) {
|
||||
if (v.x != null) {
|
||||
flattenedVerts.push(v.x);
|
||||
flattenedVerts.push(v.y);
|
||||
flattenedVerts.push(v.z);
|
||||
}
|
||||
else if (v[0] != null) {
|
||||
flattenedVerts.push(v[0]);
|
||||
flattenedVerts.push(v[1]);
|
||||
flattenedVerts.push(v[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if lnx_bullet
|
||||
var hook = obj.getTrait(PhysicsHook);
|
||||
if (hook == null) {
|
||||
hook = new PhysicsHook(target.name, flattenedVerts);
|
||||
obj.addTrait(hook);
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
@ -20,7 +20,6 @@ class AddRigidBodyNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
object = inputs[1].get();
|
||||
if (object == null) return;
|
||||
|
||||
#if lnx_physics
|
||||
|
||||
@ -70,6 +69,7 @@ class AddRigidBodyNode extends LogicNode {
|
||||
case "Cylinder": shape = Cylinder;
|
||||
case "Convex Hull": shape = ConvexHull;
|
||||
case "Mesh": shape = Mesh;
|
||||
case "Compound Parent": shape = Compound;
|
||||
}
|
||||
|
||||
rb = new RigidBody(shape, mass, friction, bounciness, group, mask);
|
||||
@ -77,6 +77,48 @@ class AddRigidBodyNode extends LogicNode {
|
||||
rb.staticObj = !active;
|
||||
rb.isTriggerObject(trigger);
|
||||
|
||||
if (property0 == "Compound Parent") {
|
||||
var compoundChildren = [];
|
||||
for (child in object.children) {
|
||||
var childRb: RigidBody = child.getTrait(RigidBody);
|
||||
if (childRb != null) {
|
||||
var childShape = 0;
|
||||
switch (@:privateAccess childRb.shape) {
|
||||
case Box: childShape = 0;
|
||||
case Sphere: childShape = 1;
|
||||
case ConvexHull: childShape = 2;
|
||||
case Mesh: childShape = 3;
|
||||
case Cone: childShape = 4;
|
||||
case Cylinder: childShape = 5;
|
||||
case Capsule: childShape = 6;
|
||||
default: childShape = 0;
|
||||
}
|
||||
childRb.remove();
|
||||
var m = object.transform.world.clone();
|
||||
m.getInverse(object.transform.world);
|
||||
m.multmat(child.transform.world);
|
||||
var loc = new iron.math.Vec4();
|
||||
var rot = new iron.math.Quat();
|
||||
var scl = new iron.math.Vec4();
|
||||
m.decompose(loc, rot, scl);
|
||||
compoundChildren.push({
|
||||
shape: childShape,
|
||||
posX: loc.x,
|
||||
posY: loc.y,
|
||||
posZ: loc.z,
|
||||
rotX: rot.x,
|
||||
rotY: rot.y,
|
||||
rotZ: rot.z,
|
||||
rotW: rot.w,
|
||||
dimX: child.transform.dim.x,
|
||||
dimY: child.transform.dim.y,
|
||||
dimZ: child.transform.dim.z
|
||||
});
|
||||
}
|
||||
}
|
||||
@:privateAccess rb.compoundChildren = compoundChildren;
|
||||
}
|
||||
|
||||
if (property1) {
|
||||
rb.linearDamping = linDamp;
|
||||
rb.angularDamping = angDamp;
|
||||
|
||||
38
leenkx/Sources/leenkx/logicnode/AddSoftBodyNode.hx
Normal file
38
leenkx/Sources/leenkx/logicnode/AddSoftBodyNode.hx
Normal file
@ -0,0 +1,38 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
#if lnx_physics_soft
|
||||
import leenkx.trait.physics.bullet.SoftBody;
|
||||
#end
|
||||
|
||||
class AddSoftBodyNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var obj: Object = inputs[1].get();
|
||||
if (obj == null) return;
|
||||
|
||||
var shape: Int = inputs[2].get(); // 0: Cloth, 1: Volume
|
||||
var bend: Float = inputs[3].get();
|
||||
var mass: Float = inputs[4].get();
|
||||
var margin: Float = inputs[5].get();
|
||||
var friction: Float = inputs[6].get();
|
||||
var damping: Float = inputs[7].get();
|
||||
var pressure: Float = inputs[8].get();
|
||||
var lStiff: Float = inputs[9].get();
|
||||
var aStiff: Float = inputs[10].get();
|
||||
|
||||
#if lnx_physics_soft
|
||||
var sb: SoftBody = obj.getTrait(SoftBody);
|
||||
if (sb == null) {
|
||||
sb = new SoftBody(shape, bend, mass, margin, friction, damping, lStiff, aStiff, pressure);
|
||||
obj.addTrait(sb);
|
||||
}
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
@ -4,25 +4,38 @@ import iron.object.Object;
|
||||
|
||||
class AddTraitNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
var trait: Dynamic;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var object: Object = inputs[1].get();
|
||||
var traitName: String = inputs[2].get();
|
||||
|
||||
assert(Error, object != null, "Object should not be null");
|
||||
assert(Error, traitName != null, "Trait name should not be null");
|
||||
|
||||
var cname = Type.resolveClass(Main.projectPackage + "." + traitName);
|
||||
if (cname == null) cname = Type.resolveClass(Main.projectPackage + ".node." + traitName);
|
||||
assert(Error, cname != null, 'No trait with the name "$traitName" found, make sure that the trait is exported!');
|
||||
assert(Warning, object.getTrait(cname) == null, 'Object already has the trait "$traitName" applied');
|
||||
if (property0 == 'TraitName'){
|
||||
var traitName: String = inputs[2].get();
|
||||
|
||||
assert(Error, traitName != null, "Trait name should not be null");
|
||||
|
||||
var cname = Type.resolveClass(Main.projectPackage + "." + traitName);
|
||||
if (cname == null) cname = Type.resolveClass(Main.projectPackage + ".node." + traitName);
|
||||
assert(Error, cname != null, 'No trait with the name "$traitName" found, make sure that the trait is exported!');
|
||||
assert(Warning, object.getTrait(cname) == null, 'Object already has the trait "$traitName" applied');
|
||||
|
||||
trait = Type.createInstance(cname, []);
|
||||
|
||||
} else
|
||||
trait = inputs[2].get();
|
||||
|
||||
var trait = Type.createInstance(cname, []);
|
||||
object.addTrait(trait);
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return trait;
|
||||
}
|
||||
}
|
||||
|
||||
23
leenkx/Sources/leenkx/logicnode/AlongCurveNode.hx
Normal file
23
leenkx/Sources/leenkx/logicnode/AlongCurveNode.hx
Normal file
@ -0,0 +1,23 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.CurveObject;
|
||||
|
||||
class AlongCurveNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var object: Object = inputs[1].get();
|
||||
var curve: CurveObject = inputs[2].get();
|
||||
var splineIdx: Int = inputs[3].get();
|
||||
var forwardAxis: String = inputs[4].get();
|
||||
var position: Float = inputs[5].get();
|
||||
|
||||
curve.follow(object, position, splineIdx, forwardAxis);
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
35
leenkx/Sources/leenkx/logicnode/AnimationNode.hx
Normal file
35
leenkx/Sources/leenkx/logicnode/AnimationNode.hx
Normal file
@ -0,0 +1,35 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.Animation;
|
||||
import iron.object.ObjectAnimation;
|
||||
|
||||
class AnimationNode 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 from == 0 ? null : 0;
|
||||
|
||||
var animation: Animation = object.animation;
|
||||
if (animation == null) animation = object.getParentArmature(object.name);
|
||||
|
||||
var actions: Array<String> = [];
|
||||
|
||||
if (animation.isSkinned)
|
||||
for(a in animation.armature.actions)
|
||||
actions.push(a.name);
|
||||
else
|
||||
for (a in cast(animation, ObjectAnimation).oactions)
|
||||
if (a != null)
|
||||
actions.push(a.objects[0].name);
|
||||
|
||||
return from == 0 ? actions : actions.length;
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavMesh;
|
||||
#end
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class AroundNavigableLocationNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if lnx_navigation
|
||||
var activeNavMesh: NavMesh = Navigation.active.navMeshes.get(inputs[0].get());
|
||||
var position: Vec4 = inputs[1].get();
|
||||
var radius: Float = inputs[2].get();
|
||||
|
||||
assert(Error, activeNavMesh != null, "No Navigation Mesh Present");
|
||||
return activeNavMesh.getRandomPointAround(position, radius);
|
||||
#end
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ class ArrayAddNode extends LogicNode {
|
||||
override function run(from: Int) {
|
||||
ar = inputs[1].get();
|
||||
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
// "Modify Original" == `false` -> Copy the input array
|
||||
if (!inputs[2].get()) {
|
||||
|
||||
@ -2,7 +2,7 @@ package leenkx.logicnode;
|
||||
|
||||
class ArrayGetNextNode extends LogicNode {
|
||||
|
||||
var i = 0;
|
||||
var i = -1;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -13,12 +13,12 @@ class ArrayGetNextNode extends LogicNode {
|
||||
|
||||
if (ar == null) return null;
|
||||
|
||||
var value = ar[i];
|
||||
|
||||
if (i < ar.length - 1)
|
||||
i++;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
var value = ar[i];
|
||||
|
||||
return value;
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ package leenkx.logicnode;
|
||||
|
||||
class ArrayGetPreviousNextNode extends LogicNode {
|
||||
|
||||
var i = 0;
|
||||
var i = -1;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
|
||||
@ -13,7 +13,7 @@ class ArrayInsertNode extends LogicNode {
|
||||
var index: Int = inputs[2].get();
|
||||
var value: Dynamic = inputs[3].get();
|
||||
|
||||
if (ar == null || value == null) return;
|
||||
assert(Error, ar != null && value != null, 'Array or Value should not be null');
|
||||
|
||||
ar.insert(index, value);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ class ArrayLoopNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
var ar: Array<Dynamic> = inputs[1].get();
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
index = -1;
|
||||
for (val in ar) {
|
||||
|
||||
@ -10,7 +10,7 @@ class ArrayRemoveNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
var ar: Array<Dynamic> = inputs[1].get();
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
var i: Int = inputs[2].get();
|
||||
if (i < 0) i = ar.length + i;
|
||||
|
||||
@ -10,7 +10,7 @@ class ArrayRemoveValueNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
var ar: Array<Dynamic> = inputs[1].get();
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
var val: Dynamic = inputs[2].get();
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ class ArrayResizeNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
var ar: Array<Dynamic> = inputs[1].get();
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
var len = inputs[2].get();
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ class ArraySetNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
var ar: Array<Dynamic> = inputs[1].get();
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
var i: Int = inputs[2].get();
|
||||
var value: Dynamic = inputs[3].get();
|
||||
|
||||
@ -10,7 +10,7 @@ class ArraySpliceNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
var ar: Array<Dynamic> = inputs[1].get();
|
||||
if (ar == null) return;
|
||||
assert(Error, ar != null, 'Array should not be null');
|
||||
|
||||
var i = inputs[2].get();
|
||||
var len = inputs[3].get();
|
||||
|
||||
62
leenkx/Sources/leenkx/logicnode/AsyncArrayLoopNode.hx
Normal file
62
leenkx/Sources/leenkx/logicnode/AsyncArrayLoopNode.hx
Normal file
@ -0,0 +1,62 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class AsyncArrayLoopNode extends LogicNode {
|
||||
|
||||
var array:Array<Dynamic>;
|
||||
var index:Int = 0;
|
||||
var running:Bool = false;
|
||||
var itemsPerFrame:Int = 1;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
array = inputs[1].get();
|
||||
itemsPerFrame = inputs[2].get();
|
||||
index = 0;
|
||||
if (array == null || array.length == 0) {
|
||||
runOutput(3);
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
tree.notifyOnUpdate(update);
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (!running) return;
|
||||
|
||||
var processed = 0;
|
||||
while (processed < itemsPerFrame && index < array.length) {
|
||||
index++;
|
||||
processed++;
|
||||
runOutput(0);
|
||||
|
||||
if (tree.loopBreak) {
|
||||
tree.loopBreak = false;
|
||||
running = false;
|
||||
tree.removeUpdate(update);
|
||||
runOutput(2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tree.loopContinue) {
|
||||
tree.loopContinue = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= array.length) {
|
||||
running = false;
|
||||
tree.removeUpdate(update);
|
||||
runOutput(3);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
if (from == 1)
|
||||
return array[index - 1];
|
||||
return index - 1;
|
||||
|
||||
}
|
||||
}
|
||||
63
leenkx/Sources/leenkx/logicnode/AsyncLoopNode.hx
Normal file
63
leenkx/Sources/leenkx/logicnode/AsyncLoopNode.hx
Normal file
@ -0,0 +1,63 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class AsyncLoopNode extends LogicNode {
|
||||
|
||||
var from:Int;
|
||||
var to:Int;
|
||||
var index:Int;
|
||||
var running:Bool = false;
|
||||
var itemsPerFrame:Int = 1;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
this.from = inputs[1].get();
|
||||
this.to = inputs[2].get();
|
||||
this.itemsPerFrame = inputs[3].get();
|
||||
index = this.from;
|
||||
|
||||
if (this.from >= this.to) {
|
||||
runOutput(2);
|
||||
return;
|
||||
}
|
||||
|
||||
running = true;
|
||||
tree.notifyOnUpdate(update);
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (!running) return;
|
||||
|
||||
var processed = 0;
|
||||
while (processed < itemsPerFrame && index < to) {
|
||||
runOutput(0);
|
||||
index++;
|
||||
processed++;
|
||||
|
||||
if (tree.loopBreak) {
|
||||
tree.loopBreak = false;
|
||||
running = false;
|
||||
tree.removeUpdate(update);
|
||||
runOutput(2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tree.loopContinue) {
|
||||
tree.loopContinue = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= to) {
|
||||
running = false;
|
||||
tree.removeUpdate(update);
|
||||
runOutput(2);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return index - 1;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
class CallFunctionNode extends LogicNode {
|
||||
|
||||
var result: Dynamic;
|
||||
@ -11,8 +9,8 @@ class CallFunctionNode extends LogicNode {
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var object: Dynamic = inputs[1].get();
|
||||
if (object == null) return;
|
||||
var trait: Dynamic = inputs[1].get();
|
||||
if (trait == null){ runOutput(0); return; }
|
||||
|
||||
var funName: String = inputs[2].get();
|
||||
var args: Array<Dynamic> = [];
|
||||
@ -21,9 +19,9 @@ class CallFunctionNode extends LogicNode {
|
||||
args.push(inputs[i].get());
|
||||
}
|
||||
|
||||
var func = Reflect.field(object, funName);
|
||||
var func = Reflect.field(trait, funName);
|
||||
if (func != null) {
|
||||
result = Reflect.callMethod(object, func, args);
|
||||
result = Reflect.callMethod(trait, func, args);
|
||||
}
|
||||
|
||||
runOutput(0);
|
||||
|
||||
@ -14,14 +14,16 @@ class CameraGetNode extends LogicNode {
|
||||
case 3: leenkx.renderpath.Postprocess.camera_uniforms[3];//Camera: Exposure Compensation
|
||||
case 4: leenkx.renderpath.Postprocess.camera_uniforms[4];//Fisheye Distortion
|
||||
case 5: leenkx.renderpath.Postprocess.camera_uniforms[5];//DoF AutoFocus §§ If true, it ignores the DoF Distance setting
|
||||
case 6: leenkx.renderpath.Postprocess.camera_uniforms[6];//DoF Distance
|
||||
case 7: leenkx.renderpath.Postprocess.camera_uniforms[7];//DoF Focal Length mm
|
||||
case 8: leenkx.renderpath.Postprocess.camera_uniforms[8];//DoF F-Stop
|
||||
case 9: leenkx.renderpath.Postprocess.camera_uniforms[9];//Tonemapping Method
|
||||
case 10: leenkx.renderpath.Postprocess.camera_uniforms[10];//Distort
|
||||
case 11: leenkx.renderpath.Postprocess.camera_uniforms[11];//Film Grain
|
||||
case 12: leenkx.renderpath.Postprocess.camera_uniforms[12];//Sharpen
|
||||
case 13: leenkx.renderpath.Postprocess.camera_uniforms[13];//Vignette
|
||||
case 6: new iron.math.Vec4(leenkx.renderpath.Postprocess.auto_focus[0], leenkx.renderpath.Postprocess.auto_focus[1], 0, 1); //Auto Focus Value
|
||||
case 7: leenkx.renderpath.Postprocess.auto_focus[2]; //max blur
|
||||
case 8: leenkx.renderpath.Postprocess.camera_uniforms[6];//DoF Distance
|
||||
case 9: leenkx.renderpath.Postprocess.camera_uniforms[7];//DoF Focal Length mm
|
||||
case 10: leenkx.renderpath.Postprocess.camera_uniforms[8];//DoF F-Stop
|
||||
case 11: leenkx.renderpath.Postprocess.camera_uniforms[9];//Tonemapping Method
|
||||
case 12: leenkx.renderpath.Postprocess.camera_uniforms[10];//Distort
|
||||
case 13: leenkx.renderpath.Postprocess.camera_uniforms[11];//Film Grain
|
||||
case 14: leenkx.renderpath.Postprocess.camera_uniforms[12];//Sharpen
|
||||
case 15: leenkx.renderpath.Postprocess.camera_uniforms[13];//Vignette
|
||||
default: 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,11 @@ class CameraSetNode extends LogicNode {
|
||||
leenkx.renderpath.Postprocess.camera_uniforms[4] = inputs[1].get();//Fisheye Distortion
|
||||
case 'Auto Focus':
|
||||
leenkx.renderpath.Postprocess.camera_uniforms[5] = inputs[1].get();//DoF AutoFocus §§ If true, it ignores the DoF Distance setting
|
||||
case 'Auto Focus Value':
|
||||
leenkx.renderpath.Postprocess.auto_focus[0] = inputs[1].get().x;
|
||||
leenkx.renderpath.Postprocess.auto_focus[1] = inputs[1].get().y;
|
||||
case 'DoF Max Blur':
|
||||
leenkx.renderpath.Postprocess.auto_focus[2] = inputs[1].get(); // DoF Max Blur
|
||||
case 'DoF Distance':
|
||||
leenkx.renderpath.Postprocess.camera_uniforms[6] = inputs[1].get();//DoF Distance
|
||||
case 'DoF Length':
|
||||
|
||||
@ -14,6 +14,7 @@ class CanvasSetSliderNode extends LogicNode {
|
||||
}
|
||||
|
||||
#if lnx_ui
|
||||
/*
|
||||
function update() {
|
||||
if (!canvas.ready) return;
|
||||
|
||||
@ -26,7 +27,7 @@ class CanvasSetSliderNode extends LogicNode {
|
||||
catch (e: Dynamic) {}
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}*/
|
||||
|
||||
override function run(from: Int) {
|
||||
element = inputs[1].get();
|
||||
@ -34,9 +35,15 @@ class CanvasSetSliderNode extends LogicNode {
|
||||
|
||||
canvas = CanvasScript.getActiveCanvas();
|
||||
|
||||
canvas.notifyOnReady(() -> {
|
||||
canvas.getHandle(element).value = value;
|
||||
runOutput(0);
|
||||
|
||||
});
|
||||
|
||||
// Ensure canvas is ready
|
||||
tree.notifyOnUpdate(update);
|
||||
update();
|
||||
//tree.notifyOnUpdate(update);
|
||||
//update();
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
@ -4,148 +4,15 @@ import iron.math.Vec4;
|
||||
|
||||
class ColorMixNode extends LogicNode {
|
||||
|
||||
var SIZE:Int = 38;
|
||||
var GAMMA:Float = 2.4;
|
||||
var EPSILON:Float = 0.00000001;
|
||||
|
||||
var SPD_C:Array<Float> = [0.96853629, 0.96855103, 0.96859338, 0.96877345, 0.96942204, 0.97143709, 0.97541862, 0.98074186, 0.98580992, 0.98971194, 0.99238027, 0.99409844, 0.995172, 0.99576545, 0.99593552, 0.99564041, 0.99464769, 0.99229579, 0.98638762, 0.96829712, 0.89228016, 0.53740239, 0.15360445, 0.05705719, 0.03126539, 0.02205445, 0.01802271, 0.0161346, 0.01520947, 0.01475977, 0.01454263, 0.01444459, 0.01439897, 0.0143762, 0.01436343, 0.01435687, 0.0143537, 0.01435408];
|
||||
var SPD_M:Array<Float> = [0.51567122, 0.5401552, 0.62645502, 0.75595012, 0.92826996, 0.97223624, 0.98616174, 0.98955255, 0.98676237, 0.97312575, 0.91944277, 0.32564851, 0.13820628, 0.05015143, 0.02912336, 0.02421691, 0.02660696, 0.03407586, 0.04835936, 0.0001172, 0.00008554, 0.85267882, 0.93188793, 0.94810268, 0.94200977, 0.91478045, 0.87065445, 0.78827548, 0.65738359, 0.59909403, 0.56817268, 0.54031997, 0.52110241, 0.51041094, 0.50526577, 0.5025508, 0.50126452, 0.50083021];
|
||||
var SPD_Y:Array<Float> = [0.02055257, 0.02059936, 0.02062723, 0.02073387, 0.02114202, 0.02233154, 0.02556857, 0.03330189, 0.05185294, 0.10087639, 0.24000413, 0.53589066, 0.79874659, 0.91186529, 0.95399623, 0.97137099, 0.97939505, 0.98345207, 0.98553736, 0.98648905, 0.98674535, 0.98657555, 0.98611877, 0.98559942, 0.98507063, 0.98460039, 0.98425301, 0.98403909, 0.98388535, 0.98376116, 0.98368246, 0.98365023, 0.98361309, 0.98357259, 0.98353856, 0.98351247, 0.98350101, 0.98350852];
|
||||
var SPD_R:Array<Float> = [0.03147571, 0.03146636, 0.03140624, 0.03119611, 0.03053888, 0.02856855, 0.02459485, 0.0192952, 0.01423112, 0.01033111, 0.00765876, 0.00593693, 0.00485616, 0.00426186, 0.00409039, 0.00438375, 0.00537525, 0.00772962, 0.0136612, 0.03181352, 0.10791525, 0.46249516, 0.84604333, 0.94275572, 0.96860996, 0.97783966, 0.98187757, 0.98377315, 0.98470202, 0.98515481, 0.98537114, 0.98546685, 0.98550011, 0.98551031, 0.98550741, 0.98551323, 0.98551563, 0.98551547];
|
||||
var SPD_G:Array<Float> = [0.49108579, 0.46944057, 0.4016578, 0.2449042, 0.0682688, 0.02732883, 0.013606, 0.01000187, 0.01284127, 0.02636635, 0.07058713, 0.70421692, 0.85473994, 0.95081565, 0.9717037, 0.97651888, 0.97429245, 0.97012917, 0.9425863, 0.99989207, 0.99989891, 0.13823139, 0.06968113, 0.05628787, 0.06111561, 0.08987709, 0.13656016, 0.22169624, 0.32176956, 0.36157329, 0.4836192, 0.46488579, 0.47440306, 0.4857699, 0.49267971, 0.49625685, 0.49807754, 0.49889859];
|
||||
var SPD_B:Array<Float> = [0.97901834, 0.97901649, 0.97901118, 0.97892146, 0.97858555, 0.97743705, 0.97428075, 0.96663223, 0.94822893, 0.89937713, 0.76070164, 0.4642044, 0.20123039, 0.08808402, 0.04592894, 0.02860373, 0.02060067, 0.01656701, 0.01451549, 0.01357964, 0.01331243, 0.01347661, 0.01387181, 0.01435472, 0.01479836, 0.0151525, 0.01540513, 0.01557233, 0.0156571, 0.01571025, 0.01571916, 0.01572133, 0.01572502, 0.01571717, 0.01571905, 0.01571059, 0.01569728, 0.0157002];
|
||||
var CIE_CMF_X:Array<Float> = [0.00006469, 0.00021941, 0.00112057, 0.00376661, 0.01188055, 0.02328644, 0.03455942, 0.03722379, 0.03241838, 0.02123321, 0.01049099, 0.00329584, 0.00050704, 0.00094867, 0.00627372, 0.01686462, 0.02868965, 0.04267481, 0.05625475, 0.0694704, 0.08305315, 0.0861261, 0.09046614, 0.08500387, 0.07090667, 0.05062889, 0.03547396, 0.02146821, 0.01251646, 0.00680458, 0.00346457, 0.00149761, 0.0007697, 0.00040737, 0.00016901, 0.00009522, 0.00004903, 0.00002];
|
||||
var CIE_CMF_Y:Array<Float> = [0.00000184, 0.00000621, 0.00003101, 0.00010475, 0.00035364, 0.00095147, 0.00228226, 0.00420733, 0.0066888, 0.0098884, 0.01524945, 0.02141831, 0.03342293, 0.05131001, 0.07040208, 0.08783871, 0.09424905, 0.09795667, 0.09415219, 0.08678102, 0.07885653, 0.0635267, 0.05374142, 0.04264606, 0.03161735, 0.02088521, 0.01386011, 0.00810264, 0.0046301, 0.00249138, 0.0012593, 0.00054165, 0.00027795, 0.00014711, 0.00006103, 0.00003439, 0.00001771, 0.00000722];
|
||||
var CIE_CMF_Z:Array<Float> = [0.00030502, 0.00103681, 0.00531314, 0.01795439, 0.05707758, 0.11365162, 0.17335873, 0.19620658, 0.18608237, 0.13995048, 0.08917453, 0.04789621, 0.02814563, 0.01613766, 0.0077591, 0.00429615, 0.00200551, 0.00086147, 0.00036904, 0.00019143, 0.00014956, 0.00009231, 0.00006813, 0.00002883, 0.00001577, 0.00000394, 0.00000158, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
||||
var XYZ_RGB:Array<Array<Float>> = [[3.24306333, -1.53837619, -0.49893282], [-0.96896309, 1.87542451, 0.04154303], [0.05568392, -0.20417438, 1.05799454]];
|
||||
|
||||
public function linearToConcentration(l1:Float, l2:Float, t:Float):Float {
|
||||
var t1 = l1 * Math.pow(1 - t, 2);
|
||||
var t2 = l2 * Math.pow(t, 2);
|
||||
return t2 / (t1 + t2);
|
||||
}
|
||||
|
||||
public function spectralMix(color1:Array<Int>, color2:Array<Int>, t:Float):Array<Int> {
|
||||
var lrgb1 = srgbToLinear(color1);
|
||||
var lrgb2 = srgbToLinear(color2);
|
||||
|
||||
var R1 = linearToReflectance(lrgb1);
|
||||
var R2 = linearToReflectance(lrgb2);
|
||||
|
||||
var l1 = dotProduct(R1, CIE_CMF_Y);
|
||||
var l2 = dotProduct(R2, CIE_CMF_Y);
|
||||
|
||||
t = linearToConcentration(l1, l2, t);
|
||||
|
||||
var R:Array<Float> = new Array<Float>();
|
||||
for (i in 0...SIZE) {
|
||||
var KS = (1 - t) * Math.pow((1 - R1[i]), 2) / (2 * R1[i]) + t * Math.pow((1 - R2[i]), 2) / (2 * R2[i]);
|
||||
var KM = 1 + KS - Math.sqrt(KS * KS + 2 * KS);
|
||||
R.push(KM);
|
||||
}
|
||||
|
||||
var xyz = reflectanceToXYZ(R);
|
||||
return xyzToSrgb(xyz);
|
||||
}
|
||||
|
||||
public function uncompand(x:Float):Float {
|
||||
return x < 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, GAMMA);
|
||||
}
|
||||
|
||||
public function compand(x:Float):Float {
|
||||
return x < 0.0031308 ? x * 12.92 : 1.055 * Math.pow(x, 1.0 / GAMMA) - 0.055;
|
||||
}
|
||||
|
||||
public function srgbToLinear(srgb:Array<Int>):Array<Float> {
|
||||
var r = uncompand(srgb[0] / 255);
|
||||
var g = uncompand(srgb[1] / 255);
|
||||
var b = uncompand(srgb[2] / 255);
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
public function linearToSrgb(lrgb:Array<Float>):Array<Int> {
|
||||
var r = compand(lrgb[0]);
|
||||
var g = compand(lrgb[1]);
|
||||
var b = compand(lrgb[2]);
|
||||
return [Math.round(clamp(r, 0, 1) * 255), Math.round(clamp(g, 0, 1) * 255), Math.round(clamp(b, 0, 1) * 255)];
|
||||
}
|
||||
|
||||
public function reflectanceToXYZ(R:Array<Float>):Array<Float> {
|
||||
var x = dotProduct(R, CIE_CMF_X);
|
||||
var y = dotProduct(R, CIE_CMF_Y);
|
||||
var z = dotProduct(R, CIE_CMF_Z);
|
||||
return [x, y, z];
|
||||
}
|
||||
|
||||
public function xyzToSrgb(xyz:Array<Float>):Array<Int> {
|
||||
var r = dotProduct(XYZ_RGB[0], xyz);
|
||||
var g = dotProduct(XYZ_RGB[1], xyz);
|
||||
var b = dotProduct(XYZ_RGB[2], xyz);
|
||||
return linearToSrgb([r, g, b]);
|
||||
}
|
||||
|
||||
public function spectralUpsampling(lrgb:Array<Float>):Array<Float> {
|
||||
var w = Math.min(Math.min(lrgb[0], lrgb[1]), lrgb[2]);
|
||||
|
||||
var lrgbNew = [lrgb[0] - w, lrgb[1] - w, lrgb[2] - w];
|
||||
|
||||
var c = Math.min(lrgbNew[1], lrgbNew[2]);
|
||||
var m = Math.min(lrgbNew[0], lrgbNew[2]);
|
||||
var y = Math.min(lrgbNew[0], lrgbNew[1]);
|
||||
var r = Math.max(0, Math.min(lrgbNew[0] - lrgbNew[2], lrgbNew[0] - lrgbNew[1]));
|
||||
var g = Math.max(0, Math.min(lrgbNew[1] - lrgbNew[2], lrgbNew[1] - lrgbNew[0]));
|
||||
var b = Math.max(0, Math.min(lrgbNew[2] - lrgbNew[1], lrgbNew[2] - lrgbNew[0]));
|
||||
|
||||
return [w, c, m, y, r, g, b];
|
||||
}
|
||||
|
||||
public function linearToReflectance(lrgb:Array<Float>):Array<Float> {
|
||||
var weights = spectralUpsampling(lrgb);
|
||||
|
||||
var R:Array<Float> = new Array<Float>();
|
||||
for (i in 0...SIZE) {
|
||||
R[i] = Math.max(EPSILON,
|
||||
weights[0]
|
||||
+ weights[1] * SPD_C[i]
|
||||
+ weights[2] * SPD_M[i]
|
||||
+ weights[3] * SPD_Y[i]
|
||||
+ weights[4] * SPD_R[i]
|
||||
+ weights[5] * SPD_G[i]
|
||||
+ weights[6] * SPD_B[i]
|
||||
);
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
public function dotProduct(a:Array<Float>, b:Array<Float>):Float {
|
||||
var sum:Float = 0;
|
||||
for (i in 0...a.length) {
|
||||
sum += a[i] * b[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public function clamp(value:Float, minValue:Float, maxValue:Float):Float {
|
||||
return Math.min(Math.max(value, minValue), maxValue);
|
||||
}
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var Color1:Vec4 = inputs[0].get();
|
||||
var Color2:Vec4 = inputs[1].get();
|
||||
var mix:Float = inputs[2].get();
|
||||
|
||||
mix = Math.min(Math.max(mix, 0), 1);
|
||||
|
||||
var col1 = [Std.int(Color1.x*255), Std.int(Color1.y*255), Std.int(Color1.z*255)];
|
||||
var col2 = [Std.int(Color2.x*255), Std.int(Color2.y*255), Std.int(Color2.z*255)];
|
||||
|
||||
var ColorMix = spectralMix(col1, col2, mix);
|
||||
|
||||
return new Vec4(ColorMix[0]/255, ColorMix[1]/255, ColorMix[2]/255, (Color1.w+Color2.w)/2);
|
||||
var c1: Vec4 = inputs[0].get();
|
||||
var c2: Vec4 = inputs[1].get();
|
||||
var factor: Float = inputs[2].get();
|
||||
|
||||
return leenkx.trait.internal.Spectral.mix([c1, c2], [1.0 - factor, factor]);
|
||||
}
|
||||
}
|
||||
|
||||
26
leenkx/Sources/leenkx/logicnode/ColorsMixNode.hx
Normal file
26
leenkx/Sources/leenkx/logicnode/ColorsMixNode.hx
Normal file
@ -0,0 +1,26 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
import leenkx.trait.internal.Spectral;
|
||||
|
||||
class ColorsMixNode extends LogicNode {
|
||||
|
||||
var result = new Vec4();
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var colors: Array<Vec4> = inputs[0].get();
|
||||
var factors: Array<Float> = inputs[1].get();
|
||||
|
||||
if (colors == null || factors == null || colors.length == 0 || factors.length == 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.setFrom(Spectral.mix(colors, factors));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
73
leenkx/Sources/leenkx/logicnode/ConvexBreakNode.hx
Normal file
73
leenkx/Sources/leenkx/logicnode/ConvexBreakNode.hx
Normal file
@ -0,0 +1,73 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.MeshObject;
|
||||
import leenkx.object.BreakerExtension;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class ConvexBreakNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
|
||||
var objects: Array<Object>;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
objects = [];
|
||||
var object: Object = inputs[1].get();
|
||||
|
||||
var breaker: ConvexBreaker = new ConvexBreaker(0.1);
|
||||
@:privateAccess breaker.scaleUV = inputs[3].get();
|
||||
@:privateAccess breaker.flatShading = inputs[4].get();
|
||||
|
||||
breaker.initBreakableObject(cast object, 0, 0, new Vec4(), new Vec4(), true);
|
||||
|
||||
var debris: Array<MeshObject> = [];
|
||||
|
||||
if (property0 == 'Plane')
|
||||
debris = breaker.subdivideByPlane(cast object, inputs[3].get(), inputs[2].get());
|
||||
else
|
||||
debris = breaker.subdivideByImpact(cast object, inputs[2].get(), inputs[3].get(), 1, 1);
|
||||
|
||||
for (o in debris) {
|
||||
var obj: Object = cast o;
|
||||
obj.name = o.data.raw.name;
|
||||
|
||||
var dims = new kha.arrays.Float32Array(3);
|
||||
dims[0] = o.data.geom.aabb.x;
|
||||
dims[1] = o.data.geom.aabb.y;
|
||||
dims[2] = o.data.geom.aabb.z;
|
||||
|
||||
obj.raw = cast {
|
||||
type: "mesh_object",
|
||||
name: obj.name,
|
||||
data_ref: obj.name,
|
||||
dimensions: dims
|
||||
};
|
||||
|
||||
obj.addTrait(new leenkx.trait.internal.UniformsManager());
|
||||
|
||||
var ud = breaker.userDataMap.get(cast o);
|
||||
if (ud == null) continue;
|
||||
objects.push(obj);
|
||||
}
|
||||
|
||||
if (objects.length > 1){
|
||||
for (obj in objects)
|
||||
obj.setParent(iron.Scene.active.root);
|
||||
object.remove();
|
||||
runOutput(1);
|
||||
}
|
||||
else
|
||||
runOutput(2);
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return objects;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package leenkx.logicnode;
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
import leenkx.system.Event;
|
||||
|
||||
|
||||
class CreateMapNode extends LogicNode {
|
||||
|
||||
@ -2,6 +2,8 @@ package leenkx.logicnode;
|
||||
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavMesh;
|
||||
import leenkx.trait.NavCrowd;
|
||||
#end
|
||||
|
||||
import iron.object.Object;
|
||||
@ -9,24 +11,30 @@ import iron.math.Vec4;
|
||||
|
||||
class CrowdGoToLocationNode extends LogicNode {
|
||||
|
||||
var object: Object;
|
||||
var location: Vec4;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
object = inputs[1].get();
|
||||
location = inputs[2].get();
|
||||
|
||||
var navMeshId: String = inputs[1].get();
|
||||
var object: Object = inputs[2].get();
|
||||
var location: Vec4 = inputs[3].get();
|
||||
var maxSpeed: Float = inputs[4].get();
|
||||
var maxAcceleration: Float = inputs[5].get();
|
||||
var turnSpeed: Float = inputs[6].get();
|
||||
|
||||
assert(Error, object != null, "The object input not be null");
|
||||
assert(Error, location != null, "The location to navigate to must not be null");
|
||||
|
||||
#if lnx_navigation
|
||||
assert(Error, Navigation.active.navMeshes.length > 0, "No Navigation Mesh Present");
|
||||
var crowdAgent: leenkx.trait.NavCrowd = object.getTrait(leenkx.trait.NavCrowd);
|
||||
var activeNavMesh: NavMesh = Navigation.active.navMeshes.get(navMeshId);
|
||||
assert(Error, activeNavMesh != null, "No Navigation Mesh Present");
|
||||
|
||||
var crowdAgent: NavCrowd = object.getTrait(NavCrowd);
|
||||
assert(Error, crowdAgent != null, "Object does not have a NavCrowd trait");
|
||||
crowdAgent.crowdAgentSetMaxSpeed(maxSpeed);
|
||||
crowdAgent.crowdAgentSetMaxAcceleration(maxAcceleration);
|
||||
crowdAgent.turnSpeed = turnSpeed;
|
||||
crowdAgent.crowdAgentGoto(location);
|
||||
#end
|
||||
runOutput(0);
|
||||
|
||||
33
leenkx/Sources/leenkx/logicnode/CrowdSetLocationNode.hx
Normal file
33
leenkx/Sources/leenkx/logicnode/CrowdSetLocationNode.hx
Normal file
@ -0,0 +1,33 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavMesh;
|
||||
import leenkx.trait.NavCrowd;
|
||||
#end
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class CrowdSetLocationNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var navMeshId: String = inputs[1].get();
|
||||
var object: Object = inputs[2].get();
|
||||
var location: Vec4 = inputs[3].get();
|
||||
|
||||
#if lnx_navigation
|
||||
var activeNavMesh: NavMesh = Navigation.active.navMeshes.get(navMeshId);
|
||||
assert(Error, activeNavMesh != null, "No Navigation Mesh Present");
|
||||
|
||||
var crowdAgent: NavCrowd = object.getTrait(NavCrowd);
|
||||
assert(Error, crowdAgent != null, "Object does not have a NavCrowd trait");
|
||||
crowdAgent.crowdAgentTeleport(location);
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
33
leenkx/Sources/leenkx/logicnode/CurveGuideNode.hx
Normal file
33
leenkx/Sources/leenkx/logicnode/CurveGuideNode.hx
Normal file
@ -0,0 +1,33 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.MeshObject;
|
||||
|
||||
class CurveGuideNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
#if lnx_cpu_particles
|
||||
var object: Object = inputs[1].get();
|
||||
var slot: Int = inputs[2].get();
|
||||
|
||||
if (object == null){ runOutput(0); return; }
|
||||
|
||||
var mo: MeshObject = cast object;
|
||||
|
||||
var psys = mo.particleSystems != null ? mo.particleSystems[slot] : null;
|
||||
|
||||
if (psys == null){ runOutput(0); return; }
|
||||
|
||||
psys.curveGuides = inputs[3].get();
|
||||
psys.curveGuideStrength = inputs[4].get();
|
||||
psys.curveGuideSpeed = inputs[5].get();
|
||||
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
27
leenkx/Sources/leenkx/logicnode/DeformCurveNode.hx
Normal file
27
leenkx/Sources/leenkx/logicnode/DeformCurveNode.hx
Normal file
@ -0,0 +1,27 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.CurveObject;
|
||||
import iron.object.MeshObject;
|
||||
import iron.data.MeshData;
|
||||
|
||||
class DeformCurveNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var mo: MeshObject = inputs[1].get();
|
||||
var curve: CurveObject = inputs[2].get();
|
||||
|
||||
var mData: MeshData = curve.generateDeformedMesh(mo.data, inputs[3].get(), inputs[4].get(), 1, inputs[5].get(), inputs[6].get());
|
||||
|
||||
if (mData != null){
|
||||
mo.setData(mData);
|
||||
mo.transform.scale.set(1, 1, 1);
|
||||
mo.transform.buildMatrix();
|
||||
}
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
@ -8,11 +8,9 @@ import iron.object.CameraObject;
|
||||
import leenkx.renderpath.RenderPathCreator;
|
||||
|
||||
class DrawCameraNode extends LogicNode {
|
||||
static inline var numStaticInputs = 2;
|
||||
|
||||
var cameras: Array<CameraObject>;
|
||||
var renderTargets: Array<kha.Image>;
|
||||
var positions: Array<Vec2>;
|
||||
var camera: CameraObject;
|
||||
var renderTarget: kha.Image;
|
||||
var position: Vec2 = new Vec2();
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -21,39 +19,18 @@ class DrawCameraNode extends LogicNode {
|
||||
override function run(from: Int) {
|
||||
switch (from) {
|
||||
case 0: // Start
|
||||
if (cameras == null) {
|
||||
final numDynamicInputs = inputs.length - numStaticInputs;
|
||||
final numCams = Std.int(numDynamicInputs / 5);
|
||||
camera = inputs[2].get();
|
||||
position.set(
|
||||
inputs[3].get(),
|
||||
inputs[4].get()
|
||||
);
|
||||
|
||||
// Preallocate
|
||||
cameras = [];
|
||||
cameras.resize(numCams);
|
||||
|
||||
positions = [];
|
||||
positions.resize(numCams);
|
||||
for (i in 0...positions.length) {
|
||||
positions[i] = new Vec2();
|
||||
}
|
||||
|
||||
renderTargets = [];
|
||||
renderTargets.resize(numCams);
|
||||
}
|
||||
|
||||
for (i in 0...cameras.length) {
|
||||
cameras[i] = inputs[numStaticInputs + i * 5].get();
|
||||
positions[i].set(
|
||||
inputs[numStaticInputs + i * 5 + 1].get(),
|
||||
inputs[numStaticInputs + i * 5 + 2].get()
|
||||
);
|
||||
|
||||
// TODO: implement proper rendertarget cache/pool
|
||||
renderTargets[i] = kha.Image.createRenderTarget(
|
||||
inputs[numStaticInputs + i * 5 + 3].get(), // w
|
||||
inputs[numStaticInputs + i * 5 + 4].get(), // h
|
||||
kha.graphics4.TextureFormat.RGBA32,
|
||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil
|
||||
);
|
||||
}
|
||||
renderTarget = kha.Image.createRenderTarget(
|
||||
inputs[5].get(), // w
|
||||
inputs[6].get(), // h
|
||||
kha.graphics4.TextureFormat.RGBA32,
|
||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil
|
||||
);
|
||||
|
||||
tree.notifyOnRender(render);
|
||||
tree.notifyOnRender2D(render2D);
|
||||
@ -67,47 +44,45 @@ class DrawCameraNode extends LogicNode {
|
||||
}
|
||||
|
||||
function render(g:kha.graphics4.Graphics) {
|
||||
if (inputs[7].get()) return;
|
||||
final rpPaused = RenderPath.active.paused;
|
||||
RenderPath.active.paused = false;
|
||||
|
||||
final sceneCam = iron.Scene.active.camera;
|
||||
|
||||
for (i in 0...cameras.length) {
|
||||
final cam = cameras[i];
|
||||
final cam = camera;
|
||||
|
||||
final oldRT = cam.renderTarget;
|
||||
cam.renderTarget = renderTargets[i];
|
||||
final oldRT = cam.renderTarget;
|
||||
cam.renderTarget = renderTarget;
|
||||
|
||||
iron.Scene.active.camera = cam;
|
||||
cam.renderFrame(g);
|
||||
iron.Scene.active.camera = cam;
|
||||
cam.renderFrame(g);
|
||||
|
||||
cam.renderTarget = oldRT;
|
||||
}
|
||||
cam.renderTarget = oldRT;
|
||||
|
||||
iron.Scene.active.camera = sceneCam;
|
||||
RenderPath.active.paused = rpPaused;
|
||||
}
|
||||
|
||||
function render2D(g: kha.graphics2.Graphics) {
|
||||
for(i in 0...cameras.length) {
|
||||
final rt = renderTargets[i];
|
||||
if (inputs[7].get()) return;
|
||||
final rt = renderTarget;
|
||||
|
||||
positions[i].set(
|
||||
inputs[numStaticInputs + i * 5 + 1].get(),
|
||||
inputs[numStaticInputs + i * 5 + 2].get()
|
||||
);
|
||||
position.set(
|
||||
inputs[3].get(),
|
||||
inputs[4].get()
|
||||
);
|
||||
|
||||
final posX = positions[i].x;
|
||||
final posY = positions[i].y;
|
||||
final posX = position.x;
|
||||
final posY = position.y;
|
||||
|
||||
g.color = 0xff000000;
|
||||
g.fillRect(posX, posY, rt.width, rt.height);
|
||||
g.color = 0xffffffff;
|
||||
|
||||
if (kha.Image.renderTargetsInvertedY())
|
||||
g.drawScaledImage(rt, posX, posY+rt.height, rt.width, -rt.height);
|
||||
else
|
||||
g.drawScaledImage(rt, posX, posY, rt.width, rt.height);
|
||||
}
|
||||
g.color = 0xff000000;
|
||||
g.fillRect(posX, posY, rt.width, rt.height);
|
||||
g.color = 0xffffffff;
|
||||
|
||||
if (kha.Image.renderTargetsInvertedY())
|
||||
g.drawScaledImage(rt, posX, posY+rt.height, rt.width, -rt.height);
|
||||
else
|
||||
g.drawScaledImage(rt, posX, posY, rt.width, rt.height);
|
||||
}
|
||||
}
|
||||
|
||||
129
leenkx/Sources/leenkx/logicnode/DrawGifNode.hx
Normal file
129
leenkx/Sources/leenkx/logicnode/DrawGifNode.hx
Normal file
@ -0,0 +1,129 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
import kha.Image;
|
||||
import kha.Color;
|
||||
import leenkx.renderpath.RenderToTexture;
|
||||
|
||||
import iron.format.gif.Reader;
|
||||
import iron.format.gif.Data;
|
||||
import iron.format.gif.Tools;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.BytesInput;
|
||||
|
||||
import leenkx.system.Event;
|
||||
|
||||
class DrawGifNode extends LogicNode {
|
||||
var data:Data = null;
|
||||
var frames:Int = 0;
|
||||
var img: Array<Image> = [];
|
||||
var lastImgName = "";
|
||||
var duration = 0.0;
|
||||
var index = 0;
|
||||
var i = 0;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
|
||||
Event.add('load', function() {
|
||||
var extractedBytes:Bytes = Tools.extractFullRGBA(data, i);
|
||||
img.push(kha.Image.fromBytes(extractedBytes, data.logicalScreenDescriptor.width, data.logicalScreenDescriptor.height, kha.graphics4.TextureFormat.RGBA32));
|
||||
});
|
||||
|
||||
tree.notifyOnRemove(onRemove);
|
||||
|
||||
}
|
||||
|
||||
function onRemove() {
|
||||
Event.remove('load');
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
if (from == 0){
|
||||
|
||||
if (data == null){
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
|
||||
RenderToTexture.ensure2DContext("DrawGifNode");
|
||||
|
||||
final colorVec: Vec4 = inputs[3].get();
|
||||
final anchorH: Int = inputs[4].get();
|
||||
final anchorV: Int = inputs[5].get();
|
||||
final x: Float = inputs[6].get();
|
||||
final y: Float = inputs[7].get();
|
||||
final width: Float = inputs[8].get();
|
||||
final height: Float = inputs[9].get();
|
||||
final angle: Float = inputs[10].get();
|
||||
|
||||
var sindex: Int = inputs[11].get();
|
||||
var eindex: Int = inputs[12].get();
|
||||
final fdur: Float = inputs[13].get();
|
||||
final loop: Bool = inputs[14].get();
|
||||
|
||||
final drawx = x - 0.5 * width * anchorH;
|
||||
final drawy = y - 0.5 * height * anchorV;
|
||||
|
||||
if(eindex == -1 || eindex > frames)
|
||||
eindex = frames;
|
||||
|
||||
if(sindex < 0 || sindex > frames)
|
||||
sindex = 0;
|
||||
|
||||
if (index < sindex || index > eindex)
|
||||
index = sindex;
|
||||
|
||||
duration += iron.system.Time.delta;
|
||||
if (duration >= fdur){
|
||||
if (index < eindex)
|
||||
index += 1;
|
||||
else
|
||||
if (loop) index = sindex;
|
||||
duration = 0;
|
||||
if (i < eindex){
|
||||
++i;
|
||||
Event.send('load');
|
||||
}
|
||||
}
|
||||
|
||||
if (img.length > (index - sindex)){
|
||||
RenderToTexture.g.rotate(angle, x, y);
|
||||
RenderToTexture.g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w);
|
||||
RenderToTexture.g.drawScaledImage(img[index-sindex], drawx, drawy, width, height);
|
||||
RenderToTexture.g.rotate(-angle, x, y);
|
||||
}
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
else{
|
||||
final imgName: String = inputs[2].get();
|
||||
if (imgName != lastImgName) {
|
||||
lastImgName = imgName;
|
||||
img = [];
|
||||
i = inputs[11].get();
|
||||
index = i;
|
||||
iron.data.Data.getBlob(imgName, (blob: kha.Blob) -> {
|
||||
var bytes: Bytes = blob.toBytes();
|
||||
var input: BytesInput = new BytesInput(bytes);
|
||||
data = new Reader(input).read();
|
||||
frames = Tools.framesCount(data);
|
||||
if (i > frames) return;
|
||||
var extractedBytes:Bytes = Tools.extractFullRGBA(data, i);
|
||||
img.push(kha.Image.fromBytes(extractedBytes, data.logicalScreenDescriptor.width, data.logicalScreenDescriptor.height, kha.graphics4.TextureFormat.RGBA32));
|
||||
++i;
|
||||
Event.send('load');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
if (from == 1)
|
||||
return frames;
|
||||
else
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,15 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
import iron.RenderPath;
|
||||
import kha.Image;
|
||||
import kha.Color;
|
||||
import leenkx.renderpath.RenderToTexture;
|
||||
|
||||
class DrawImageRenderNode extends LogicNode {
|
||||
var img: Image;
|
||||
var img2D: Image;
|
||||
var initialized: Bool = false;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -14,8 +17,21 @@ class DrawImageRenderNode extends LogicNode {
|
||||
|
||||
override function run(from: Int) {
|
||||
|
||||
if (from == 1)
|
||||
if (from == 1){
|
||||
if (inputs[16].get()){
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
img = kha.Image.createRenderTarget(iron.App.w(), iron.App.h(),
|
||||
kha.graphics4.TextureFormat.RGBA32,
|
||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
|
||||
if (inputs[15].get() || kha.Image.renderTargetsInvertedY())
|
||||
img2D = kha.Image.createRenderTarget(iron.App.w(), iron.App.h(),
|
||||
kha.graphics4.TextureFormat.RGBA32,
|
||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
|
||||
tree.notifyOnRender(render);
|
||||
}
|
||||
else {
|
||||
|
||||
RenderToTexture.ensure2DContext("DrawImageRenderNode");
|
||||
@ -38,12 +54,14 @@ class DrawImageRenderNode extends LogicNode {
|
||||
|
||||
RenderToTexture.g.rotate(angle, x, y);
|
||||
|
||||
if (img != null){
|
||||
RenderToTexture.g.color = 0xff000000;
|
||||
RenderToTexture.g.fillRect(drawx, drawy, width, height);
|
||||
RenderToTexture.g.color = RenderToTexture.g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w);
|
||||
RenderToTexture.g.color = 0xff000000;
|
||||
RenderToTexture.g.fillRect(drawx, drawy, width, height);
|
||||
RenderToTexture.g.color = RenderToTexture.g.color = Color.fromFloats(colorVec.x, colorVec.y, colorVec.z, colorVec.w);
|
||||
|
||||
if ((inputs[15].get() || kha.Image.renderTargetsInvertedY()) && img2D != null)
|
||||
RenderToTexture.g.drawScaledSubImage(img2D, sx, sy, swidth, sheight, drawx, drawy, width, height);
|
||||
else if(img != null)
|
||||
RenderToTexture.g.drawScaledSubImage(img, sx, sy, swidth, sheight, drawx, drawy, width, height);
|
||||
}
|
||||
|
||||
RenderToTexture.g.rotate(-angle, x, y);
|
||||
|
||||
@ -54,13 +72,11 @@ class DrawImageRenderNode extends LogicNode {
|
||||
}
|
||||
|
||||
function render(g: kha.graphics4.Graphics) {
|
||||
final rpPaused = RenderPath.active.paused;
|
||||
RenderPath.active.paused = false;
|
||||
|
||||
var camera = inputs[2].get();
|
||||
|
||||
img = kha.Image.createRenderTarget(iron.App.w(), iron.App.h(),
|
||||
kha.graphics4.TextureFormat.RGBA32,
|
||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
|
||||
|
||||
final sceneCam = iron.Scene.active.camera;
|
||||
final oldRT = camera.renderTarget;
|
||||
|
||||
@ -69,38 +85,30 @@ class DrawImageRenderNode extends LogicNode {
|
||||
|
||||
camera.renderFrame(g);
|
||||
|
||||
img = camera.renderTarget;
|
||||
|
||||
if (inputs[15].get() || kha.Image.renderTargetsInvertedY()) {
|
||||
|
||||
img = kha.Image.createRenderTarget(iron.App.w(), iron.App.h(),
|
||||
kha.graphics4.TextureFormat.RGBA32,
|
||||
kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
|
||||
img2D.g2.begin(true, Color.Transparent);
|
||||
img2D.g2.color = Color.White;
|
||||
|
||||
img.g2.begin(true, Color.Transparent);
|
||||
if (kha.Image.renderTargetsInvertedY())
|
||||
img2D.g2.drawScaledImage(camera.renderTarget, 0, iron.App.h(), iron.App.w(), -iron.App.h());
|
||||
else
|
||||
img2D.g2.drawImage(camera.renderTarget, 0, 0);
|
||||
|
||||
img.g2.color = Color.White;
|
||||
|
||||
if (kha.Image.renderTargetsInvertedY()) {
|
||||
img.g2.drawScaledImage(camera.renderTarget, 0, iron.App.h(), iron.App.w(), -iron.App.h());
|
||||
} else {
|
||||
img.g2.drawImage(camera.renderTarget, 0, 0);
|
||||
}
|
||||
|
||||
if (inputs[15].get()) {
|
||||
for (f in @:privateAccess iron.App.traitRenders2D) {
|
||||
f(img.g2);
|
||||
}
|
||||
}
|
||||
|
||||
img.g2.end();
|
||||
if (inputs[15].get())
|
||||
for (f in @:privateAccess iron.App.traitRenders2D)
|
||||
f(img2D.g2);
|
||||
|
||||
img2D.g2.end();
|
||||
}
|
||||
|
||||
camera.renderTarget = oldRT;
|
||||
iron.Scene.active.camera = sceneCam;
|
||||
|
||||
tree.removeRender(render);
|
||||
RenderPath.active.paused = rpPaused;
|
||||
|
||||
if (!inputs[16].get())
|
||||
tree.removeRender(render);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -16,8 +16,8 @@ class DrawRoundedRectNode extends LogicNode {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
#if lnx_ui
|
||||
override function run(from: Int) {
|
||||
#if lnx_ui
|
||||
RenderToTexture.ensure2DContext("DrawPolygonNode");
|
||||
|
||||
final anchorH: Int = inputs[4].get();
|
||||
@ -61,8 +61,6 @@ class DrawRoundedRectNode extends LogicNode {
|
||||
} else {
|
||||
RenderToTexture.g.drawPolygon(0, 0, vertices, inputs[3].get());
|
||||
}
|
||||
#end
|
||||
|
||||
RenderToTexture.g.rotate(-angle, x, y);
|
||||
runOutput(0);
|
||||
}
|
||||
@ -115,4 +113,5 @@ class DrawRoundedRectNode extends LogicNode {
|
||||
|
||||
return vertices;
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
@ -3,9 +3,13 @@ package leenkx.logicnode;
|
||||
import kha.Font;
|
||||
import kha.Color;
|
||||
import leenkx.renderpath.RenderToTexture;
|
||||
import kha.graphics2.VerTextAlignment;
|
||||
import kha.graphics2.HorTextAlignment;
|
||||
|
||||
#if lnx_ui
|
||||
import leenkx.ui.Canvas;
|
||||
|
||||
using zui.GraphicsExtension;
|
||||
#end
|
||||
|
||||
class DrawStringNode extends LogicNode {
|
||||
@ -13,13 +17,20 @@ class DrawStringNode extends LogicNode {
|
||||
var lastFontName = "";
|
||||
var string:String;
|
||||
|
||||
public var property1: String;
|
||||
public var property2: String;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
#if lnx_ui
|
||||
override function run(from: Int) {
|
||||
RenderToTexture.ensure2DContext("DrawStringNode");
|
||||
|
||||
var horA = TextLeft;
|
||||
var verA = TextTop;
|
||||
|
||||
string = Std.string(inputs[1].get());
|
||||
var angle: Float = inputs[7].get();
|
||||
|
||||
@ -45,6 +56,18 @@ class DrawStringNode extends LogicNode {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(property1){
|
||||
case 'TextLeft': horA = TextLeft;
|
||||
case 'TextCenter': horA = TextCenter;
|
||||
case 'TextRight': horA = TextRight;
|
||||
}
|
||||
|
||||
switch(property2){
|
||||
case 'TextTop': verA = TextTop;
|
||||
case 'TextMiddle': verA = TextMiddle;
|
||||
case 'TextBottom': verA = TextBottom;
|
||||
}
|
||||
|
||||
RenderToTexture.g.rotate(angle, inputs[5].get(), inputs[6].get());
|
||||
|
||||
final colorVec = inputs[4].get();
|
||||
@ -53,7 +76,7 @@ class DrawStringNode extends LogicNode {
|
||||
RenderToTexture.g.fontSize = inputs[3].get();
|
||||
RenderToTexture.g.font = font;
|
||||
|
||||
RenderToTexture.g.drawString(string, inputs[5].get(), inputs[6].get());
|
||||
RenderToTexture.g.drawAlignedString(string, inputs[5].get(), inputs[6].get(), horA, verA);
|
||||
|
||||
RenderToTexture.g.rotate(-angle, inputs[5].get(), inputs[6].get());
|
||||
|
||||
@ -65,4 +88,5 @@ class DrawStringNode extends LogicNode {
|
||||
return from == 1 ? RenderToTexture.g.font.width(RenderToTexture.g.fontSize, string) : RenderToTexture.g.font.height(RenderToTexture.g.fontSize);
|
||||
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
47
leenkx/Sources/leenkx/logicnode/FollowCurveNode.hx
Normal file
47
leenkx/Sources/leenkx/logicnode/FollowCurveNode.hx
Normal file
@ -0,0 +1,47 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.CurveObject;
|
||||
import iron.system.Time;
|
||||
|
||||
class FollowCurveNode extends LogicNode {
|
||||
|
||||
var progress: Float = -1;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
var cycle: Bool = false;
|
||||
var object: Object = inputs[1].get();
|
||||
var curve: CurveObject = inputs[2].get();
|
||||
var splineIdx: Int = inputs[3].get();
|
||||
|
||||
if (progress == -1) progress = inputs[8].get();
|
||||
|
||||
var len = curve.getLength(splineIdx);
|
||||
var speed = inputs[5].get();
|
||||
|
||||
var currentDist = progress * len;
|
||||
currentDist += (speed * Time.delta * (inputs[6].get() ? 1.0 : -1.0));
|
||||
|
||||
if (inputs[7].get()){
|
||||
if (currentDist > len){ currentDist -= len; cycle = true; }
|
||||
else if (currentDist < 0){ currentDist += len; cycle = true; }
|
||||
}
|
||||
|
||||
progress = (len > 0) ? currentDist / len : 0.0;
|
||||
|
||||
if (cycle)
|
||||
runOutput(1);
|
||||
else{
|
||||
curve.follow(object, progress, splineIdx, inputs[4].get());
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return progress;
|
||||
}
|
||||
}
|
||||
57
leenkx/Sources/leenkx/logicnode/FormatNumberNode.hx
Normal file
57
leenkx/Sources/leenkx/logicnode/FormatNumberNode.hx
Normal file
@ -0,0 +1,57 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class FormatNumberNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var number: Float = inputs[0].get();
|
||||
var thousandsSeparator: String = inputs[1].get();
|
||||
var decimalSeparator: String = inputs[2].get();
|
||||
var includeSymbol: Bool = inputs[3].get();
|
||||
|
||||
var s = Std.string(number);
|
||||
var isNegative = s.charAt(0) == "-";
|
||||
if (isNegative) s = s.substring(1);
|
||||
|
||||
var parts = s.split(".");
|
||||
var integerPart = parts[0];
|
||||
var decimalPart = (parts.length > 1) ? parts[1] : "";
|
||||
|
||||
var len = integerPart.length;
|
||||
var formattedInteger = "";
|
||||
|
||||
if (len <= 3) {
|
||||
formattedInteger = integerPart;
|
||||
} else {
|
||||
var firstGroupLen = len % 3;
|
||||
if (firstGroupLen == 0) firstGroupLen = 3;
|
||||
|
||||
formattedInteger += integerPart.substring(0, firstGroupLen);
|
||||
|
||||
var i = firstGroupLen;
|
||||
while (i < len) {
|
||||
formattedInteger += thousandsSeparator + integerPart.substring(i, i + 3);
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
var finalNumber = formattedInteger;
|
||||
if (decimalPart != "") {
|
||||
finalNumber += decimalSeparator + decimalPart;
|
||||
}
|
||||
|
||||
var result = "";
|
||||
var sign = isNegative ? "-" : "";
|
||||
|
||||
if (includeSymbol) {
|
||||
result = sign + "$" + finalNumber;
|
||||
} else {
|
||||
result = sign + finalNumber;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
32
leenkx/Sources/leenkx/logicnode/FormatTimeNode.hx
Normal file
32
leenkx/Sources/leenkx/logicnode/FormatTimeNode.hx
Normal file
@ -0,0 +1,32 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class FormatTimeNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var time: Float = inputs[0].get();
|
||||
var format: String = inputs[1].get();
|
||||
|
||||
var totalSeconds = Math.floor(time);
|
||||
var milliseconds = Math.floor((time - totalSeconds) * 1000);
|
||||
var centiseconds = Math.floor(milliseconds / 10);
|
||||
|
||||
var h = Math.floor(totalSeconds / 3600);
|
||||
var m = Math.floor((totalSeconds % 3600) / 60);
|
||||
var s = totalSeconds % 60;
|
||||
|
||||
var result = format;
|
||||
result = StringTools.replace(result, "HH", (h < 10 ? "0" : "") + h);
|
||||
result = StringTools.replace(result, "MM", (m < 10 ? "0" : "") + m);
|
||||
result = StringTools.replace(result, "SS", (s < 10 ? "0" : "") + s);
|
||||
result = StringTools.replace(result, "MS", (centiseconds < 10 ? "0" : "") + centiseconds);
|
||||
result = StringTools.replace(result, "H", "" + h);
|
||||
result = StringTools.replace(result, "M", "" + m);
|
||||
result = StringTools.replace(result, "S", "" + s);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -2,24 +2,32 @@ package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavAgent;
|
||||
#end
|
||||
|
||||
class GetAgentDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Float {
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
|
||||
assert(Error, object != null, "The object to naviagte should not be null");
|
||||
|
||||
#if lnx_navigation
|
||||
var agent: leenkx.trait.NavAgent = object.getTrait(leenkx.trait.NavAgent);
|
||||
assert(Error, agent != null, "The object does not have NavAgent Trait");
|
||||
if(from == 0) return agent.speed;
|
||||
else return agent.turnDuration;
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
#if lnx_navigation
|
||||
var agent: NavAgent = object.getTrait(NavAgent);
|
||||
if (agent == null) return null;
|
||||
return switch(from){
|
||||
case 0: agent.navMeshId;
|
||||
case 1: agent.speed;
|
||||
case 2: agent.turnDuration;
|
||||
case 3: @:privateAccess agent.path;
|
||||
default: null;
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
27
leenkx/Sources/leenkx/logicnode/GetAreaLightDataNode.hx
Normal file
27
leenkx/Sources/leenkx/logicnode/GetAreaLightDataNode.hx
Normal file
@ -0,0 +1,27 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.LightObject;
|
||||
|
||||
class GetAreaLightDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var light: LightObject = inputs[0].get();
|
||||
|
||||
if (light == null) return null;
|
||||
|
||||
#if lnx_ltc
|
||||
if (light.data.raw.type == "area")
|
||||
if (from == 0)
|
||||
return light.data.raw.size;
|
||||
else
|
||||
return light.data.raw.size_y;
|
||||
#end
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
12
leenkx/Sources/leenkx/logicnode/GetAssetsNode.hx
Normal file
12
leenkx/Sources/leenkx/logicnode/GetAssetsNode.hx
Normal file
@ -0,0 +1,12 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class GetAssetsNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return leenkx.system.Starter.assets;
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,18 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.MeshObject;
|
||||
import iron.object.CameraObject;
|
||||
import iron.object.LightObject;
|
||||
import iron.object.SpeakerObject;
|
||||
import iron.object.DecalObject;
|
||||
import iron.object.ProbeObject;
|
||||
import iron.object.CurveObject;
|
||||
|
||||
class GetChildNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
public var property1: String;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -12,22 +20,31 @@ class GetChildNode extends LogicNode {
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var childName: String = inputs[1].get();
|
||||
if (object == null) return null;
|
||||
|
||||
if (object == null || childName == null) return null;
|
||||
if (property0 != "By Type") {
|
||||
var childName: String = inputs[1].get();
|
||||
if (childName == null) return null;
|
||||
|
||||
switch (property0) {
|
||||
case "By Name":
|
||||
return object.getChild(childName);
|
||||
case "Contains":
|
||||
return contains(object, childName);
|
||||
case "Starts With":
|
||||
return startsWith(object, childName);
|
||||
case "Ends With":
|
||||
return endsWith(object, childName);
|
||||
return switch (property0) {
|
||||
case "By Name": object.getChild(childName);
|
||||
case "Contains": contains(object, childName);
|
||||
case "Starts With": startsWith(object, childName);
|
||||
case "Ends With": endsWith(object, childName);
|
||||
default: null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return switch (property1) {
|
||||
case "MeshObject": object.getChildOfType(MeshObject);
|
||||
case "CameraObject": object.getChildOfType(CameraObject);
|
||||
case "LightObject": object.getChildOfType(LightObject);
|
||||
case "SpeakerObject": object.getChildOfType(SpeakerObject);
|
||||
case "DecalObject": object.getChildOfType(DecalObject);
|
||||
case "ProbeObject": object.getChildOfType(ProbeObject);
|
||||
case "CurveObject": object.getChildOfType(CurveObject);
|
||||
default: null;
|
||||
}
|
||||
}
|
||||
|
||||
function contains(o: Object, name: String): Object {
|
||||
|
||||
@ -13,6 +13,6 @@ class GetChildrenNode extends LogicNode {
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
return object.children;
|
||||
return from == 0 ? object.children : object.children.length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,9 @@ class GetContactsNode extends LogicNode {
|
||||
|
||||
#if lnx_physics
|
||||
var physics = leenkx.trait.physics.PhysicsWorld.active;
|
||||
var rbs = physics.getContacts(object.getTrait(RigidBody));
|
||||
var rb = object.getTrait(RigidBody);
|
||||
if (rb == null) return null;
|
||||
var rbs = physics.getContacts(rb);
|
||||
var obs = [];
|
||||
|
||||
if (rbs != null) for (rb in rbs) if (rb != null) obs.push(rb.object);
|
||||
|
||||
39
leenkx/Sources/leenkx/logicnode/GetCrowdDataNode.hx
Normal file
39
leenkx/Sources/leenkx/logicnode/GetCrowdDataNode.hx
Normal file
@ -0,0 +1,39 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavCrowd;
|
||||
#end
|
||||
|
||||
class GetCrowdDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
|
||||
#if lnx_navigation
|
||||
var crowdAgent: NavCrowd = object.getTrait(NavCrowd);
|
||||
if (crowdAgent == null) return null;
|
||||
return switch(from){
|
||||
case 0: crowdAgent.navMeshId;
|
||||
case 1: crowdAgent.crowdAgentVelocity();
|
||||
case 2: crowdAgent.crowdAgentMaxSpeed();
|
||||
case 3: crowdAgent.crowdAgentMaxAcceleration();
|
||||
case 4: crowdAgent.turnSpeed;
|
||||
case 5: crowdAgent.crowdAgentPosition();
|
||||
case 6: crowdAgent.crowdAgentNextPath();
|
||||
case 7: @:privateAccess crowdAgent.agentID;
|
||||
case 8: crowdAgent.crowdAgentPath();
|
||||
default: null;
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
|
||||
#end
|
||||
}
|
||||
}
|
||||
33
leenkx/Sources/leenkx/logicnode/GetCurveDataNode.hx
Normal file
33
leenkx/Sources/leenkx/logicnode/GetCurveDataNode.hx
Normal file
@ -0,0 +1,33 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.CurveObject;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class GetCurveDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var curve: CurveObject = inputs[0].get();
|
||||
if (curve == null) return null;
|
||||
return
|
||||
switch (from) {
|
||||
case 0:
|
||||
curve.splinesLength;
|
||||
case 1:
|
||||
curve.equidistantSamples;
|
||||
case 2:
|
||||
curve.visible;
|
||||
case 3:
|
||||
curve.data.strength;
|
||||
case 4:
|
||||
new Vec4(curve.data.color[0], curve.data.color[1], curve.data.color[2], curve.data.color[3]);
|
||||
case 5:
|
||||
curve.curveMesh;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
leenkx/Sources/leenkx/logicnode/GetCurveSplineNode.hx
Normal file
36
leenkx/Sources/leenkx/logicnode/GetCurveSplineNode.hx
Normal file
@ -0,0 +1,36 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.CurveObject;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class GetCurveSplineNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var curve: CurveObject = inputs[0].get();
|
||||
var index: Int = inputs[1].get();
|
||||
|
||||
if (index > curve.splinesLength) return null;
|
||||
|
||||
switch(from){
|
||||
case 0:
|
||||
var points: Array<Vec4> = [];
|
||||
var worldMat = curve.transform.world;
|
||||
for (point in curve.data.splines[index].points){
|
||||
var p = new Vec4(point.co[0], point.co[1], point.co[2]);
|
||||
p.applymat(worldMat);
|
||||
points.push(p);
|
||||
}
|
||||
return points;
|
||||
case 1:
|
||||
return curve.data.splines[index].closed;
|
||||
case 2:
|
||||
return curve.data.splines[index].resolution;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,10 @@ class GetFirstContactNode extends LogicNode {
|
||||
|
||||
#if lnx_physics
|
||||
var physics = leenkx.trait.physics.PhysicsWorld.active;
|
||||
var rbs = physics.getContacts(object.getTrait(RigidBody));
|
||||
|
||||
var rb = object.getTrait(RigidBody);
|
||||
if (rb == null) return null;
|
||||
var rbs = physics.getContacts(rb);
|
||||
|
||||
if (rbs != null && rbs.length > 0) return rbs[0].object;
|
||||
#end
|
||||
|
||||
@ -8,6 +8,6 @@ class GetGroupNode extends LogicNode {
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var groupName: String = inputs[0].get();
|
||||
return iron.Scene.active.getGroup(groupName);
|
||||
return from == 0 ? iron.Scene.active.getGroup(groupName) : iron.Scene.active.getGroup(groupName).length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,10 +38,10 @@ class GetImageColorNode extends LogicNode {
|
||||
renderTarget.g2.color = Color.White;
|
||||
|
||||
if (property0 == 'Render' || property0 == 'Render&Render2D'){
|
||||
if (leenkx.renderpath.RenderPathCreator.finalTarget != null){
|
||||
var img: Image = iron.RenderPath.active.renderTargets.get("buf").image;
|
||||
renderTarget.g2.drawScaledImage(img, 0, 0, iron.App.w(), iron.App.h());
|
||||
}
|
||||
if (leenkx.renderpath.RenderPathCreator.finalTarget != null){
|
||||
var img: Image = iron.RenderPath.active.renderTargets.get("buf").image;
|
||||
renderTarget.g2.drawScaledImage(img, 0, 0, iron.App.w(), iron.App.h());
|
||||
}
|
||||
}
|
||||
|
||||
if (Image.renderTargetsInvertedY()){
|
||||
@ -75,7 +75,7 @@ class GetImageColorNode extends LogicNode {
|
||||
var pixels = renderTarget.getPixels();
|
||||
|
||||
var k = j * renderTarget.width + i;
|
||||
|
||||
|
||||
#if kha_krom
|
||||
var l = k;
|
||||
#elseif kha_html5
|
||||
@ -84,11 +84,11 @@ class GetImageColorNode extends LogicNode {
|
||||
|
||||
var r = pixels.get(l * 4 + 0)/255;
|
||||
var g = pixels.get(l * 4 + 1)/255;
|
||||
var b = pixels.get(l * 4 + 2)/255;
|
||||
var b = pixels.get(l * 4 + 2)/255;
|
||||
var a = pixels.get(l * 4 + 3)/255;
|
||||
|
||||
var v = new Vec4(r, g, b, a);
|
||||
|
||||
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
52
leenkx/Sources/leenkx/logicnode/GetKeyboardNode.hx
Normal file
52
leenkx/Sources/leenkx/logicnode/GetKeyboardNode.hx
Normal file
@ -0,0 +1,52 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.system.Input;
|
||||
import iron.system.Time;
|
||||
|
||||
class GetKeyboardNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
var activeKey: String = "";
|
||||
var lastTime: Float = -1.0;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
tree.notifyOnUpdate(update);
|
||||
}
|
||||
|
||||
function update() {
|
||||
var keyboard = Input.getKeyboard();
|
||||
var found = false;
|
||||
|
||||
for (k in iron.system.Keyboard.keys) {
|
||||
var b = false;
|
||||
switch (property0) {
|
||||
case "started":
|
||||
b = keyboard.started(k);
|
||||
case "down":
|
||||
b = keyboard.down(k);
|
||||
case "released":
|
||||
b = keyboard.released(k);
|
||||
}
|
||||
|
||||
if (b) {
|
||||
if (property0 == "started" || property0 == "released") {
|
||||
var currentTime = Time.time();
|
||||
if (currentTime == lastTime && Time.delta != 0) continue;
|
||||
lastTime = currentTime;
|
||||
}
|
||||
activeKey = k;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return activeKey;
|
||||
}
|
||||
}
|
||||
37
leenkx/Sources/leenkx/logicnode/GetLightDataNode.hx
Normal file
37
leenkx/Sources/leenkx/logicnode/GetLightDataNode.hx
Normal file
@ -0,0 +1,37 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.LightObject;
|
||||
|
||||
class GetLightDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var light: LightObject = inputs[0].get();
|
||||
|
||||
if (light.data == null) return null;
|
||||
|
||||
return switch (from) {
|
||||
case 0:
|
||||
return iron.data.LightData.typeToInt(light.data.raw.type);
|
||||
#if lnx_single_point
|
||||
case 1:
|
||||
return light.data.raw.type == "sun" ? light.data.raw.strength / 0.325 : light.data.raw.strength / 0.01;
|
||||
case 2:
|
||||
return new iron.math.Vec4(light.data.raw.color[0], light.data.raw.color[1], light.data.raw.color[2]);
|
||||
#else
|
||||
case 1:
|
||||
return light.data.raw.type == "sun" ? light.data.raw.strength / 0.325 : light.strength / 0.01;
|
||||
case 2:
|
||||
return light.data.raw.type == "sun" ? new iron.math.Vec4(light.data.raw.color[0], light.data.raw.color[1], light.data.raw.color[2]) : light.color;
|
||||
#end
|
||||
case 3:
|
||||
light.data.raw.cast_shadow;
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
leenkx/Sources/leenkx/logicnode/GetMaterialImageParamNode.hx
Normal file
31
leenkx/Sources/leenkx/logicnode/GetMaterialImageParamNode.hx
Normal file
@ -0,0 +1,31 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.Scene;
|
||||
import iron.data.MaterialData;
|
||||
import iron.object.Object;
|
||||
import leenkx.trait.internal.UniformsManager;
|
||||
|
||||
class GetMaterialImageParamNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var perObject: Bool = inputs[1].get();
|
||||
var mat: MaterialData = inputs[2].get();
|
||||
var link: String = inputs[3].get();
|
||||
|
||||
if (mat == null || link == null) return null;
|
||||
|
||||
if (!perObject) {
|
||||
object = Scene.active.root;
|
||||
}
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
var val = @:privateAccess UniformsManager.getObjectTextureLink(object, mat, link);
|
||||
return val != null ? val : null;
|
||||
}
|
||||
}
|
||||
31
leenkx/Sources/leenkx/logicnode/GetMaterialRgbParamNode.hx
Normal file
31
leenkx/Sources/leenkx/logicnode/GetMaterialRgbParamNode.hx
Normal file
@ -0,0 +1,31 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.Scene;
|
||||
import iron.data.MaterialData;
|
||||
import iron.object.Object;
|
||||
import leenkx.trait.internal.UniformsManager;
|
||||
|
||||
class GetMaterialRgbParamNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var perObject: Bool = inputs[1].get();
|
||||
var mat: MaterialData = inputs[2].get();
|
||||
var link: String = inputs[3].get();
|
||||
|
||||
if (mat == null || link == null) return null;
|
||||
|
||||
if (!perObject) {
|
||||
object = Scene.active.root;
|
||||
}
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
var val = @:privateAccess UniformsManager.getObjectVec3Link(object, mat, link);
|
||||
return val != null ? val : null;
|
||||
}
|
||||
}
|
||||
31
leenkx/Sources/leenkx/logicnode/GetMaterialValueParamNode.hx
Normal file
31
leenkx/Sources/leenkx/logicnode/GetMaterialValueParamNode.hx
Normal file
@ -0,0 +1,31 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.Scene;
|
||||
import iron.data.MaterialData;
|
||||
import iron.object.Object;
|
||||
import leenkx.trait.internal.UniformsManager;
|
||||
|
||||
class GetMaterialValueParamNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var perObject: Bool = inputs[1].get();
|
||||
var mat: MaterialData = inputs[2].get();
|
||||
var link: String = inputs[3].get();
|
||||
|
||||
if (mat == null || link == null) return 0.0;
|
||||
|
||||
if (!perObject) {
|
||||
object = Scene.active.root;
|
||||
}
|
||||
|
||||
if (object == null) return 0.0;
|
||||
|
||||
var val = @:privateAccess UniformsManager.getObjectFloatLink(object, mat, link);
|
||||
return val != null ? val : 0.0;
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,5 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.data.SceneFormat;
|
||||
import iron.object.Object;
|
||||
|
||||
class GetObjectByUidNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
|
||||
27
leenkx/Sources/leenkx/logicnode/GetObjectCameraDataNode.hx
Normal file
27
leenkx/Sources/leenkx/logicnode/GetObjectCameraDataNode.hx
Normal file
@ -0,0 +1,27 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.MeshObject;
|
||||
import iron.Scene;
|
||||
|
||||
class GetObjectCameraDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var mo: MeshObject = cast inputs[0].get();
|
||||
|
||||
if (mo == null) return null;
|
||||
|
||||
if ((from == 0 && mo.cameraDistance == null) || (from == 1 && mo.screenSize == 0)) {
|
||||
var cam = Scene.active.camera;
|
||||
mo.computeCameraDistance(cam.transform.worldx(), cam.transform.worldy(), cam.transform.worldz());
|
||||
if (from == 1) {
|
||||
mo.computeScreenSize(cam);
|
||||
}
|
||||
}
|
||||
|
||||
return from == 0 ? mo.cameraDistance : mo.screenSize;
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,8 @@ import iron.math.Vec4;
|
||||
|
||||
class GetObjectGeomNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
@ -14,13 +16,30 @@ class GetObjectGeomNode extends LogicNode {
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
if (from == 5)
|
||||
return object.vertex_groups;
|
||||
var worldMat = object.transform.world;
|
||||
|
||||
if (from == 5) {
|
||||
if (property0 == "Global") {
|
||||
var vertexGroups = new Map<String, Array<Vec4>>();
|
||||
for (key in object.vertexGroups.keys()) {
|
||||
var vp = [];
|
||||
for (p in object.vertexGroups.get(key)) {
|
||||
var p = new Vec4(p.x, p.y, p.z, p.w);
|
||||
p.applymat(worldMat);
|
||||
vp.push(p);
|
||||
}
|
||||
vertexGroups.set(key, vp);
|
||||
}
|
||||
return vertexGroups;
|
||||
}
|
||||
else
|
||||
return object.vertexGroups;
|
||||
}
|
||||
|
||||
if (from == 6){
|
||||
var keys = [];
|
||||
if (object.vertex_groups != null)
|
||||
for (key in object.vertex_groups.keys())
|
||||
if (object.vertexGroups != null)
|
||||
for (key in object.vertexGroups.keys())
|
||||
keys.push(key);
|
||||
|
||||
return keys;
|
||||
@ -36,8 +55,21 @@ class GetObjectGeomNode extends LogicNode {
|
||||
var normals = object.data.geom.normals.values;
|
||||
|
||||
for (i in 0...Std.int(positions.length/4)){
|
||||
pos.push(new Vec4(positions[i*4]*scl/32767, positions[i*4+1]*scl/32767, positions[i*4+2]*scl/32767, 1));
|
||||
nor.push(new Vec4(normals[i*2]/32767, normals[i*2+1]/32767, positions[i*4+3]/32767, 1));
|
||||
var p = new Vec4(positions[i*4]*scl/32767, positions[i*4+1]*scl/32767, positions[i*4+2]*scl/32767, 1);
|
||||
var n = new Vec4(normals[i*2]/32767, normals[i*2+1]/32767, positions[i*4+3]/32767, 1);
|
||||
|
||||
if (property0 == "Global") {
|
||||
p.applymat(worldMat);
|
||||
var m = worldMat.clone();
|
||||
m.getInverse(m);
|
||||
m.transpose3x3();
|
||||
m._30 = 0; m._31 = 0; m._32 = 0;
|
||||
n.applymat(m);
|
||||
n.normalize();
|
||||
}
|
||||
|
||||
pos.push(p);
|
||||
nor.push(n);
|
||||
}
|
||||
|
||||
if (from == 0)
|
||||
|
||||
43
leenkx/Sources/leenkx/logicnode/GetObjectInstancedNode.hx
Normal file
43
leenkx/Sources/leenkx/logicnode/GetObjectInstancedNode.hx
Normal file
@ -0,0 +1,43 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.object.MeshObject;
|
||||
import kha.arrays.Float32Array;
|
||||
|
||||
class GetObjectInstancedNode 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;
|
||||
|
||||
var geom = cast(object, MeshObject).data.geom;
|
||||
|
||||
return
|
||||
switch(from){
|
||||
case 0: geom.instanced;
|
||||
case 1: @:privateAccess geom.data.raw.instanced_type;
|
||||
case 2: geom.instanceCount;
|
||||
case 3: geom.instanceStride;
|
||||
case 4: toArray(@:privateAccess geom.data.raw.instanced_data);
|
||||
default: null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function toArray(elements: Float32Array): Array<Float>{
|
||||
if (elements == null) return null;
|
||||
var len = elements.length;
|
||||
var nid: Array<Float> = [];
|
||||
|
||||
for (i in 0...len) {
|
||||
nid[i] = elements[i];
|
||||
}
|
||||
|
||||
return nid;
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,7 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.data.SceneFormat;
|
||||
import iron.object.Object;
|
||||
|
||||
class GetObjectNode extends LogicNode {
|
||||
|
||||
/** Scene from which to take the object **/
|
||||
public var property0: Null<String>;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
28
leenkx/Sources/leenkx/logicnode/GetObjectShapeKeyNode.hx
Normal file
28
leenkx/Sources/leenkx/logicnode/GetObjectShapeKeyNode.hx
Normal file
@ -0,0 +1,28 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.MeshObject;
|
||||
|
||||
class GetObjectShapeKeyNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if lnx_morph_target
|
||||
var object: Dynamic = inputs[0].get();
|
||||
var shapeKey: String = inputs[1].get();
|
||||
|
||||
assert(Error, object != null, "Object should not be null");
|
||||
var morph = cast(object, MeshObject).morphTarget;
|
||||
|
||||
assert(Error, morph != null, "Object does not have shape keys");
|
||||
|
||||
if (morph.morphMap.exists(shapeKey))
|
||||
return morph.morphWeights.get(morph.morphMap.get(shapeKey));
|
||||
#end
|
||||
return 0.0;
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,8 @@ class GetObjectTraitsNode extends LogicNode {
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
if (object == null) return null;
|
||||
return object.traits;
|
||||
return
|
||||
from == 0 ? object.name != null ? object.traits : inputs[0].get().root.children[0].traits :
|
||||
object.name != null ? object.traits.length : inputs[0].get().root.children[0].traits.length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +62,8 @@ class GetParticleDataNode extends LogicNode {
|
||||
@:privateAccess psys.lapTime;
|
||||
case 18:
|
||||
@:privateAccess psys.count;
|
||||
case 19:
|
||||
cast(mo.particleChildren[slot], Object);
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_audio
|
||||
import iron.object.SpeakerObject;
|
||||
import kha.audio1.AudioChannel;
|
||||
#end
|
||||
|
||||
class GetPositionSpeakerNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if lnx_audio
|
||||
var object: SpeakerObject = cast(inputs[0].get(), SpeakerObject);
|
||||
if (object == null || object.sound == null) return 0.0;
|
||||
|
||||
if (object.channels.length == 0) return 0.0;
|
||||
|
||||
var channel = object.channels[0];
|
||||
|
||||
var position = 0.0;
|
||||
if (channel != null) {
|
||||
position = @:privateAccess channel.get_position();
|
||||
}
|
||||
|
||||
return position;
|
||||
#else
|
||||
return 0.0;
|
||||
#end
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
import leenkx.trait.physics.RigidBody;
|
||||
|
||||
class GetRigidBodyDataNode extends LogicNode {
|
||||
@ -16,33 +17,30 @@ class GetRigidBodyDataNode extends LogicNode {
|
||||
|
||||
#if lnx_physics
|
||||
var rb = object.getTrait(RigidBody);
|
||||
if (rb == null) return null;
|
||||
|
||||
return switch (from) {
|
||||
case 0:
|
||||
rb == null ? return false : return true;
|
||||
case 1:
|
||||
rb.group;
|
||||
case 2:
|
||||
rb.mask;
|
||||
case 3:
|
||||
rb.animated;
|
||||
case 4:
|
||||
rb.staticObj;
|
||||
case 5:
|
||||
rb.angularDamping;
|
||||
case 6:
|
||||
rb.linearDamping;
|
||||
case 7:
|
||||
rb.friction;
|
||||
case 8:
|
||||
rb.mass;
|
||||
//case 9: ; // collision shape
|
||||
//case 10: ; // activation state
|
||||
//case 11: ; // is gravity enabled
|
||||
//case 12: ; // angular factor
|
||||
//case 13: ; // linear factor
|
||||
default:
|
||||
null;
|
||||
case 0: true;
|
||||
case 1: rb.group;
|
||||
case 2: rb.mask;
|
||||
case 3: rb.animated;
|
||||
case 4: rb.staticObj;
|
||||
case 5: rb.linearDamping;
|
||||
case 6: rb.angularDamping;
|
||||
case 7: rb.friction;
|
||||
case 8: rb.angularFriction;
|
||||
case 9: rb.mass;
|
||||
case 10: (rb.body.getCollisionFlags() & 4) != 0;
|
||||
case 11: rb.restitution;
|
||||
case 12: rb.getGravity().length() > 0.0001;
|
||||
case 13: rb.getGravity();
|
||||
case 14:
|
||||
var lf = @:privateAccess rb.linearFactors;
|
||||
return new Vec4(lf[0], lf[1], lf[2]);
|
||||
case 15:
|
||||
var af = @:privateAccess rb.angularFactors;
|
||||
return new Vec4(af[0], af[1], af[2]);
|
||||
default: null;
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
47
leenkx/Sources/leenkx/logicnode/GetSoftBodyDataNode.hx
Normal file
47
leenkx/Sources/leenkx/logicnode/GetSoftBodyDataNode.hx
Normal file
@ -0,0 +1,47 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
#if lnx_physics_soft
|
||||
import leenkx.trait.physics.bullet.SoftBody;
|
||||
#end
|
||||
|
||||
class GetSoftBodyDataNode extends LogicNode {
|
||||
|
||||
var friction: Float;
|
||||
var damping: Float;
|
||||
var pressure: Float;
|
||||
var linearStiffness: Float;
|
||||
var angularStiffness: Float;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var obj: Object = inputs[0].get();
|
||||
if (obj == null) return null;
|
||||
|
||||
#if lnx_physics_soft
|
||||
var sb = obj.getTrait(SoftBody);
|
||||
if (sb == null) return null;
|
||||
|
||||
return switch (from) {
|
||||
case 0: true; // Has SB
|
||||
case 1: sb.mass;
|
||||
case 2: sb.bend;
|
||||
case 3: sb.shape;
|
||||
case 4: sb.margin;
|
||||
case 5: new Vec4(sb.vertOffsetX, sb.vertOffsetY, sb.vertOffsetZ);
|
||||
case 6: sb.friction;
|
||||
case 7: sb.damping;
|
||||
case 8: sb.pressure;
|
||||
case 9: sb.linearStiffness;
|
||||
case 10: sb.angularStiffness;
|
||||
default: null;
|
||||
}
|
||||
#end
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
48
leenkx/Sources/leenkx/logicnode/GetSpeakerDataNode.hx
Normal file
48
leenkx/Sources/leenkx/logicnode/GetSpeakerDataNode.hx
Normal file
@ -0,0 +1,48 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_audio
|
||||
import iron.object.SpeakerObject;
|
||||
import kha.audio1.AudioChannel;
|
||||
#end
|
||||
|
||||
class GetSpeakerDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if lnx_audio
|
||||
var object: SpeakerObject = cast(inputs[0].get(), SpeakerObject);
|
||||
|
||||
switch(from){
|
||||
case 0:
|
||||
return object.volume;
|
||||
case 1:
|
||||
return object.data.pitch;
|
||||
case 2:
|
||||
return object.channels.length;
|
||||
case 3:
|
||||
var len: Array<Float> = null;
|
||||
if (object.channels.length > 0){
|
||||
len = [];
|
||||
for (channel in object.channels)
|
||||
len.push(channel.length);
|
||||
}
|
||||
return len;
|
||||
case 4:
|
||||
var pos: Array<Float> = null;
|
||||
if (object.channels.length > 0){
|
||||
pos = [];
|
||||
for (channel in object.channels)
|
||||
pos.push(channel.position);
|
||||
}
|
||||
return pos;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
35
leenkx/Sources/leenkx/logicnode/GetSpotLightDataNode.hx
Normal file
35
leenkx/Sources/leenkx/logicnode/GetSpotLightDataNode.hx
Normal file
@ -0,0 +1,35 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.object.LightObject;
|
||||
|
||||
class GetSpotLightDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var light: LightObject = inputs[0].get();
|
||||
|
||||
if (light == null) return null;
|
||||
|
||||
#if lnx_spot
|
||||
if (light.data.raw.type == "spot"){
|
||||
#if lnx_single_point
|
||||
if (from == 0)
|
||||
return Math.acos(light.data.raw.spot_size) * 2;
|
||||
else
|
||||
return light.data.raw.spot_blend * 10;
|
||||
#else
|
||||
if (from == 0)
|
||||
return Math.acos(light.size) * 2;
|
||||
else
|
||||
return light.blend * 10;
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
@ -12,9 +12,9 @@ class GetTilesheetFlipNode extends LogicNode {
|
||||
var object: MeshObject = inputs[0].get();
|
||||
|
||||
if (object == null) return null;
|
||||
if (object.tilesheet == null) return null;
|
||||
if (from == 0) return object.tilesheet.flipX;
|
||||
if (from == 1) return object.tilesheet.flipY;
|
||||
if (object.activeTilesheet == null) return null;
|
||||
if (from == 0) return object.activeTilesheet.flipX;
|
||||
if (from == 1) return object.activeTilesheet.flipY;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -11,9 +11,9 @@ class GetTilesheetStateNode extends LogicNode {
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: MeshObject = inputs[0].get();
|
||||
|
||||
if (object == null || object.tilesheet == null) return null;
|
||||
if (object == null || object.activeTilesheet == null) return null;
|
||||
|
||||
var tilesheet = object.tilesheet;
|
||||
var tilesheet = object.activeTilesheet;
|
||||
|
||||
return switch (from) {
|
||||
case 0: object.name; // Return object name since tilesheet is embedded
|
||||
|
||||
@ -17,6 +17,7 @@ class GetTraitNode extends LogicNode {
|
||||
if (object == null) return null;
|
||||
if (cname == null) cname = cast Type.resolveClass(Main.projectPackage + "." + name);
|
||||
if (cname == null) cname = cast Type.resolveClass(Main.projectPackage + ".node." + name);
|
||||
if (cname == null) cname = cast Type.resolveClass(name);
|
||||
|
||||
return object.getTrait(cname);
|
||||
}
|
||||
|
||||
@ -10,9 +10,10 @@ class GetTransformNode extends LogicNode {
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var relative: Bool = inputs[1].get();
|
||||
|
||||
if (object == null) return null;
|
||||
|
||||
return object.transform.world;
|
||||
return relative && object.parent != null ? object.transform.local : object.transform.world;
|
||||
}
|
||||
}
|
||||
|
||||
34
leenkx/Sources/leenkx/logicnode/GetWorldDataNode.hx
Normal file
34
leenkx/Sources/leenkx/logicnode/GetWorldDataNode.hx
Normal file
@ -0,0 +1,34 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class GetWorldDataNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
|
||||
var world = iron.Scene.active.world.raw;
|
||||
|
||||
return switch (from) {
|
||||
case 0:
|
||||
world.name;
|
||||
case 1:
|
||||
world.turbidity != null ? world.probe.strength * 10 : world.probe.strength;
|
||||
case 2:
|
||||
intToColor(world.background_color);
|
||||
default:
|
||||
null;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
function intToColor(val: Int): Array<Float> {
|
||||
var a: Float = ((val >>> 24) & 0xff) / 255.0;
|
||||
var r: Float = ((val >> 16) & 0xff) / 255.0;
|
||||
var g: Float = ((val >> 8) & 0xff) / 255.0;
|
||||
var b: Float = (val & 0xff) / 255.0;
|
||||
return [r, g, b, a];
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ class GetWorldStrengthNode extends LogicNode {
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return iron.Scene.active.world.raw.probe.strength;
|
||||
var world = iron.Scene.active.world.raw;
|
||||
return world.turbidity != null ? world.probe.strength * 10 : world.probe.strength;
|
||||
}
|
||||
}
|
||||
@ -1,82 +1,48 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_physics
|
||||
import leenkx.trait.physics.PhysicsWorld;
|
||||
#end
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavMesh;
|
||||
import leenkx.trait.NavAgent;
|
||||
#end
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class GoToLocationNode extends LogicNode {
|
||||
|
||||
var object: Object;
|
||||
var location: Vec4;
|
||||
var speed: Float;
|
||||
var turnDuration: Float;
|
||||
var heightOffset: Float;
|
||||
var useRaycast: Bool;
|
||||
var rayCastDepth: Float;
|
||||
var rayCastMask: Int;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from: Int) {
|
||||
object = inputs[1].get();
|
||||
location = inputs[2].get();
|
||||
speed = inputs[3].get();
|
||||
turnDuration = inputs[4].get();
|
||||
heightOffset = inputs[5].get();
|
||||
useRaycast = inputs[6].get();
|
||||
rayCastDepth = inputs[7].get();
|
||||
rayCastMask = inputs[8].get();
|
||||
|
||||
assert(Error, object != null, "The object input not be null");
|
||||
assert(Error, location != null, "The location to navigate to must not be null");
|
||||
assert(Error, speed != null, "Speed of Nav Agent should not be null");
|
||||
|
||||
var navMeshId: String = inputs[1].get();
|
||||
var object: Object = inputs[2].get();
|
||||
var location: Vec4 = inputs[3].get();
|
||||
var speed: Float = inputs[4].get();
|
||||
var turnDuration: Float = inputs[5].get();
|
||||
var heightOffset: Float = inputs[6].get();
|
||||
|
||||
assert(Warning, speed >= 0, "Speed of Nav Agent should be positive");
|
||||
assert(Error, turnDuration != null, "Turn Duration of Nav Agent should not be null");
|
||||
assert(Warning, turnDuration >= 0, "Turn Duration of Nav Agent should be positive");
|
||||
|
||||
#if lnx_navigation
|
||||
var from = object.transform.world.getLoc();
|
||||
var to = location;
|
||||
#if lnx_navigation
|
||||
var activeNavMesh: NavMesh = Navigation.active.navMeshes.get(navMeshId);
|
||||
assert(Error, activeNavMesh != null, "No Navigation Mesh Present");
|
||||
|
||||
assert(Error, Navigation.active.navMeshes.length > 0, "No Navigation Mesh Present");
|
||||
Navigation.active.navMeshes[0].findPath(from, to, function(path: Array<iron.math.Vec4>) {
|
||||
var agent: leenkx.trait.NavAgent = object.getTrait(leenkx.trait.NavAgent);
|
||||
assert(Error, agent != null, "Object does not have a NavAgent trait");
|
||||
agent.speed = speed;
|
||||
agent.turnDuration = turnDuration;
|
||||
agent.heightOffset = heightOffset;
|
||||
agent.tickPos = tickPos;
|
||||
agent.tickRot = tickRot;
|
||||
agent.setPath(path);
|
||||
});
|
||||
#end
|
||||
activeNavMesh.findPath(object.transform.world.getLoc(), location, function(path: Array<Vec4>) {
|
||||
var agent: NavAgent = object.getTrait(NavAgent);
|
||||
assert(Error, agent != null, "Object does not have a NavAgent trait");
|
||||
agent.navMeshId = navMeshId;
|
||||
agent.speed = speed;
|
||||
agent.turnDuration = turnDuration;
|
||||
agent.heightOffset = heightOffset;
|
||||
agent.setPath(path);
|
||||
});
|
||||
#end
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
function tickPos(){
|
||||
#if lnx_physics
|
||||
if(useRaycast) setAgentHeight();
|
||||
#end
|
||||
runOutput(1);
|
||||
}
|
||||
|
||||
function tickRot(){
|
||||
runOutput(2);
|
||||
}
|
||||
|
||||
function setAgentHeight(){
|
||||
#if lnx_physics
|
||||
var fromLoc = object.transform.world.getLoc();
|
||||
var toLoc = fromLoc.clone();
|
||||
toLoc.z += rayCastDepth;
|
||||
var hit = PhysicsWorld.active.rayCast(fromLoc, toLoc, rayCastMask);
|
||||
if(hit != null) object.transform.loc.z = hit.pos.z + heightOffset;
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,6 @@ class GroupNode extends LogicNode {
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return Scene.active.getGroup(property0);
|
||||
return from == 0 ? Scene.active.getGroup(property0) : Scene.active.getGroup(property0).length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,14 +17,16 @@ class HasContactArrayNode extends LogicNode {
|
||||
#if lnx_physics
|
||||
var physics = leenkx.trait.physics.PhysicsWorld.active;
|
||||
var rb1 = object1.getTrait(RigidBody);
|
||||
var rbs = physics.getContacts(rb1);
|
||||
|
||||
if (rb1 != null && rbs != null) {
|
||||
for (object2 in objects) {
|
||||
var rb2 = object2.getTrait(RigidBody);
|
||||
for (rb in rbs) {
|
||||
if (rb == rb2) {
|
||||
return true;
|
||||
if (rb1 != null){
|
||||
var rbs = physics.getContacts(rb1);
|
||||
|
||||
if (rbs != null) {
|
||||
for (object2 in objects) {
|
||||
var rb2 = object2.getTrait(RigidBody);
|
||||
for (rb in rbs) {
|
||||
if (rb == rb2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,12 @@ class LogicTree extends iron.Trait {
|
||||
|
||||
public function add() {}
|
||||
|
||||
public override function remove() {
|
||||
if (paused)
|
||||
_remove = null;
|
||||
super.remove();
|
||||
}
|
||||
|
||||
public var paused = false;
|
||||
|
||||
public function pause() {
|
||||
@ -36,6 +42,7 @@ class LogicTree extends iron.Trait {
|
||||
if (_fixedUpdate != null) for (f in _fixedUpdate) iron.App.removeFixedUpdate(f);
|
||||
if (_update != null) for (f in _update) iron.App.removeUpdate(f);
|
||||
if (_lateUpdate != null) for (f in _lateUpdate) iron.App.removeLateUpdate(f);
|
||||
if (_render2D != null) for (f in _render2D) iron.App.removeRender2D(f);
|
||||
}
|
||||
|
||||
public function resume() {
|
||||
@ -45,5 +52,6 @@ class LogicTree extends iron.Trait {
|
||||
if (_fixedUpdate != null) for (f in _fixedUpdate) iron.App.notifyOnFixedUpdate(f);
|
||||
if (_update != null) for (f in _update) iron.App.notifyOnUpdate(f);
|
||||
if (_lateUpdate != null) for (f in _lateUpdate) iron.App.notifyOnLateUpdate(f);
|
||||
if (_render2D != null) for (f in _render2D) iron.App.notifyOnRender2D(f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,20 @@ package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
import iron.math.Quat;
|
||||
import iron.math.Mat4;
|
||||
|
||||
class LookAtNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
var v1 = new Vec4();
|
||||
var v2 = new Vec4();
|
||||
var q = new Quat();
|
||||
var m = Mat4.identity();
|
||||
var f = new Vec4();
|
||||
var r = new Vec4();
|
||||
var u = new Vec4();
|
||||
var z = new Vec4();
|
||||
var vx = new Vec4();
|
||||
var vy = new Vec4();
|
||||
var vz = new Vec4();
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -18,25 +25,48 @@ class LookAtNode extends LogicNode {
|
||||
var vfrom: Vec4 = inputs[0].get();
|
||||
var vto: Vec4 = inputs[1].get();
|
||||
|
||||
if (vfrom == null || vto == null) return null;
|
||||
f.setFrom(vto).sub(vfrom).normalize();
|
||||
z.set(0, 0, 1);
|
||||
|
||||
if (Math.abs(f.dot(z)) > 0.9999) {
|
||||
z.set(0, 1, 0);
|
||||
}
|
||||
|
||||
r.crossvecs(f, z).normalize();
|
||||
u.crossvecs(r, f).normalize();
|
||||
|
||||
switch (property0) {
|
||||
case "X":
|
||||
v1.set(1, 0, 0);
|
||||
vx.setFrom(f);
|
||||
vy.set(-r.x, -r.y, -r.z);
|
||||
vz.setFrom(u);
|
||||
case "-X":
|
||||
v1.set(-1, 0, 0);
|
||||
vx.set(-f.x, -f.y, -f.z);
|
||||
vy.setFrom(r);
|
||||
vz.setFrom(u);
|
||||
case "Y":
|
||||
v1.set(0, 1, 0);
|
||||
vx.setFrom(r);
|
||||
vy.setFrom(f);
|
||||
vz.setFrom(u);
|
||||
case "-Y":
|
||||
v1.set(0, -1, 0);
|
||||
vx.set(-r.x, -r.y, -r.z);
|
||||
vy.set(-f.x, -f.y, -f.z);
|
||||
vz.setFrom(u);
|
||||
case "Z":
|
||||
v1.set(0, 0, 1);
|
||||
vx.setFrom(r);
|
||||
vy.set(-u.x, -u.y, -u.z);
|
||||
vz.setFrom(f);
|
||||
case "-Z":
|
||||
v1.set(0, 0, -1);
|
||||
vx.setFrom(r);
|
||||
vy.setFrom(u);
|
||||
vz.set(-f.x, -f.y, -f.z);
|
||||
}
|
||||
v2.setFrom(vto).sub(vfrom).normalize();
|
||||
|
||||
q.fromTo(v1, v2);
|
||||
m._00 = vx.x; m._01 = vx.y; m._02 = vx.z;
|
||||
m._10 = vy.x; m._11 = vy.y; m._12 = vy.z;
|
||||
m._20 = vz.x; m._21 = vz.y; m._22 = vz.z;
|
||||
|
||||
q.fromRotationMat(m);
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,17 +6,18 @@ class MapRangeNode extends LogicNode {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): kha.FastFloat {
|
||||
var value = inputs[0].get();
|
||||
var fromMin = inputs[1].get();
|
||||
var fromMax = inputs[2].get();
|
||||
var toMin = inputs[3].get();
|
||||
var toMax = inputs[4].get();
|
||||
override function get(from: Int): Dynamic {
|
||||
var value: Float = inputs[0].get();
|
||||
var fromMin: Float = inputs[1].get();
|
||||
var fromMax: Float = inputs[2].get();
|
||||
var toMin: Float = inputs[3].get();
|
||||
var toMax: Float = inputs[4].get();
|
||||
|
||||
if (value == null || fromMin == null || fromMax == null || toMin == null || toMax == null) return null;
|
||||
var deltaFrom = fromMax - fromMin;
|
||||
if (deltaFrom == 0) return (toMin + toMax) / 2.0;
|
||||
|
||||
//Implements https://stackoverflow.com/a/5732390
|
||||
var slope = (toMax - toMin) / (fromMax - fromMin);
|
||||
//https://stackoverflow.com/a/5732390
|
||||
var slope = (toMax - toMin) / deltaFrom;
|
||||
return toMin + slope * (value - fromMin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,9 +16,43 @@ class MaterialNode extends LogicNode {
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
if (property0 != null) {
|
||||
iron.data.Data.getMaterial(iron.Scene.active.raw.name, property0, function(mat: MaterialData) {
|
||||
value = mat;
|
||||
if (property0 != null && value == null) {
|
||||
var currentSceneName = iron.Scene.active.raw.name;
|
||||
|
||||
iron.data.Data.getSceneRaw(currentSceneName, function(currentFormat: iron.data.SceneFormat.TSceneFormat) {
|
||||
var foundInCurrent = false;
|
||||
|
||||
if (currentFormat.material_datas != null) {
|
||||
for (matData in currentFormat.material_datas) {
|
||||
if (matData.name == property0) {
|
||||
foundInCurrent = true;
|
||||
iron.data.Data.getMaterial(currentSceneName, property0, function(mat: MaterialData) {
|
||||
value = mat;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundInCurrent) {
|
||||
for (sceneName in leenkx.system.Starter.scenes) {
|
||||
if (sceneName == currentSceneName) continue;
|
||||
|
||||
iron.data.Data.getSceneRaw(sceneName, function(sceneFormat: iron.data.SceneFormat.TSceneFormat) {
|
||||
if (sceneFormat.material_datas != null) {
|
||||
for (matData in sceneFormat.material_datas) {
|
||||
if (matData.name == property0) {
|
||||
iron.data.Data.getMaterial(sceneName, property0, function(mat: MaterialData) {
|
||||
value = mat;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (value != null) break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
16
leenkx/Sources/leenkx/logicnode/MathConstantsNode.hx
Normal file
16
leenkx/Sources/leenkx/logicnode/MathConstantsNode.hx
Normal file
@ -0,0 +1,16 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
|
||||
class MathConstantsNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override public function get(index: Int): Dynamic {
|
||||
if (index == 0) return Math.NEGATIVE_INFINITY;
|
||||
else if (index == 1) return Math.POSITIVE_INFINITY;
|
||||
else return Math.PI;
|
||||
}
|
||||
}
|
||||
@ -98,7 +98,18 @@ class MathNode extends LogicNode {
|
||||
}
|
||||
case "Ping-Pong":
|
||||
r = pingpong(inputs[0].get(), inputs[1].get());
|
||||
}
|
||||
case "Hyperbolic Sine":
|
||||
var x = inputs[0].get();
|
||||
r = (Math.exp(x) - Math.exp(-x)) / 2;
|
||||
case "Hyperbolic Cosine":
|
||||
var x = inputs[0].get();
|
||||
r = (Math.exp(x) + Math.exp(-x)) / 2;
|
||||
case "Hyperbolic Tangent":
|
||||
var x = inputs[0].get();
|
||||
var sinh = (Math.exp(x) - Math.exp(-x)) / 2;
|
||||
var cosh = (Math.exp(x) + Math.exp(-x)) / 2;
|
||||
r = sinh / cosh;
|
||||
}
|
||||
// Clamp
|
||||
if (property1) r = r < 0.0 ? 0.0 : (r > 1.0 ? 1.0 : r);
|
||||
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Mat4;
|
||||
|
||||
class MatrixMathNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
var m = Mat4.identity();
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var m1: Mat4 = inputs[0].get();
|
||||
var m2: Mat4 = inputs[1].get();
|
||||
|
||||
if (m1 == null || m2 == null) return null;
|
||||
|
||||
m.setFrom(m1);
|
||||
switch (property0) {
|
||||
case "Multiply":
|
||||
m.multmat(m2);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,12 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.system.Time;
|
||||
|
||||
class MergedKeyboardNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
public var property1: String;
|
||||
var lastTime: Float = -1.0;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -22,7 +25,14 @@ class MergedKeyboardNode extends LogicNode {
|
||||
case "released":
|
||||
b = keyboard.released(property1);
|
||||
}
|
||||
if (b) runOutput(0);
|
||||
if (b) {
|
||||
if (property0 == "started" || property0 == "released") {
|
||||
var currentTime = Time.time();
|
||||
if (currentTime == lastTime && Time.delta != 0) return;
|
||||
lastTime = currentTime;
|
||||
}
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
|
||||
@ -4,11 +4,14 @@ package leenkx.logicnode;
|
||||
import leenkx.trait.internal.DebugConsole;
|
||||
#end
|
||||
|
||||
import iron.system.Time;
|
||||
|
||||
class MergedMouseNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
public var property1: String;
|
||||
public var property2: Bool;
|
||||
var lastTime: Float = -1.0;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -33,7 +36,14 @@ class MergedMouseNode extends LogicNode {
|
||||
case "moved":
|
||||
b = mouse.moved;
|
||||
}
|
||||
if (b) runOutput(0);
|
||||
if (b) {
|
||||
if (property0 == "started" || property0 == "released") {
|
||||
var currentTime = Time.time();
|
||||
if (currentTime == lastTime && Time.delta != 0) return;
|
||||
lastTime = currentTime;
|
||||
}
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.system.Time;
|
||||
|
||||
class MergedSurfaceNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
var lastTime: Float = -1.0;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -23,7 +26,14 @@ class MergedSurfaceNode extends LogicNode {
|
||||
case "moved":
|
||||
b = surface.moved;
|
||||
}
|
||||
if (b) runOutput(0);
|
||||
if (b) {
|
||||
if (property0 == "started" || property0 == "released") {
|
||||
var currentTime = Time.time();
|
||||
if (currentTime == lastTime && Time.delta != 0) return;
|
||||
lastTime = currentTime;
|
||||
}
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.system.Time;
|
||||
|
||||
class MergedVirtualButtonNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
public var property1: String;
|
||||
var lastTime: Float = -1.0;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -23,7 +26,14 @@ class MergedVirtualButtonNode extends LogicNode {
|
||||
case "released":
|
||||
b = vb.released;
|
||||
}
|
||||
if (b) runOutput(0);
|
||||
if (b) {
|
||||
if (property0 == "started" || property0 == "released") {
|
||||
var currentTime = Time.time();
|
||||
if (currentTime == lastTime && Time.delta != 0) return;
|
||||
lastTime = currentTime;
|
||||
}
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
|
||||
@ -1,25 +1,40 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
import iron.math.Vec4;
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavMesh;
|
||||
#end
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
|
||||
class NavigableLocationNode extends LogicNode {
|
||||
|
||||
var loc: Vec4;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if lnx_navigation
|
||||
|
||||
assert(Error, Navigation.active.navMeshes.length > 0, "No Navigation Mesh Present");
|
||||
Navigation.active.navMeshes[0].getRandomPoint(function(p: Vec4) {
|
||||
loc = p;
|
||||
});
|
||||
#end
|
||||
return loc;
|
||||
#if lnx_navigation
|
||||
var object: Object = inputs[0].get();
|
||||
|
||||
var v = new iron.math.Vec4();
|
||||
|
||||
var centerLoc: Vec4 = object.transform.world.getLoc();
|
||||
var dim: Vec4 = object.transform.dim;
|
||||
|
||||
var v = new Vec4(
|
||||
centerLoc.x + dim.x * 0.5 * (Math.random() * 2.0 - 1.0),
|
||||
centerLoc.y + dim.y * 0.5 * (Math.random() * 2.0 - 1.0),
|
||||
centerLoc.z + dim.z * 0.5 * (Math.random() * 2.0 - 1.0)
|
||||
);
|
||||
|
||||
var activeNavMesh: NavMesh = object.getTrait(NavMesh);
|
||||
|
||||
assert(Error, activeNavMesh != null, "No Navigation Mesh Present");
|
||||
return activeNavMesh.getClosestPoint(v);
|
||||
#end
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ class OnContactArrayNode extends LogicNode {
|
||||
|
||||
public var property0: String;
|
||||
var lastContact = false;
|
||||
var contactObjects: Array<Object> = [];
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
@ -19,28 +20,30 @@ class OnContactArrayNode extends LogicNode {
|
||||
var objects: Array<Object> = inputs[1].get();
|
||||
|
||||
if (object1 == null) object1 = tree.object;
|
||||
if (objects == null)return;
|
||||
if (objects == null) return;
|
||||
|
||||
var contact = false;
|
||||
var currentContacts: Array<Object> = [];
|
||||
|
||||
#if lnx_physics
|
||||
var physics = leenkx.trait.physics.PhysicsWorld.active;
|
||||
var rb1 = object1.getTrait(RigidBody);
|
||||
var rbs = physics.getContacts(rb1);
|
||||
if (rb1 != null && rbs != null) {
|
||||
for (object2 in objects) {
|
||||
var rb2 = object2.getTrait(RigidBody);
|
||||
for (rb in rbs) {
|
||||
if (rb == rb2) {
|
||||
contact = true;
|
||||
break;
|
||||
if (rb1 != null){
|
||||
var rbs = physics.getContacts(rb1);
|
||||
if (rbs != null) {
|
||||
for (object2 in objects) {
|
||||
var rb2 = object2.getTrait(RigidBody);
|
||||
for (rb in rbs) {
|
||||
if (rb == rb2) {
|
||||
currentContacts.push(object2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contact) break;
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
var contact = currentContacts.length > 0;
|
||||
var b = false;
|
||||
switch (property0) {
|
||||
case "begin":
|
||||
@ -52,7 +55,13 @@ class OnContactArrayNode extends LogicNode {
|
||||
}
|
||||
|
||||
lastContact = contact;
|
||||
contactObjects = currentContacts;
|
||||
|
||||
if (b) runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
if (from == 1) return contactObjects;
|
||||
return contactObjects.length > 0 ? contactObjects[0] : null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,13 @@ class OnRender2DNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
tree.notifyOnRender2D(onRender2D);
|
||||
#if lnx_ui
|
||||
tree.notifyOnInit(initNode);
|
||||
#end
|
||||
}
|
||||
|
||||
function initNode() {
|
||||
tree.notifyOnRender2D(onRender2D, inputs[0].get());
|
||||
}
|
||||
|
||||
function onRender2D(g: kha.graphics2.Graphics) {
|
||||
@ -15,4 +21,8 @@ class OnRender2DNode extends LogicNode {
|
||||
runOutput(0);
|
||||
RenderToTexture.g = null;
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return onRender2D;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ class PauseActionNode extends LogicNode {
|
||||
override function run(from: Int) {
|
||||
var object: Object = inputs[1].get();
|
||||
|
||||
if (object == null) return;
|
||||
if (object == null){ runOutput(0); return; }
|
||||
var animation = object.animation;
|
||||
if (animation == null) animation = object.getBoneAnimation(object.uid);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ class PauseSoundNode extends LogicNode {
|
||||
override function run(from: Int) {
|
||||
#if lnx_audio
|
||||
var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
|
||||
if (object == null) return;
|
||||
if (object == null){ runOutput(0); return; }
|
||||
object.pause();
|
||||
#end
|
||||
runOutput(0);
|
||||
|
||||
@ -11,9 +11,10 @@ class PauseTilesheetNode extends LogicNode {
|
||||
override function run(from: Int) {
|
||||
var object: MeshObject = inputs[1].get();
|
||||
|
||||
if (object == null || object.tilesheet == null) return;
|
||||
if (object == null){ runOutput(0); return; }
|
||||
if (object.activeTilesheet == null) return;
|
||||
|
||||
object.tilesheet.pause();
|
||||
object.activeTilesheet.pause();
|
||||
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
@ -1,33 +1,94 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_navigation
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import leenkx.trait.NavMesh;
|
||||
#end
|
||||
|
||||
#if lnx_physics
|
||||
import leenkx.trait.physics.PhysicsWorld;
|
||||
import leenkx.trait.physics.RigidBody;
|
||||
#end
|
||||
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
import iron.math.RayCaster;
|
||||
import iron.Scene;
|
||||
|
||||
class PickLocationNode extends LogicNode {
|
||||
|
||||
var loc = new Vec4();
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var object: Object = inputs[0].get();
|
||||
var coords: Vec4 = inputs[1].get();
|
||||
var x: Int = inputs[1].get();
|
||||
var y: Int = inputs[2].get();
|
||||
|
||||
if (object == null || coords == null) return null;
|
||||
var loc = new Vec4();
|
||||
|
||||
#if lnx_physics
|
||||
var physics = leenkx.trait.physics.PhysicsWorld.active;
|
||||
var b = physics.pickClosest(coords.x, coords.y);
|
||||
var rb = object.getTrait(leenkx.trait.physics.RigidBody);
|
||||
#if lnx_navigation
|
||||
var activeNavMesh: NavMesh = object.getTrait(NavMesh);
|
||||
var useChildren = activeNavMesh != null && activeNavMesh.combineImmidiateChildren;
|
||||
#end
|
||||
|
||||
if (rb != null && b == rb) {
|
||||
var p = physics.hitPointWorld;
|
||||
loc.set(p.x, p.y, p.z);
|
||||
return loc;
|
||||
#if lnx_physics
|
||||
var rb = object.getTrait(RigidBody);
|
||||
if (rb != null){
|
||||
var physics = PhysicsWorld.active;
|
||||
var b = physics.pickClosest(x, y);
|
||||
|
||||
var hit = false;
|
||||
|
||||
if (b == rb)
|
||||
hit = true;
|
||||
|
||||
if (!hit) {
|
||||
#if lnx_navigation
|
||||
if (useChildren) {
|
||||
for (child in object.children) {
|
||||
if (child.raw.type != "mesh_object") continue;
|
||||
|
||||
var childRb = child.getTrait(RigidBody);
|
||||
if (childRb != null && childRb == b) {
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
var p = physics.hitPointWorld;
|
||||
loc.set(p.x, p.y, p.z);
|
||||
return loc;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
#end
|
||||
#end
|
||||
|
||||
#if lnx_navigation
|
||||
|
||||
assert(Error, activeNavMesh != null, "No Navigation Mesh Present");
|
||||
|
||||
loc = RayCaster.boxIntersectObject(object, x, y, Scene.active.camera);
|
||||
|
||||
if (loc == null && useChildren) {
|
||||
for (child in object.children) {
|
||||
if (child.raw.type != "mesh_object") continue;
|
||||
|
||||
loc = RayCaster.boxIntersectObject(child, x, y, Scene.active.camera);
|
||||
|
||||
if (loc != null) break;
|
||||
}
|
||||
}
|
||||
|
||||
return loc != null ? activeNavMesh.getClosestPoint(loc) : null;
|
||||
#end
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ class PlayActionFromNode extends LogicNode {
|
||||
loop = inputs[7].get();
|
||||
reverse = inputs[8].get();
|
||||
|
||||
if (object == null) return;
|
||||
if (object == null){ runOutput(0); return; }
|
||||
animation = object.animation;
|
||||
if (animation == null) animation = object.getBoneAnimation(object.uid);
|
||||
|
||||
@ -63,7 +63,7 @@ class PlayActionFromNode extends LogicNode {
|
||||
#if lnx_skin
|
||||
if (animation.isSkinned){
|
||||
for(a in animation.armature.actions)
|
||||
if (a.name == actionR) isnew = false;
|
||||
if (a.name == actionR){ isnew = false; break; }
|
||||
|
||||
if (isnew){
|
||||
for(a in animation.armature.actions)
|
||||
@ -156,7 +156,7 @@ class PlayActionFromNode extends LogicNode {
|
||||
var oactions = cast(animation, ObjectAnimation).oactions;
|
||||
|
||||
for (a in oactions)
|
||||
if (a != null && a.objects[0].name == actionR) isnew = false;
|
||||
if (a != null && a.objects[0].name == actionR){ isnew = false; break; }
|
||||
|
||||
if (isnew){
|
||||
for (a in oactions){
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user