Merge pull request #2283 from MoritzBrueckner/live-patch
Live patch: refactor and logic nodes support
This commit is contained in:
commit
ce75516c59
|
@ -1,13 +1,11 @@
|
||||||
package armory.logicnode;
|
package armory.logicnode;
|
||||||
|
|
||||||
import armory.trait.physics.PhysicsConstraint;
|
|
||||||
#if arm_physics
|
|
||||||
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintType;
|
|
||||||
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
|
|
||||||
#end
|
|
||||||
import iron.object.Object;
|
import iron.object.Object;
|
||||||
import armory.trait.physics.RigidBody;
|
|
||||||
import armory.logicnode.PhysicsConstraintNode;
|
#if arm_physics
|
||||||
|
import armory.trait.physics.PhysicsConstraint;
|
||||||
|
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintType;
|
||||||
|
#end
|
||||||
|
|
||||||
class AddPhysicsConstraintNode extends LogicNode {
|
class AddPhysicsConstraintNode extends LogicNode {
|
||||||
|
|
||||||
|
@ -21,115 +19,96 @@ class AddPhysicsConstraintNode extends LogicNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
override function run(from: Int) {
|
override function run(from: Int) {
|
||||||
var pivotObject:Object = inputs[1].get();
|
var pivotObject: Object = inputs[1].get();
|
||||||
rb1 = inputs[2].get();
|
rb1 = inputs[2].get();
|
||||||
rb2 = inputs[3].get();
|
rb2 = inputs[3].get();
|
||||||
var disableCollisions: Bool = inputs[4].get();
|
|
||||||
var breakable: Bool = inputs[5].get();
|
|
||||||
var breakingThreshold: Float = inputs[6].get();
|
|
||||||
var type: ConstraintType = 0;
|
|
||||||
|
|
||||||
if (pivotObject == null || rb1 == null || rb2 == null) return;
|
if (pivotObject == null || rb1 == null || rb2 == null) return;
|
||||||
|
|
||||||
#if arm_physics
|
#if arm_physics
|
||||||
|
|
||||||
|
var disableCollisions: Bool = inputs[4].get();
|
||||||
|
var breakable: Bool = inputs[5].get();
|
||||||
|
var breakingThreshold: Float = inputs[6].get();
|
||||||
|
var type: ConstraintType = 0;
|
||||||
|
|
||||||
var con: PhysicsConstraint = pivotObject.getTrait(PhysicsConstraint);
|
var con: PhysicsConstraint = pivotObject.getTrait(PhysicsConstraint);
|
||||||
if(con == null)
|
if (con == null) {
|
||||||
{
|
switch (property0) {
|
||||||
switch(property0)
|
case "Fixed": type = Fixed;
|
||||||
{
|
case "Point": type = Point;
|
||||||
case 'Fixed':
|
case "Hinge": type = Hinge;
|
||||||
type = Fixed;
|
case "Slider": type = Slider;
|
||||||
case 'Point':
|
case "Piston": type = Piston;
|
||||||
type = Point;
|
case "Generic Spring": type = Generic;
|
||||||
case 'Hinge':
|
|
||||||
type = Hinge;
|
|
||||||
case 'Slider':
|
|
||||||
type = Slider;
|
|
||||||
case 'Piston':
|
|
||||||
type = Piston;
|
|
||||||
case 'Generic Spring':
|
|
||||||
type = Generic;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! breakable) breakingThreshold = 0.0;
|
if (!breakable) breakingThreshold = 0.0;
|
||||||
|
|
||||||
|
if (type != Generic) {
|
||||||
|
|
||||||
if(type != Generic) {
|
|
||||||
|
|
||||||
con = new PhysicsConstraint(rb1, rb2, type, disableCollisions, breakingThreshold);
|
con = new PhysicsConstraint(rb1, rb2, type, disableCollisions, breakingThreshold);
|
||||||
|
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case Hinge:
|
case Hinge:
|
||||||
var setLimit:Bool = inputs[7].get();
|
var setLimit: Bool = inputs[7].get();
|
||||||
var low:Float = inputs[8].get();
|
var low: Float = inputs[8].get();
|
||||||
var up:Float = inputs[9].get();
|
var up: Float = inputs[9].get();
|
||||||
con.setHingeConstraintLimits(setLimit, low, up);
|
con.setHingeConstraintLimits(setLimit, low, up);
|
||||||
|
|
||||||
case Slider:
|
case Slider:
|
||||||
var setLimit:Bool = inputs[7].get();
|
var setLimit: Bool = inputs[7].get();
|
||||||
var low:Float = inputs[8].get();
|
var low: Float = inputs[8].get();
|
||||||
var up:Float = inputs[9].get();
|
var up: Float = inputs[9].get();
|
||||||
con.setSliderConstraintLimits(setLimit, low, up);
|
con.setSliderConstraintLimits(setLimit, low, up);
|
||||||
|
|
||||||
case Piston:
|
case Piston:
|
||||||
var setLinLimit:Bool = inputs[7].get();
|
var setLinLimit: Bool = inputs[7].get();
|
||||||
var linLow:Float = inputs[8].get();
|
var linLow: Float = inputs[8].get();
|
||||||
var linUp:Float = inputs[9].get();
|
var linUp: Float = inputs[9].get();
|
||||||
var setAngLimit:Bool = inputs[10].get();
|
var setAngLimit: Bool = inputs[10].get();
|
||||||
var angLow:Float = inputs[11].get();
|
var angLow: Float = inputs[11].get();
|
||||||
var angUp:Float = inputs[12].get();
|
var angUp: Float = inputs[12].get();
|
||||||
con.setPistonConstraintLimits(setLinLimit, linLow, linUp, setAngLimit, angLow, angUp);
|
con.setPistonConstraintLimits(setLinLimit, linLow, linUp, setAngLimit, angLow, angUp);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
var spring: Bool = false;
|
var spring: Bool = false;
|
||||||
var prop: PhysicsConstraintNode;
|
var prop: PhysicsConstraintNode;
|
||||||
for(inp in 7...inputs.length)
|
|
||||||
{
|
for (inp in 7...inputs.length) {
|
||||||
prop = inputs[inp].get();
|
prop = inputs[inp].get();
|
||||||
if(prop == null) continue;
|
if (prop == null) continue;
|
||||||
if(prop.isSpring)
|
if (prop.isSpring) {
|
||||||
{
|
|
||||||
spring = true;
|
spring = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(spring) {
|
if (spring) {
|
||||||
con = new PhysicsConstraint(rb1, rb2, GenericSpring, disableCollisions, breakingThreshold);
|
con = new PhysicsConstraint(rb1, rb2, GenericSpring, disableCollisions, breakingThreshold);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
con = new PhysicsConstraint(rb1, rb2, Generic, disableCollisions, breakingThreshold);
|
con = new PhysicsConstraint(rb1, rb2, Generic, disableCollisions, breakingThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(inp in 7...inputs.length)
|
for (inp in 7...inputs.length) {
|
||||||
{
|
|
||||||
prop = inputs[inp].get();
|
prop = inputs[inp].get();
|
||||||
if(prop == null) continue;
|
if (prop == null) continue;
|
||||||
(inp + ': ');
|
|
||||||
|
|
||||||
if(prop.isSpring)
|
if (prop.isSpring) {
|
||||||
{
|
|
||||||
con.setSpringParams(prop.isSpring, prop.value1, prop.value2, prop.axis, prop.isAngular);
|
con.setSpringParams(prop.isSpring, prop.value1, prop.value2, prop.axis, prop.isAngular);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
con.setGenericConstraintLimits(true, prop.value1, prop.value2, prop.axis, prop.isAngular);
|
con.setGenericConstraintLimits(true, prop.value1, prop.value2, prop.axis, prop.isAngular);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pivotObject.addTrait(con);
|
pivotObject.addTrait(con);
|
||||||
|
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
runOutput(0);
|
runOutput(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package armory.logicnode;
|
package armory.logicnode;
|
||||||
|
|
||||||
|
import iron.object.Object;
|
||||||
|
|
||||||
#if arm_physics
|
#if arm_physics
|
||||||
|
import armory.trait.physics.RigidBody;
|
||||||
import armory.trait.physics.bullet.RigidBody.Shape;
|
import armory.trait.physics.bullet.RigidBody.Shape;
|
||||||
#end
|
#end
|
||||||
import iron.object.Object;
|
|
||||||
import armory.trait.physics.RigidBody;
|
|
||||||
|
|
||||||
class AddRigidBodyNode extends LogicNode {
|
class AddRigidBodyNode extends LogicNode {
|
||||||
|
|
||||||
public var property0: String;//Shape
|
public var property0: String; //Shape
|
||||||
public var property1: String;//Advanced
|
public var property1: Bool; //Advanced
|
||||||
public var object: Object;
|
public var object: Object;
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
public function new(tree: LogicTree) {
|
||||||
|
@ -18,6 +20,10 @@ class AddRigidBodyNode extends LogicNode {
|
||||||
|
|
||||||
override function run(from: Int) {
|
override function run(from: Int) {
|
||||||
object = inputs[1].get();
|
object = inputs[1].get();
|
||||||
|
if (object == null) return;
|
||||||
|
|
||||||
|
#if arm_physics
|
||||||
|
|
||||||
var mass: Float = inputs[2].get();
|
var mass: Float = inputs[2].get();
|
||||||
var active: Bool = inputs[3].get();
|
var active: Bool = inputs[3].get();
|
||||||
var animated: Bool = inputs[4].get();
|
var animated: Bool = inputs[4].get();
|
||||||
|
@ -38,8 +44,7 @@ class AddRigidBodyNode extends LogicNode {
|
||||||
|
|
||||||
var shape: Shape = 1;
|
var shape: Shape = 1;
|
||||||
|
|
||||||
if(property1 == 'true')
|
if (property1) {
|
||||||
{
|
|
||||||
margin = inputs[9].get();
|
margin = inputs[9].get();
|
||||||
marginLen = inputs[10].get();
|
marginLen = inputs[10].get();
|
||||||
linDamp = inputs[11].get();
|
linDamp = inputs[11].get();
|
||||||
|
@ -49,50 +54,34 @@ class AddRigidBodyNode extends LogicNode {
|
||||||
angVelThreshold = inputs[15].get();
|
angVelThreshold = inputs[15].get();
|
||||||
group = inputs[16].get();
|
group = inputs[16].get();
|
||||||
mask = inputs[17].get();
|
mask = inputs[17].get();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (object == null) return;
|
|
||||||
|
|
||||||
#if arm_physics
|
|
||||||
var rb: RigidBody = object.getTrait(RigidBody);
|
var rb: RigidBody = object.getTrait(RigidBody);
|
||||||
if((group < 0) || (group > 32)) group = 1; //Limiting max groups to 32
|
if ((group < 0) || (group > 32)) group = 1; //Limiting max groups to 32
|
||||||
if((mask < 0) || (mask > 32)) mask = 1; //Limiting max masks to 32
|
if ((mask < 0) || (mask > 32)) mask = 1; //Limiting max masks to 32
|
||||||
if(rb == null)
|
if (rb == null) {
|
||||||
{
|
switch (property0) {
|
||||||
|
case "Box": shape = Box;
|
||||||
switch (property0){
|
case "Sphere": shape = Sphere;
|
||||||
|
case "Capsule": shape = Capsule;
|
||||||
case 'Box':
|
case "Cone": shape = Cone;
|
||||||
shape = Box;
|
case "Cylinder": shape = Cylinder;
|
||||||
case 'Sphere':
|
case "Convex Hull": shape = ConvexHull;
|
||||||
shape = Sphere;
|
case "Mesh": shape = Mesh;
|
||||||
case 'Capsule':
|
|
||||||
shape = Capsule;
|
|
||||||
case 'Cone':
|
|
||||||
shape = Cone;
|
|
||||||
case 'Cylinder':
|
|
||||||
shape = Cylinder;
|
|
||||||
case 'Convex Hull':
|
|
||||||
shape = ConvexHull;
|
|
||||||
case 'Mesh':
|
|
||||||
shape = Mesh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rb = new RigidBody(shape, mass, friction, bounciness, group, mask);
|
rb = new RigidBody(shape, mass, friction, bounciness, group, mask);
|
||||||
rb.animated = animated;
|
rb.animated = animated;
|
||||||
rb.staticObj = ! active;
|
rb.staticObj = !active;
|
||||||
rb.isTriggerObject(trigger);
|
rb.isTriggerObject(trigger);
|
||||||
if(property1 == 'true')
|
|
||||||
{
|
if (property1) {
|
||||||
rb.linearDamping = linDamp;
|
rb.linearDamping = linDamp;
|
||||||
rb.angularDamping = angDamp;
|
rb.angularDamping = angDamp;
|
||||||
if(margin) rb.collisionMargin = marginLen;
|
if (margin) rb.collisionMargin = marginLen;
|
||||||
if(useDeactiv) {
|
if (useDeactiv) {
|
||||||
rb.setUpDeactivation(true, linearVelThreshold, angVelThreshold, 0.0);
|
rb.setUpDeactivation(true, linearVelThreshold, angVelThreshold, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object.addTrait(rb);
|
object.addTrait(rb);
|
||||||
|
|
|
@ -1,31 +1,136 @@
|
||||||
package armory.logicnode;
|
package armory.logicnode;
|
||||||
|
|
||||||
|
#if arm_patch @:keep @:keepSub #end
|
||||||
class LogicNode {
|
class LogicNode {
|
||||||
|
|
||||||
var tree: LogicTree;
|
var tree: LogicTree;
|
||||||
var inputs: Array<LogicNodeInput> = [];
|
var inputs: Array<LogicNodeLink> = [];
|
||||||
var outputs: Array<Array<LogicNode>> = [];
|
var outputs: Array<Array<LogicNodeLink>> = [];
|
||||||
|
|
||||||
#if arm_debug
|
#if (arm_debug || arm_patch)
|
||||||
public var name = "";
|
public var name = "";
|
||||||
public function watch(b: Bool) { // Watch in debug console
|
|
||||||
var nodes = armory.trait.internal.DebugConsole.watchNodes;
|
#if (arm_debug)
|
||||||
b ? nodes.push(this) : nodes.remove(this);
|
public function watch(b: Bool) { // Watch in debug console
|
||||||
}
|
var nodes = armory.trait.internal.DebugConsole.watchNodes;
|
||||||
|
b ? nodes.push(this) : nodes.remove(this);
|
||||||
|
}
|
||||||
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
public function new(tree: LogicTree) {
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addInput(node: LogicNode, from: Int) {
|
/**
|
||||||
inputs.push(new LogicNodeInput(node, from));
|
Resize the inputs array to a given size to minimize dynamic
|
||||||
|
reallocation and over-allocation later.
|
||||||
|
**/
|
||||||
|
inline function preallocInputs(amount: Int) {
|
||||||
|
this.inputs.resize(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addOutputs(nodes: Array<LogicNode>) {
|
/**
|
||||||
outputs.push(nodes);
|
Resize the outputs array to a given size to minimize dynamic
|
||||||
|
reallocation and over-allocation later.
|
||||||
|
**/
|
||||||
|
inline function preallocOutputs(amount: Int) {
|
||||||
|
this.outputs.resize(amount);
|
||||||
|
for (i in 0...outputs.length) {
|
||||||
|
outputs[i] = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Add a link between to nodes to the tree.
|
||||||
|
**/
|
||||||
|
public static function addLink(fromNode: LogicNode, toNode: LogicNode, fromIndex: Int, toIndex: Int): LogicNodeLink {
|
||||||
|
var link = new LogicNodeLink(fromNode, toNode, fromIndex, toIndex);
|
||||||
|
|
||||||
|
if (toNode.inputs.length <= toIndex) {
|
||||||
|
toNode.inputs.resize(toIndex + 1);
|
||||||
|
}
|
||||||
|
toNode.inputs[toIndex] = link;
|
||||||
|
|
||||||
|
var fromNodeOuts = fromNode.outputs;
|
||||||
|
var outLen = fromNodeOuts.length;
|
||||||
|
if (outLen <= fromIndex) {
|
||||||
|
fromNodeOuts.resize(fromIndex + 1);
|
||||||
|
|
||||||
|
// Initialize with empty arrays
|
||||||
|
for (i in outLen...fromIndex + 1) {
|
||||||
|
fromNodeOuts[i] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fromNodeOuts[fromIndex].push(link);
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if arm_patch
|
||||||
|
/**
|
||||||
|
Removes a link from the tree.
|
||||||
|
**/
|
||||||
|
static function removeLink(link: LogicNodeLink) {
|
||||||
|
link.fromNode.outputs[link.fromIndex].remove(link);
|
||||||
|
|
||||||
|
// Reuse the same link and connect a default input node to it.
|
||||||
|
// That's why this function is only available in arm_patch mode, we need
|
||||||
|
// access to the link's type and value.
|
||||||
|
link.fromNode = LogicNode.createSocketDefaultNode(link.toNode.tree, link.toType, link.toValue);
|
||||||
|
link.fromIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Removes all inputs and their links from this node.
|
||||||
|
Warning: this function changes the amount of node inputs to 0!
|
||||||
|
**/
|
||||||
|
function clearInputs() {
|
||||||
|
for (link in inputs) {
|
||||||
|
link.fromNode.outputs[link.fromIndex].remove(link);
|
||||||
|
}
|
||||||
|
inputs.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Removes all outputs and their links from this node.
|
||||||
|
Warning: this function changes the amount of node inputs to 0!
|
||||||
|
**/
|
||||||
|
function clearOutputs() {
|
||||||
|
for (links in outputs) {
|
||||||
|
for (link in links) {
|
||||||
|
var defaultNode = LogicNode.createSocketDefaultNode(tree, link.toType, link.toValue);
|
||||||
|
link.fromNode = defaultNode;
|
||||||
|
link.fromIndex = 0;
|
||||||
|
defaultNode.outputs[0] = [link];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outputs.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a default node for a socket so that get() and set() can be
|
||||||
|
used without null checks.
|
||||||
|
Loosely equivalent to `make_logic.build_default_node()` in Python.
|
||||||
|
**/
|
||||||
|
static inline function createSocketDefaultNode(tree: LogicTree, socketType: String, value: Dynamic): LogicNode {
|
||||||
|
// Make sure to not add these nodes to the LogicTree.nodes array as they
|
||||||
|
// won't be garbage collected then if unlinked later.
|
||||||
|
return switch (socketType) {
|
||||||
|
case "VECTOR": new armory.logicnode.VectorNode(tree, value[0], value[1], value[2]);
|
||||||
|
case "RGBA": new armory.logicnode.ColorNode(tree, value[0], value[1], value[2], value[3]);
|
||||||
|
case "RGB": new armory.logicnode.ColorNode(tree, value[0], value[1], value[2]);
|
||||||
|
case "VALUE": new armory.logicnode.FloatNode(tree, value);
|
||||||
|
case "INT": new armory.logicnode.IntegerNode(tree, value);
|
||||||
|
case "BOOLEAN": new armory.logicnode.BooleanNode(tree, value);
|
||||||
|
case "STRING": new armory.logicnode.StringNode(tree, value);
|
||||||
|
case "NONE": new armory.logicnode.NullNode(tree);
|
||||||
|
case "OBJECT": new armory.logicnode.ObjectNode(tree, value);
|
||||||
|
default: new armory.logicnode.DynamicNode(tree, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Called when this node is activated.
|
Called when this node is activated.
|
||||||
@param from impulse index
|
@param from impulse index
|
||||||
|
@ -38,47 +143,45 @@ class LogicNode {
|
||||||
**/
|
**/
|
||||||
function runOutput(i: Int) {
|
function runOutput(i: Int) {
|
||||||
if (i >= outputs.length) return;
|
if (i >= outputs.length) return;
|
||||||
for (output in outputs[i]) {
|
for (outLink in outputs[i]) {
|
||||||
// Check which input activated the node
|
outLink.toNode.run(outLink.toIndex);
|
||||||
for (j in 0...output.inputs.length) {
|
|
||||||
// Check if the node is connected to the current node
|
|
||||||
if (output.inputs[j].node == this) {
|
|
||||||
// Check if the input socekt is linked to current output socket
|
|
||||||
if (output.inputs[j].from == i) {
|
|
||||||
output.run(j);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@:allow(armory.logicnode.LogicNodeInput)
|
@:allow(armory.logicnode.LogicNodeLink)
|
||||||
function get(from: Int): Dynamic { return this; }
|
function get(from: Int): Dynamic { return this; }
|
||||||
|
|
||||||
@:allow(armory.logicnode.LogicNodeInput)
|
@:allow(armory.logicnode.LogicNodeLink)
|
||||||
function set(value: Dynamic) {}
|
function set(value: Dynamic) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogicNodeInput {
|
@:allow(armory.logicnode.LogicNode)
|
||||||
|
@:allow(armory.logicnode.LogicTree)
|
||||||
|
class LogicNodeLink {
|
||||||
|
|
||||||
@:allow(armory.logicnode.LogicNode)
|
var fromNode: LogicNode;
|
||||||
var node: LogicNode;
|
var toNode: LogicNode;
|
||||||
@:allow(armory.logicnode.LogicNode)
|
var fromIndex: Int;
|
||||||
var from: Int; // Socket index
|
var toIndex: Int;
|
||||||
|
|
||||||
public function new(node: LogicNode, from: Int) {
|
#if arm_patch
|
||||||
this.node = node;
|
var fromType: String;
|
||||||
this.from = from;
|
var toType: String;
|
||||||
|
var toValue: Dynamic;
|
||||||
|
#end
|
||||||
|
|
||||||
|
inline function new(fromNode: LogicNode, toNode: LogicNode, fromIndex: Int, toIndex: Int) {
|
||||||
|
this.fromNode = fromNode;
|
||||||
|
this.toNode = toNode;
|
||||||
|
this.fromIndex = fromIndex;
|
||||||
|
this.toIndex = toIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:allow(armory.logicnode.LogicNode)
|
inline function get(): Dynamic {
|
||||||
function get(): Dynamic {
|
return fromNode.get(fromIndex);
|
||||||
return node.get(from);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@:allow(armory.logicnode.LogicNode)
|
inline function set(value: Dynamic) {
|
||||||
function set(value: Dynamic) {
|
fromNode.set(value);
|
||||||
node.set(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,26 @@ package armory.logicnode;
|
||||||
|
|
||||||
class LogicTree extends iron.Trait {
|
class LogicTree extends iron.Trait {
|
||||||
|
|
||||||
|
#if arm_patch
|
||||||
|
/**
|
||||||
|
Stores all trait instances of the tree via its name.
|
||||||
|
**/
|
||||||
|
public static var nodeTrees = new Map<String, Array<LogicTree>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
[node name => logic node] for later node replacement for live patching.
|
||||||
|
**/
|
||||||
|
public var nodes: Map<String, LogicNode>;
|
||||||
|
#end
|
||||||
|
|
||||||
public var loopBreak = false; // Trigger break from loop nodes
|
public var loopBreak = false; // Trigger break from loop nodes
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
#if arm_patch
|
||||||
|
nodes = new Map<String, LogicNode>();
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add() {}
|
public function add() {}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package armory.logicnode;
|
||||||
class MathNode extends LogicNode {
|
class MathNode extends LogicNode {
|
||||||
|
|
||||||
public var property0: String; // Operation
|
public var property0: String; // Operation
|
||||||
public var property1: String; // Clamp
|
public var property1: Bool; // Clamp
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
public function new(tree: LogicTree) {
|
||||||
super(tree);
|
super(tree);
|
||||||
|
@ -80,8 +80,8 @@ class MathNode extends LogicNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clamp
|
// Clamp
|
||||||
if (property1 == "true") r = r < 0.0 ? 0.0 : (r > 1.0 ? 1.0 : r);
|
if (property1) r = r < 0.0 ? 0.0 : (r > 1.0 ? 1.0 : r);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ class MixNode extends LogicNode {
|
||||||
|
|
||||||
public var property0: String; // Type
|
public var property0: String; // Type
|
||||||
public var property1: String; // Ease
|
public var property1: String; // Ease
|
||||||
public var property2: String; // Clamp
|
public var property2: Bool; // Clamp
|
||||||
|
|
||||||
var ease: Float->Float = null;
|
var ease: Float->Float = null;
|
||||||
|
|
||||||
|
@ -50,7 +50,9 @@ class MixNode extends LogicNode {
|
||||||
var v2: Float = inputs[2].get();
|
var v2: Float = inputs[2].get();
|
||||||
var f = v1 + (v2 - v1) * ease(k);
|
var f = v1 + (v2 - v1) * ease(k);
|
||||||
|
|
||||||
if (property2 == "true") f = f < 0 ? 0 : f > 1 ? 1 : f;
|
// Clamp
|
||||||
|
if (property2) f = f < 0 ? 0 : f > 1 ? 1 : f;
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ObjectNode extends LogicNode {
|
||||||
override function set(value: Dynamic) {
|
override function set(value: Dynamic) {
|
||||||
if (inputs.length > 0) inputs[0].set(value);
|
if (inputs.length > 0) inputs[0].set(value);
|
||||||
else {
|
else {
|
||||||
objectName = value.name;
|
objectName = value != null ? value.name : "";
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,50 +3,39 @@ package armory.logicnode;
|
||||||
#if arm_physics
|
#if arm_physics
|
||||||
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
|
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
|
||||||
#end
|
#end
|
||||||
import iron.object.Object;
|
|
||||||
|
|
||||||
class PhysicsConstraintNode extends LogicNode {
|
class PhysicsConstraintNode extends LogicNode {
|
||||||
|
|
||||||
public var property0: String;//Linear or Angular
|
public var property0: String; //Linear or Angular
|
||||||
public var property1: String;//Axis
|
public var property1: String; //Axis
|
||||||
public var property2: String;//Is a spring
|
public var property2: Bool; //Is a spring
|
||||||
public var value1: Float;//Lower limit or Spring Stiffness
|
|
||||||
public var value2: Float;//Upper limit or Spring Damping
|
#if arm_physics
|
||||||
|
public var value1: Float; //Lower limit or Spring Stiffness
|
||||||
|
public var value2: Float; //Upper limit or Spring Damping
|
||||||
public var isAngular: Bool;
|
public var isAngular: Bool;
|
||||||
public var axis: ConstraintAxis;
|
public var axis: ConstraintAxis;
|
||||||
public var isSpring: Bool;
|
public var isSpring: Bool;
|
||||||
|
#end
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
public function new(tree: LogicTree) {
|
||||||
super(tree);
|
super(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
override function get(from: Int): PhysicsConstraintNode {
|
override function get(from: Int): PhysicsConstraintNode {
|
||||||
|
#if arm_physics
|
||||||
value1 = inputs[0].get();
|
value1 = inputs[0].get();
|
||||||
value2 = inputs[1].get();
|
value2 = inputs[1].get();
|
||||||
|
|
||||||
if(property0 == 'Linear') {
|
isAngular = property0 != "Linear";
|
||||||
isAngular = false;
|
isSpring = property2;
|
||||||
}
|
|
||||||
else{
|
|
||||||
isAngular = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(property2 == 'true'){
|
switch (property1) {
|
||||||
isSpring = true;
|
case "X": axis = X;
|
||||||
|
case "Y": axis = Y;
|
||||||
|
case "Z": axis = Z;
|
||||||
}
|
}
|
||||||
else {
|
#end
|
||||||
isSpring = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (property1){
|
|
||||||
case 'X':
|
|
||||||
axis = X;
|
|
||||||
case 'Y':
|
|
||||||
axis = Y;
|
|
||||||
case 'Z':
|
|
||||||
axis = Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ class QuaternionNode extends LogicNode {
|
||||||
super(tree);
|
super(tree);
|
||||||
|
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
addInput(new FloatNode(tree, x), 0);
|
LogicNode.addLink(new FloatNode(tree, x), this, 0, 0);
|
||||||
addInput(new FloatNode(tree, y), 0);
|
LogicNode.addLink(new FloatNode(tree, y), this, 0, 1);
|
||||||
addInput(new FloatNode(tree, z), 0);
|
LogicNode.addLink(new FloatNode(tree, z), this, 0, 2);
|
||||||
addInput(new FloatNode(tree, w), 0);
|
LogicNode.addLink(new FloatNode(tree, w), this, 0, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,15 +27,15 @@ class QuaternionNode extends LogicNode {
|
||||||
switch (from){
|
switch (from){
|
||||||
case 0:
|
case 0:
|
||||||
return value;
|
return value;
|
||||||
case 1:
|
case 1:
|
||||||
var value1 = new Vec4();
|
var value1 = new Vec4();
|
||||||
value1.x = value.x;
|
value1.x = value.x;
|
||||||
value1.y = value.y;
|
value1.y = value.y;
|
||||||
value1.z = value.z;
|
value1.z = value.z;
|
||||||
value1.w = 0; // use 0 to avoid this vector being translated.
|
value1.w = 0; // use 0 to avoid this vector being translated.
|
||||||
return value1;
|
return value1;
|
||||||
case 2:
|
case 2:
|
||||||
return value.w;
|
return value.w;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,9 @@ class SetParentNode extends LogicNode {
|
||||||
|
|
||||||
var parent: Object;
|
var parent: Object;
|
||||||
var isUnparent = false;
|
var isUnparent = false;
|
||||||
if (Std.isOfType(inputs[2].node, ObjectNode)) {
|
|
||||||
var parentNode = cast(inputs[2].node, ObjectNode);
|
if (Std.isOfType(inputs[2].fromNode, ObjectNode)) {
|
||||||
|
var parentNode = cast(inputs[2].fromNode, ObjectNode);
|
||||||
isUnparent = parentNode.objectName == "";
|
isUnparent = parentNode.objectName == "";
|
||||||
}
|
}
|
||||||
if (isUnparent) parent = iron.Scene.active.root;
|
if (isUnparent) parent = iron.Scene.active.root;
|
||||||
|
@ -24,7 +25,7 @@ class SetParentNode extends LogicNode {
|
||||||
if (object == null || parent == null || object.parent == parent) return;
|
if (object == null || parent == null || object.parent == parent) return;
|
||||||
|
|
||||||
object.parent.removeChild(object, isUnparent); // keepTransform
|
object.parent.removeChild(object, isUnparent); // keepTransform
|
||||||
|
|
||||||
#if arm_physics
|
#if arm_physics
|
||||||
var rigidBody = object.getTrait(RigidBody);
|
var rigidBody = object.getTrait(RigidBody);
|
||||||
if (rigidBody != null) rigidBody.setActivationState(0);
|
if (rigidBody != null) rigidBody.setActivationState(0);
|
||||||
|
|
|
@ -7,7 +7,7 @@ class VectorMixNode extends LogicNode {
|
||||||
|
|
||||||
public var property0: String; // Type
|
public var property0: String; // Type
|
||||||
public var property1: String; // Ease
|
public var property1: String; // Ease
|
||||||
public var property2: String; // Clamp
|
public var property2: Bool; // Clamp
|
||||||
|
|
||||||
var v = new Vec4();
|
var v = new Vec4();
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class VectorMixNode extends LogicNode {
|
||||||
v.y = v1.y + (v2.y - v1.y) * f;
|
v.y = v1.y + (v2.y - v1.y) * f;
|
||||||
v.z = v1.z + (v2.z - v1.z) * f;
|
v.z = v1.z + (v2.z - v1.z) * f;
|
||||||
|
|
||||||
if (property2 == "true") v.clamp(0, 1);
|
if (property2) v.clamp(0, 1);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@ class VectorNode extends LogicNode {
|
||||||
super(tree);
|
super(tree);
|
||||||
|
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
addInput(new FloatNode(tree, x), 0);
|
LogicNode.addLink(new FloatNode(tree, x), this, 0, 0);
|
||||||
addInput(new FloatNode(tree, y), 0);
|
LogicNode.addLink(new FloatNode(tree, y), this, 0, 1);
|
||||||
addInput(new FloatNode(tree, z), 0);
|
LogicNode.addLink(new FloatNode(tree, z), this, 0, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ class Bridge {
|
||||||
public static var Input = iron.system.Input;
|
public static var Input = iron.system.Input;
|
||||||
public static var Object = iron.object.Object;
|
public static var Object = iron.object.Object;
|
||||||
public static var Data = iron.data.Data;
|
public static var Data = iron.data.Data;
|
||||||
|
public static var Vec4 = iron.math.Vec4;
|
||||||
public static function log(s: String) { trace(s); };
|
public static function log(s: String) { trace(s); };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
package armory.trait.internal;
|
package armory.trait.internal;
|
||||||
|
|
||||||
|
import armory.logicnode.LogicNode;
|
||||||
|
import armory.logicnode.LogicTree;
|
||||||
|
|
||||||
|
|
||||||
|
#if arm_patch @:expose("LivePatch") #end
|
||||||
|
@:access(armory.logicnode.LogicNode)
|
||||||
|
@:access(armory.logicnode.LogicNodeLink)
|
||||||
class LivePatch extends iron.Trait {
|
class LivePatch extends iron.Trait {
|
||||||
|
|
||||||
#if arm_patch
|
#if !arm_patch
|
||||||
|
public function new() { super(); }
|
||||||
|
#else
|
||||||
|
|
||||||
static var patchId = 0;
|
static var patchId = 0;
|
||||||
|
|
||||||
|
@ -23,9 +32,164 @@ class LivePatch extends iron.Trait {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
public static function patchCreateNodeLink(treeName: String, fromNodeName: String, toNodeName: String, fromIndex: Int, toIndex: Int) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
public function new() { super(); }
|
for (tree in trees) {
|
||||||
|
var fromNode = tree.nodes[fromNodeName];
|
||||||
|
var toNode = tree.nodes[toNodeName];
|
||||||
|
if (fromNode == null || toNode == null) return;
|
||||||
|
|
||||||
|
LogicNode.addLink(fromNode, toNode, fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function patchSetNodeLinks(treeName: String, nodeName: String, inputDatas: Array<Dynamic>, outputDatas: Array<Array<Dynamic>>) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
|
for (tree in trees) {
|
||||||
|
var node = tree.nodes[nodeName];
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
|
node.clearInputs();
|
||||||
|
node.clearOutputs();
|
||||||
|
|
||||||
|
for (inputData in inputDatas) {
|
||||||
|
var fromNode: LogicNode;
|
||||||
|
var fromIndex: Int;
|
||||||
|
|
||||||
|
if (inputData.isLinked) {
|
||||||
|
fromNode = tree.nodes[inputData.fromNode];
|
||||||
|
if (fromNode == null) continue;
|
||||||
|
fromIndex = inputData.fromIndex;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fromNode = LogicNode.createSocketDefaultNode(node.tree, inputData.socketType, inputData.socketValue);
|
||||||
|
fromIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogicNode.addLink(fromNode, node, fromIndex, inputData.toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (outputData in outputDatas) {
|
||||||
|
for (linkData in outputData) {
|
||||||
|
var toNode: LogicNode;
|
||||||
|
var toIndex: Int;
|
||||||
|
|
||||||
|
if (linkData.isLinked) {
|
||||||
|
toNode = tree.nodes[linkData.toNode];
|
||||||
|
if (toNode == null) continue;
|
||||||
|
toIndex = linkData.toIndex;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toNode = LogicNode.createSocketDefaultNode(node.tree, linkData.socketType, linkData.socketValue);
|
||||||
|
toIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogicNode.addLink(node, toNode, linkData.fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function patchUpdateNodeProp(treeName: String, nodeName: String, propName: String, value: Dynamic) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
|
for (tree in trees) {
|
||||||
|
var node = tree.nodes[nodeName];
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
|
Reflect.setField(node, propName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function patchUpdateNodeInputVal(treeName: String, nodeName: String, socketIndex: Int, value: Dynamic) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
|
for (tree in trees) {
|
||||||
|
var node = tree.nodes[nodeName];
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
|
node.inputs[socketIndex].set(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function patchNodeDelete(treeName: String, nodeName: String) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
|
for (tree in trees) {
|
||||||
|
var node = tree.nodes[nodeName];
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
|
node.clearOutputs();
|
||||||
|
node.clearInputs();
|
||||||
|
tree.nodes.remove(nodeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function patchNodeCreate(treeName: String, nodeName: String, nodeType: String, propDatas: Array<Array<Dynamic>>, inputDatas: Array<Array<Dynamic>>, outputDatas: Array<Array<Dynamic>>) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
|
for (tree in trees) {
|
||||||
|
// No further constructor parameters required here, all variable nodes
|
||||||
|
// use optional further parameters and all values are set later in this
|
||||||
|
// function.
|
||||||
|
var newNode: LogicNode = Type.createInstance(Type.resolveClass(nodeType), [tree]);
|
||||||
|
newNode.name = nodeName;
|
||||||
|
tree.nodes[nodeName] = newNode;
|
||||||
|
|
||||||
|
for (propData in propDatas) {
|
||||||
|
Reflect.setField(newNode, propData[0], propData[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
for (inputData in inputDatas) {
|
||||||
|
LogicNode.addLink(LogicNode.createSocketDefaultNode(newNode.tree, inputData[0], inputData[1]), newNode, 0, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (outputData in outputDatas) {
|
||||||
|
LogicNode.addLink(newNode, LogicNode.createSocketDefaultNode(newNode.tree, outputData[0], outputData[1]), i++, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function patchNodeCopy(treeName: String, nodeName: String, newNodeName: String, copyProps: Array<String>, inputDatas: Array<Array<Dynamic>>, outputDatas: Array<Array<Dynamic>>) {
|
||||||
|
if (!LogicTree.nodeTrees.exists(treeName)) return;
|
||||||
|
var trees = LogicTree.nodeTrees[treeName];
|
||||||
|
|
||||||
|
for (tree in trees) {
|
||||||
|
var node = tree.nodes[nodeName];
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
|
// No further constructor parameters required here, all variable nodes
|
||||||
|
// use optional further parameters and all values are set later in this
|
||||||
|
// function.
|
||||||
|
var newNode: LogicNode = Type.createInstance(Type.getClass(node), [tree]);
|
||||||
|
newNode.name = newNodeName;
|
||||||
|
tree.nodes[newNodeName] = newNode;
|
||||||
|
|
||||||
|
for (propName in copyProps) {
|
||||||
|
Reflect.setField(newNode, propName, Reflect.field(node, propName));
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
for (inputData in inputDatas) {
|
||||||
|
LogicNode.addLink(LogicNode.createSocketDefaultNode(newNode.tree, inputData[0], inputData[1]), newNode, 0, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (outputData in outputDatas) {
|
||||||
|
LogicNode.addLink(newNode, LogicNode.createSocketDefaultNode(newNode.tree, outputData[0], outputData[1]), i++, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
|
@ -1531,24 +1531,18 @@ Make sure the mesh only has tris/quads.""")
|
||||||
# Less bias for bigger maps
|
# Less bias for bigger maps
|
||||||
out_light['shadows_bias'] *= 1 / (out_light['shadowmap_size'] / 1024)
|
out_light['shadows_bias'] *= 1 / (out_light['shadowmap_size'] / 1024)
|
||||||
elif objtype == 'POINT':
|
elif objtype == 'POINT':
|
||||||
out_light['strength'] *= 2.6
|
out_light['strength'] *= 0.01
|
||||||
if bpy.app.version >= (2, 80, 72):
|
|
||||||
out_light['strength'] *= 0.01
|
|
||||||
out_light['fov'] = 1.5708 # pi/2
|
out_light['fov'] = 1.5708 # pi/2
|
||||||
out_light['shadowmap_cube'] = True
|
out_light['shadowmap_cube'] = True
|
||||||
if light_ref.shadow_soft_size > 0.1:
|
if light_ref.shadow_soft_size > 0.1:
|
||||||
out_light['light_size'] = light_ref.shadow_soft_size * 10
|
out_light['light_size'] = light_ref.shadow_soft_size * 10
|
||||||
elif objtype == 'SPOT':
|
elif objtype == 'SPOT':
|
||||||
out_light['strength'] *= 2.6
|
out_light['strength'] *= 0.01
|
||||||
if bpy.app.version >= (2, 80, 72):
|
|
||||||
out_light['strength'] *= 0.01
|
|
||||||
out_light['spot_size'] = math.cos(light_ref.spot_size / 2)
|
out_light['spot_size'] = math.cos(light_ref.spot_size / 2)
|
||||||
# Cycles defaults to 0.15
|
# Cycles defaults to 0.15
|
||||||
out_light['spot_blend'] = light_ref.spot_blend / 10
|
out_light['spot_blend'] = light_ref.spot_blend / 10
|
||||||
elif objtype == 'AREA':
|
elif objtype == 'AREA':
|
||||||
out_light['strength'] *= 80.0 / (light_ref.size * light_ref.size_y)
|
out_light['strength'] *= 0.01
|
||||||
if bpy.app.version >= (2, 80, 72):
|
|
||||||
out_light['strength'] *= 0.01
|
|
||||||
out_light['size'] = light_ref.size
|
out_light['size'] = light_ref.size
|
||||||
out_light['size_y'] = light_ref.size_y
|
out_light['size_y'] = light_ref.size_y
|
||||||
|
|
||||||
|
@ -2460,7 +2454,7 @@ Make sure the mesh only has tris/quads.""")
|
||||||
else:
|
else:
|
||||||
self.material_to_object_dict[mat] = [bobject]
|
self.material_to_object_dict[mat] = [bobject]
|
||||||
self.material_to_arm_object_dict[mat] = [o]
|
self.material_to_arm_object_dict[mat] = [o]
|
||||||
|
|
||||||
# Add UniformsManager trait
|
# Add UniformsManager trait
|
||||||
if type is NodeType.MESH:
|
if type is NodeType.MESH:
|
||||||
uniformManager = {}
|
uniformManager = {}
|
||||||
|
@ -2678,7 +2672,7 @@ Make sure the mesh only has tris/quads.""")
|
||||||
}
|
}
|
||||||
self.output['traits'].append(out_trait)
|
self.output['traits'].append(out_trait)
|
||||||
|
|
||||||
if wrd.arm_live_patch:
|
if arm.utils.is_livepatch_enabled():
|
||||||
if 'traits' not in self.output:
|
if 'traits' not in self.output:
|
||||||
self.output['traits'] = []
|
self.output['traits'] = []
|
||||||
out_trait = {'type': 'Script', 'class_name': 'armory.trait.internal.LivePatch'}
|
out_trait = {'type': 'Script', 'class_name': 'armory.trait.internal.LivePatch'}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import bpy
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
|
||||||
import arm.api
|
import arm.api
|
||||||
|
import arm.live_patch as live_patch
|
||||||
import arm.logicnode.arm_nodes as arm_nodes
|
import arm.logicnode.arm_nodes as arm_nodes
|
||||||
import arm.nodes_logic
|
import arm.nodes_logic
|
||||||
import arm.make as make
|
import arm.make as make
|
||||||
|
@ -14,6 +15,7 @@ import arm.make_state as state
|
||||||
import arm.props as props
|
import arm.props as props
|
||||||
import arm.utils
|
import arm.utils
|
||||||
|
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def on_depsgraph_update_post(self):
|
def on_depsgraph_update_post(self):
|
||||||
if state.proc_build != None:
|
if state.proc_build != None:
|
||||||
|
@ -41,12 +43,10 @@ def on_depsgraph_update_post(self):
|
||||||
|
|
||||||
# Send last operator to Krom
|
# Send last operator to Krom
|
||||||
wrd = bpy.data.worlds['Arm']
|
wrd = bpy.data.worlds['Arm']
|
||||||
if state.proc_play != None and \
|
if state.proc_play is not None and state.target == 'krom' and wrd.arm_live_patch:
|
||||||
state.target == 'krom' and \
|
|
||||||
wrd.arm_live_patch:
|
|
||||||
ops = bpy.context.window_manager.operators
|
ops = bpy.context.window_manager.operators
|
||||||
if len(ops) > 0 and ops[-1] != None:
|
if len(ops) > 0 and ops[-1] is not None:
|
||||||
send_operator(ops[-1])
|
live_patch.on_operator(ops[-1].bl_idname)
|
||||||
|
|
||||||
# Hacky solution to update armory props after operator executions
|
# Hacky solution to update armory props after operator executions
|
||||||
last_operator = bpy.context.active_operator
|
last_operator = bpy.context.active_operator
|
||||||
|
@ -125,6 +125,7 @@ def poll_threads() -> float:
|
||||||
appended_py_paths = []
|
appended_py_paths = []
|
||||||
context_screen = None
|
context_screen = None
|
||||||
|
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def on_load_post(context):
|
def on_load_post(context):
|
||||||
global appended_py_paths
|
global appended_py_paths
|
||||||
|
|
376
blender/arm/live_patch.py
Normal file
376
blender/arm/live_patch.py
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from typing import Any, Type
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
import arm.assets
|
||||||
|
import arm.node_utils
|
||||||
|
from arm.exporter import ArmoryExporter
|
||||||
|
import arm.log as log
|
||||||
|
from arm.logicnode.arm_nodes import ArmLogicTreeNode
|
||||||
|
import arm.make as make
|
||||||
|
import arm.make_state as state
|
||||||
|
import arm.utils
|
||||||
|
|
||||||
|
# Current patch id
|
||||||
|
patch_id = 0
|
||||||
|
|
||||||
|
# Any object can act as a message bus owner
|
||||||
|
msgbus_owner = object()
|
||||||
|
|
||||||
|
# Whether live patch is currently active
|
||||||
|
__running = False
|
||||||
|
|
||||||
|
|
||||||
|
def start():
|
||||||
|
"""Start the live patch session."""
|
||||||
|
log.debug("Live patch session started")
|
||||||
|
|
||||||
|
listen(bpy.types.Object, "location", "obj_location")
|
||||||
|
listen(bpy.types.Object, "rotation_euler", "obj_rotation")
|
||||||
|
listen(bpy.types.Object, "scale", "obj_scale")
|
||||||
|
|
||||||
|
# 'energy' is defined in sub classes only, also workaround for
|
||||||
|
# https://developer.blender.org/T88408
|
||||||
|
for light_type in (bpy.types.AreaLight, bpy.types.PointLight, bpy.types.SpotLight, bpy.types.SunLight):
|
||||||
|
listen(light_type, "color", "light_color")
|
||||||
|
listen(light_type, "energy", "light_energy")
|
||||||
|
|
||||||
|
global __running
|
||||||
|
__running = True
|
||||||
|
|
||||||
|
|
||||||
|
def stop():
|
||||||
|
"""Stop the live patch session."""
|
||||||
|
global __running
|
||||||
|
if __running:
|
||||||
|
__running = False
|
||||||
|
|
||||||
|
log.debug("Live patch session stopped")
|
||||||
|
bpy.msgbus.clear_by_owner(msgbus_owner)
|
||||||
|
|
||||||
|
|
||||||
|
def patch_export():
|
||||||
|
"""Re-export the current scene and update the game accordingly."""
|
||||||
|
if not __running or state.proc_build is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
arm.assets.invalidate_enabled = False
|
||||||
|
|
||||||
|
with arm.utils.WorkingDir(arm.utils.get_fp()):
|
||||||
|
asset_path = arm.utils.get_fp_build() + '/compiled/Assets/' + arm.utils.safestr(bpy.context.scene.name) + '.arm'
|
||||||
|
ArmoryExporter.export_scene(bpy.context, asset_path, scene=bpy.context.scene)
|
||||||
|
|
||||||
|
dir_std_shaders_dst = os.path.join(arm.utils.build_dir(), 'compiled', 'Shaders', 'std')
|
||||||
|
if not os.path.isdir(dir_std_shaders_dst):
|
||||||
|
dir_std_shaders_src = os.path.join(arm.utils.get_sdk_path(), 'armory', 'Shaders', 'std')
|
||||||
|
shutil.copytree(dir_std_shaders_src, dir_std_shaders_dst)
|
||||||
|
|
||||||
|
node_path = arm.utils.get_node_path()
|
||||||
|
khamake_path = arm.utils.get_khamake_path()
|
||||||
|
cmd = [
|
||||||
|
node_path, khamake_path, 'krom',
|
||||||
|
'--shaderversion', '330',
|
||||||
|
'--parallelAssetConversion', '4',
|
||||||
|
'--to', arm.utils.build_dir() + '/debug',
|
||||||
|
'--nohaxe',
|
||||||
|
'--noproject'
|
||||||
|
]
|
||||||
|
|
||||||
|
arm.assets.invalidate_enabled = True
|
||||||
|
state.proc_build = make.run_proc(cmd, patch_done)
|
||||||
|
|
||||||
|
|
||||||
|
def patch_done():
|
||||||
|
"""Signal Iron to reload the running scene after a re-export."""
|
||||||
|
js = 'iron.Scene.patch();'
|
||||||
|
write_patch(js)
|
||||||
|
state.proc_build = None
|
||||||
|
|
||||||
|
|
||||||
|
def write_patch(js: str):
|
||||||
|
"""Write the given javascript code to 'krom.patch'."""
|
||||||
|
global patch_id
|
||||||
|
with open(arm.utils.get_fp_build() + '/debug/krom/krom.patch', 'w') as f:
|
||||||
|
patch_id += 1
|
||||||
|
f.write(str(patch_id) + '\n')
|
||||||
|
f.write(js)
|
||||||
|
|
||||||
|
|
||||||
|
def listen(rna_type: Type[bpy.types.bpy_struct], prop: str, event_id: str):
|
||||||
|
"""Subscribe to '<rna_type>.<prop>'. The event_id can be choosen
|
||||||
|
freely but must match with the id used in send_event().
|
||||||
|
"""
|
||||||
|
bpy.msgbus.subscribe_rna(
|
||||||
|
key=(rna_type, prop),
|
||||||
|
owner=msgbus_owner,
|
||||||
|
args=(event_id, ),
|
||||||
|
notify=send_event
|
||||||
|
# options={"PERSISTENT"}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def send_event(event_id: str, opt_data: Any = None):
|
||||||
|
"""Send the result of the given event to Krom."""
|
||||||
|
if not __running:
|
||||||
|
return
|
||||||
|
|
||||||
|
if hasattr(bpy.context, 'object') and bpy.context.object is not None:
|
||||||
|
obj = bpy.context.object.name
|
||||||
|
|
||||||
|
if bpy.context.object.mode == "OBJECT":
|
||||||
|
if event_id == "obj_location":
|
||||||
|
vec = bpy.context.object.location
|
||||||
|
js = f'var o = iron.Scene.active.getChild("{obj}"); o.transform.loc.set({vec[0]}, {vec[1]}, {vec[2]}); o.transform.dirty = true;'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'obj_scale':
|
||||||
|
vec = bpy.context.object.scale
|
||||||
|
js = f'var o = iron.Scene.active.getChild("{obj}"); o.transform.scale.set({vec[0]}, {vec[1]}, {vec[2]}); o.transform.dirty = true;'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'obj_rotation':
|
||||||
|
vec = bpy.context.object.rotation_euler.to_quaternion()
|
||||||
|
js = f'var o = iron.Scene.active.getChild("{obj}"); o.transform.rot.set({vec[1]}, {vec[2]}, {vec[3]}, {vec[0]}); o.transform.dirty = true;'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'light_color':
|
||||||
|
light: bpy.types.Light = bpy.context.object.data
|
||||||
|
vec = light.color
|
||||||
|
js = f'var lRaw = iron.Scene.active.getLight("{light.name}").data.raw; lRaw.color[0]={vec[0]}; lRaw.color[1]={vec[1]}; lRaw.color[2]={vec[2]};'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'light_energy':
|
||||||
|
light: bpy.types.Light = bpy.context.object.data
|
||||||
|
|
||||||
|
# Align strength to Armory, see exporter.export_light()
|
||||||
|
# TODO: Use exporter.export_light() and simply reload all raw light data in Iron?
|
||||||
|
strength_fac = 1.0
|
||||||
|
if light.type == 'SUN':
|
||||||
|
strength_fac = 0.325
|
||||||
|
elif light.type in ('POINT', 'SPOT', 'AREA'):
|
||||||
|
strength_fac = 0.01
|
||||||
|
|
||||||
|
js = f'var lRaw = iron.Scene.active.getLight("{light.name}").data.raw; lRaw.strength={light.energy * strength_fac};'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
else:
|
||||||
|
patch_export()
|
||||||
|
|
||||||
|
if event_id == 'ln_insert_link':
|
||||||
|
node: ArmLogicTreeNode
|
||||||
|
link: bpy.types.NodeLink
|
||||||
|
node, link = opt_data
|
||||||
|
|
||||||
|
# This event is called twice for a connection but we only need
|
||||||
|
# send it once
|
||||||
|
if node == link.from_node:
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(node.get_tree())
|
||||||
|
|
||||||
|
# [1:] is used here because make_logic already uses that for
|
||||||
|
# node names if arm_debug is used
|
||||||
|
from_node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
to_node_name = arm.node_utils.get_export_node_name(link.to_node)[1:]
|
||||||
|
|
||||||
|
from_index = arm.node_utils.get_socket_index(node.outputs, link.from_socket)
|
||||||
|
to_index = arm.node_utils.get_socket_index(link.to_node.inputs, link.to_socket)
|
||||||
|
|
||||||
|
js = f'LivePatch.patchCreateNodeLink("{tree_name}", "{from_node_name}", "{to_node_name}", "{from_index}", "{to_index}");'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'ln_update_prop':
|
||||||
|
node: ArmLogicTreeNode
|
||||||
|
prop_name: str
|
||||||
|
node, prop_name = opt_data
|
||||||
|
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(node.get_tree())
|
||||||
|
node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
|
||||||
|
value = arm.node_utils.haxe_format_prop_value(node, prop_name)
|
||||||
|
|
||||||
|
if prop_name.endswith('_get'):
|
||||||
|
# Hack because some nodes use a different Python property
|
||||||
|
# name than they use in Haxe
|
||||||
|
prop_name = prop_name[:-4]
|
||||||
|
|
||||||
|
js = f'LivePatch.patchUpdateNodeProp("{tree_name}", "{node_name}", "{prop_name}", {value});'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'ln_socket_val':
|
||||||
|
node: ArmLogicTreeNode
|
||||||
|
socket: bpy.types.NodeSocket
|
||||||
|
node, socket = opt_data
|
||||||
|
|
||||||
|
socket_index = arm.node_utils.get_socket_index(node.inputs, socket)
|
||||||
|
|
||||||
|
if socket_index != -1:
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(node.get_tree())
|
||||||
|
node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
|
||||||
|
value = socket.get_default_value()
|
||||||
|
inp_type = socket.arm_socket_type
|
||||||
|
|
||||||
|
if inp_type in ('VECTOR', 'RGB'):
|
||||||
|
value = f'new iron.Vec4({arm.node_utils.haxe_format_socket_val(value, array_outer_brackets=False)}, 1.0)'
|
||||||
|
elif inp_type == 'RGBA':
|
||||||
|
value = f'new iron.Vec4({arm.node_utils.haxe_format_socket_val(value, array_outer_brackets=False)})'
|
||||||
|
elif inp_type == 'OBJECT':
|
||||||
|
value = f'iron.Scene.active.getChild("{value}")' if value != '' else 'null'
|
||||||
|
else:
|
||||||
|
value = arm.node_utils.haxe_format_socket_val(value)
|
||||||
|
|
||||||
|
js = f'LivePatch.patchUpdateNodeInputVal("{tree_name}", "{node_name}", {socket_index}, {value});'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'ln_create':
|
||||||
|
node: ArmLogicTreeNode = opt_data
|
||||||
|
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(node.get_tree())
|
||||||
|
node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
node_type = 'armory.logicnode.' + node.bl_idname[2:]
|
||||||
|
|
||||||
|
prop_names = list(arm.node_utils.get_haxe_property_names(node))
|
||||||
|
prop_py_names, prop_hx_names = zip(*prop_names) if len(prop_names) > 0 else ([], [])
|
||||||
|
prop_values = (getattr(node, prop_name) for prop_name in prop_py_names)
|
||||||
|
prop_datas = arm.node_utils.haxe_format_socket_val(list(zip(prop_hx_names, prop_values)))
|
||||||
|
|
||||||
|
inp_data = [(inp.arm_socket_type, inp.get_default_value()) for inp in node.inputs]
|
||||||
|
inp_data = arm.node_utils.haxe_format_socket_val(inp_data)
|
||||||
|
out_data = [(out.arm_socket_type, out.get_default_value()) for out in node.outputs]
|
||||||
|
out_data = arm.node_utils.haxe_format_socket_val(out_data)
|
||||||
|
|
||||||
|
js = f'LivePatch.patchNodeCreate("{tree_name}", "{node_name}", "{node_type}", {prop_datas}, {inp_data}, {out_data});'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'ln_delete':
|
||||||
|
node: ArmLogicTreeNode = opt_data
|
||||||
|
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(node.get_tree())
|
||||||
|
node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
|
||||||
|
js = f'LivePatch.patchNodeDelete("{tree_name}", "{node_name}");'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'ln_copy':
|
||||||
|
newnode: ArmLogicTreeNode
|
||||||
|
node: ArmLogicTreeNode
|
||||||
|
newnode, node = opt_data
|
||||||
|
|
||||||
|
# Use newnode to get the tree, node has no id_data at this moment
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(newnode.get_tree())
|
||||||
|
|
||||||
|
newnode_name = arm.node_utils.get_export_node_name(newnode)[1:]
|
||||||
|
node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
|
||||||
|
props_list = '[' + ','.join(f'"{p}"' for _, p in arm.node_utils.get_haxe_property_names(node)) + ']'
|
||||||
|
|
||||||
|
inp_data = [(inp.arm_socket_type, inp.get_default_value()) for inp in newnode.inputs]
|
||||||
|
inp_data = arm.node_utils.haxe_format_socket_val(inp_data)
|
||||||
|
out_data = [(out.arm_socket_type, out.get_default_value()) for out in newnode.outputs]
|
||||||
|
out_data = arm.node_utils.haxe_format_socket_val(out_data)
|
||||||
|
|
||||||
|
js = f'LivePatch.patchNodeCopy("{tree_name}", "{node_name}", "{newnode_name}", {props_list}, {inp_data}, {out_data});'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
elif event_id == 'ln_update_sockets':
|
||||||
|
node: ArmLogicTreeNode = opt_data
|
||||||
|
|
||||||
|
tree_name = arm.node_utils.get_export_tree_name(node.get_tree())
|
||||||
|
node_name = arm.node_utils.get_export_node_name(node)[1:]
|
||||||
|
|
||||||
|
inp_data = '['
|
||||||
|
for idx, inp in enumerate(node.inputs):
|
||||||
|
inp_data += '{'
|
||||||
|
# is_linked can be true even if there are no links if the
|
||||||
|
# user starts dragging a connection away before releasing
|
||||||
|
# the mouse
|
||||||
|
if inp.is_linked and len(inp.links) > 0:
|
||||||
|
inp_data += 'isLinked: true,'
|
||||||
|
inp_data += f'fromNode: "{arm.node_utils.get_export_node_name(inp.links[0].from_node)[1:]}",'
|
||||||
|
inp_data += f'fromIndex: {arm.node_utils.get_socket_index(inp.links[0].from_node.outputs, inp.links[0].from_socket)},'
|
||||||
|
else:
|
||||||
|
inp_data += 'isLinked: false,'
|
||||||
|
inp_data += f'socketType: "{inp.arm_socket_type}",'
|
||||||
|
inp_data += f'socketValue: {arm.node_utils.haxe_format_socket_val(inp.get_default_value())},'
|
||||||
|
|
||||||
|
inp_data += f'toIndex: {idx}'
|
||||||
|
inp_data += '},'
|
||||||
|
inp_data += ']'
|
||||||
|
|
||||||
|
out_data = '['
|
||||||
|
for idx, out in enumerate(node.outputs):
|
||||||
|
out_data += '['
|
||||||
|
for link in out.links:
|
||||||
|
out_data += '{'
|
||||||
|
if out.is_linked:
|
||||||
|
out_data += 'isLinked: true,'
|
||||||
|
out_data += f'toNode: "{arm.node_utils.get_export_node_name(link.to_node)[1:]}",'
|
||||||
|
out_data += f'toIndex: {arm.node_utils.get_socket_index(link.to_node.inputs, link.to_socket)},'
|
||||||
|
else:
|
||||||
|
out_data += 'isLinked: false,'
|
||||||
|
out_data += f'socketType: "{out.arm_socket_type}",'
|
||||||
|
out_data += f'socketValue: {arm.node_utils.haxe_format_socket_val(out.get_default_value())},'
|
||||||
|
|
||||||
|
out_data += f'fromIndex: {idx}'
|
||||||
|
out_data += '},'
|
||||||
|
out_data += '],'
|
||||||
|
out_data += ']'
|
||||||
|
|
||||||
|
js = f'LivePatch.patchSetNodeLinks("{tree_name}", "{node_name}", {inp_data}, {out_data});'
|
||||||
|
write_patch(js)
|
||||||
|
|
||||||
|
|
||||||
|
def on_operator(operator_id: str):
|
||||||
|
"""As long as bpy.msgbus doesn't listen to changes made by
|
||||||
|
operators (*), additionally notify the callback manually.
|
||||||
|
|
||||||
|
(*) https://developer.blender.org/T72109
|
||||||
|
"""
|
||||||
|
if not __running:
|
||||||
|
return
|
||||||
|
|
||||||
|
if operator_id in IGNORE_OPERATORS:
|
||||||
|
return
|
||||||
|
|
||||||
|
if operator_id == 'TRANSFORM_OT_translate':
|
||||||
|
send_event('obj_location')
|
||||||
|
elif operator_id in ('TRANSFORM_OT_rotate', 'TRANSFORM_OT_trackball'):
|
||||||
|
send_event('obj_rotation')
|
||||||
|
elif operator_id == 'TRANSFORM_OT_resize':
|
||||||
|
send_event('obj_scale')
|
||||||
|
|
||||||
|
# Rebuild
|
||||||
|
else:
|
||||||
|
patch_export()
|
||||||
|
|
||||||
|
|
||||||
|
# Don't re-export the scene for the following operators
|
||||||
|
IGNORE_OPERATORS = (
|
||||||
|
'ARM_OT_node_add_input',
|
||||||
|
'ARM_OT_node_add_input_output',
|
||||||
|
'ARM_OT_node_add_input_value',
|
||||||
|
'ARM_OT_node_add_output',
|
||||||
|
'ARM_OT_node_call_func',
|
||||||
|
'ARM_OT_node_remove_input',
|
||||||
|
'ARM_OT_node_remove_input_output',
|
||||||
|
'ARM_OT_node_remove_input_value',
|
||||||
|
'ARM_OT_node_remove_output',
|
||||||
|
'ARM_OT_node_search',
|
||||||
|
|
||||||
|
'NODE_OT_delete',
|
||||||
|
'NODE_OT_duplicate_move',
|
||||||
|
'NODE_OT_hide_toggle',
|
||||||
|
'NODE_OT_link',
|
||||||
|
'NODE_OT_move_detach_links',
|
||||||
|
'NODE_OT_select',
|
||||||
|
'NODE_OT_translate_attach',
|
||||||
|
'NODE_OT_translate_attach_remove_on_cancel',
|
||||||
|
|
||||||
|
'OBJECT_OT_editmode_toggle',
|
||||||
|
'OUTLINER_OT_item_activate',
|
||||||
|
'UI_OT_button_string_clear',
|
||||||
|
'UI_OT_eyedropper_id',
|
||||||
|
'VIEW3D_OT_select',
|
||||||
|
'VIEW3D_OT_select_box',
|
||||||
|
)
|
|
@ -6,8 +6,7 @@ class AnimActionNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Action'
|
bl_label = 'Action'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(AnimActionNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAnimAction', 'Action')
|
self.add_input('ArmNodeSocketAnimAction', 'Action')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAnimAction', 'Action', is_var=True)
|
self.add_output('ArmNodeSocketAnimAction', 'Action', is_var=True)
|
||||||
|
|
|
@ -6,12 +6,11 @@ class BlendActionNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Blend Action'
|
bl_label = 'Blend Action'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(BlendActionNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('ArmNodeSocketAnimAction', 'Action 1')
|
self.add_input('ArmNodeSocketAnimAction', 'Action 1')
|
||||||
self.add_input('ArmNodeSocketAnimAction', 'Action 2')
|
self.add_input('ArmNodeSocketAnimAction', 'Action 2')
|
||||||
self.add_input('NodeSocketFloat', 'Factor', default_value = 0.5)
|
self.add_input('ArmFloatSocket', 'Factor', default_value = 0.5)
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -7,11 +7,10 @@ class BoneFKNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'armature'
|
arm_section = 'armature'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(BoneFKNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Bone')
|
self.add_input('ArmStringSocket', 'Bone')
|
||||||
self.add_input('NodeSocketShader', 'Transform')
|
self.add_input('ArmDynamicSocket', 'Transform')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -26,19 +26,17 @@ class BoneIKNode(ArmLogicTreeNode):
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
arm_section = 'armature'
|
arm_section = 'armature'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(BoneIKNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Bone')
|
self.add_input('ArmStringSocket', 'Bone')
|
||||||
self.add_input('NodeSocketVector', 'Goal Position')
|
self.add_input('ArmVectorSocket', 'Goal Position')
|
||||||
self.add_input('NodeSocketBool', 'Enable Pole')
|
self.add_input('ArmBoolSocket', 'Enable Pole')
|
||||||
self.add_input('NodeSocketVector', 'Pole Position')
|
self.add_input('ArmVectorSocket', 'Pole Position')
|
||||||
self.add_input('NodeSocketInt', 'Chain Length')
|
self.add_input('ArmIntSocket', 'Chain Length')
|
||||||
self.add_input('NodeSocketInt', 'Max Iterations', 10)
|
self.add_input('ArmIntSocket', 'Max Iterations', 10)
|
||||||
self.add_input('NodeSocketFloat', 'Precision', 0.01)
|
self.add_input('ArmFloatSocket', 'Precision', 0.01)
|
||||||
self.add_input('NodeSocketFloat', 'Roll Angle')
|
self.add_input('ArmFloatSocket', 'Roll Angle')
|
||||||
|
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,9 @@ class AnimationStateNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Action State'
|
bl_label = 'Get Action State'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(AnimationStateNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
|
|
||||||
self.add_output('NodeSocketString', 'Action')
|
self.add_output('ArmStringSocket', 'Action')
|
||||||
self.add_output('NodeSocketInt', 'Frame')
|
self.add_output('ArmIntSocket', 'Frame')
|
||||||
self.add_output('NodeSocketBool', 'Is Paused')
|
self.add_output('ArmBoolSocket', 'Is Paused')
|
||||||
|
|
|
@ -7,8 +7,7 @@ class GetBoneFkIkOnlyNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'armature'
|
arm_section = 'armature'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(GetBoneFkIkOnlyNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Bone')
|
self.add_input('ArmStringSocket', 'Bone')
|
||||||
self.add_output('NodeSocketBool', 'FK or IK only')
|
self.add_output('ArmBoolSocket', 'FK or IK only')
|
||||||
|
|
|
@ -7,8 +7,7 @@ class GetBoneTransformNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'armature'
|
arm_section = 'armature'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(GetBoneTransformNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Bone')
|
self.add_input('ArmStringSocket', 'Bone')
|
||||||
self.add_output('NodeSocketShader', 'Transform')
|
self.add_output('ArmDynamicSocket', 'Transform')
|
||||||
|
|
|
@ -7,10 +7,9 @@ class GetTilesheetStateNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'tilesheet'
|
arm_section = 'tilesheet'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(GetTilesheetStateNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
|
|
||||||
self.add_output('NodeSocketString', 'Name')
|
self.add_output('ArmStringSocket', 'Name')
|
||||||
self.add_output('NodeSocketInt', 'Frame')
|
self.add_output('ArmIntSocket', 'Frame')
|
||||||
self.add_output('NodeSocketBool', 'Is Paused')
|
self.add_output('ArmBoolSocket', 'Is Paused')
|
||||||
|
|
|
@ -6,9 +6,8 @@ class OnActionMarkerNode(ArmLogicTreeNode):
|
||||||
bl_label = 'On Action Marker'
|
bl_label = 'On Action Marker'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnActionMarkerNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Marker')
|
self.add_input('ArmStringSocket', 'Marker')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,15 +6,14 @@ class PlayActionFromNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Play Action From'
|
bl_label = 'Play Action From'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(PlayActionFromNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('ArmNodeSocketAnimAction', 'Action')
|
self.add_input('ArmNodeSocketAnimAction', 'Action')
|
||||||
self.add_input('NodeSocketInt', 'Start Frame')
|
self.add_input('ArmIntSocket', 'Start Frame')
|
||||||
self.add_input('NodeSocketFloat', 'Blend', default_value = 0.25)
|
self.add_input('ArmFloatSocket', 'Blend', default_value = 0.25)
|
||||||
self.add_input('NodeSocketFloat', 'Speed', default_value = 1.0)
|
self.add_input('ArmFloatSocket', 'Speed', default_value = 1.0)
|
||||||
self.add_input('NodeSocketBool', 'Loop', default_value = False)
|
self.add_input('ArmBoolSocket', 'Loop', default_value = False)
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('ArmNodeSocketAction', 'Done')
|
self.add_output('ArmNodeSocketAction', 'Done')
|
||||||
|
@ -22,7 +21,7 @@ class PlayActionFromNode(ArmLogicTreeNode):
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
if self.arm_version not in (0, 1):
|
if self.arm_version not in (0, 1):
|
||||||
raise LookupError()
|
raise LookupError()
|
||||||
|
|
||||||
return NodeReplacement(
|
return NodeReplacement(
|
||||||
'LNPlayActionFromNode', self.arm_version, 'LNPlayActionFromNode', 2,
|
'LNPlayActionFromNode', self.arm_version, 'LNPlayActionFromNode', 2,
|
||||||
in_socket_mapping={0:0, 1:1, 2:2, 3:3, 4:4}, out_socket_mapping={0:0, 1:1}
|
in_socket_mapping={0:0, 1:1, 2:2, 3:3, 4:4}, out_socket_mapping={0:0, 1:1}
|
||||||
|
|
|
@ -7,11 +7,10 @@ class PlayTilesheetNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'tilesheet'
|
arm_section = 'tilesheet'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(PlayTilesheetNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Name')
|
self.add_input('ArmStringSocket', 'Name')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('ArmNodeSocketAction', 'Done')
|
self.add_output('ArmNodeSocketAction', 'Done')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class SetActionPausedNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Action Paused'
|
bl_label = 'Set Action Paused'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetActionPausedNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketBool', 'Paused')
|
self.add_input('ArmBoolSocket', 'Paused')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class SetActionSpeedNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Action Speed'
|
bl_label = 'Set Action Speed'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetActionSpeedNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketFloat', 'Speed', default_value=1.0)
|
self.add_input('ArmFloatSocket', 'Speed', default_value=1.0)
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -7,11 +7,10 @@ class SetBoneFkIkOnlyNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'armature'
|
arm_section = 'armature'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetBoneFkIkOnlyNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketString', 'Bone')
|
self.add_input('ArmStringSocket', 'Bone')
|
||||||
self.add_input('NodeSocketBool', 'FK or IK only')
|
self.add_input('ArmBoolSocket', 'FK or IK only')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -7,11 +7,10 @@ class SetParentBoneNode(ArmLogicTreeNode):
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
arm_section = 'armature'
|
arm_section = 'armature'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetParentBoneNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('ArmNodeSocketObject', 'Parent', default_value='Parent')
|
self.add_input('ArmNodeSocketObject', 'Parent', default_value='Parent')
|
||||||
self.add_input('NodeSocketString', 'Bone', default_value='Bone')
|
self.add_input('ArmStringSocket', 'Bone', default_value='Bone')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class SetParticleSpeedNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Particle Speed'
|
bl_label = 'Set Particle Speed'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetParticleSpeedNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketFloat', 'Speed', default_value=1.0)
|
self.add_input('ArmFloatSocket', 'Speed', default_value=1.0)
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -7,10 +7,9 @@ class SetTilesheetPausedNode(ArmLogicTreeNode):
|
||||||
arm_section = 'tilesheet'
|
arm_section = 'tilesheet'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetTilesheetPausedNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketBool', 'Paused')
|
self.add_input('ArmBoolSocket', 'Paused')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import itertools
|
import itertools
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import Any, Generator, List, Optional, Type, Dict
|
from typing import Any, Generator, List, Optional, Type
|
||||||
from typing import OrderedDict as ODict # Prevent naming conflicts
|
from typing import OrderedDict as ODict # Prevent naming conflicts
|
||||||
|
|
||||||
import bpy.types
|
import bpy.types
|
||||||
from bpy.props import *
|
from bpy.props import *
|
||||||
from nodeitems_utils import NodeItem
|
from nodeitems_utils import NodeItem
|
||||||
|
|
||||||
# Pass NodeReplacment forward to individual node modules that import arm_nodes
|
import arm # we cannot import arm.livepatch here or we have a circular import
|
||||||
|
# Pass custom property types and NodeReplacement forward to individual
|
||||||
|
# node modules that import arm_nodes
|
||||||
|
from arm.logicnode.arm_props import *
|
||||||
from arm.logicnode.replacement import NodeReplacement
|
from arm.logicnode.replacement import NodeReplacement
|
||||||
import arm.node_utils
|
import arm.node_utils
|
||||||
|
|
||||||
|
@ -21,6 +24,10 @@ category_items: ODict[str, List['ArmNodeCategory']] = OrderedDict()
|
||||||
|
|
||||||
array_nodes = dict()
|
array_nodes = dict()
|
||||||
|
|
||||||
|
# See ArmLogicTreeNode.update()
|
||||||
|
# format: [tree pointer => (num inputs, num input links, num outputs, num output links)]
|
||||||
|
last_node_state: dict[int, tuple[int, int, int, int]] = {}
|
||||||
|
|
||||||
|
|
||||||
class ArmLogicTreeNode(bpy.types.Node):
|
class ArmLogicTreeNode(bpy.types.Node):
|
||||||
arm_category = PKG_AS_CATEGORY
|
arm_category = PKG_AS_CATEGORY
|
||||||
|
@ -34,6 +41,14 @@ class ArmLogicTreeNode(bpy.types.Node):
|
||||||
else:
|
else:
|
||||||
self.arm_version = 1
|
self.arm_version = 1
|
||||||
|
|
||||||
|
if not hasattr(self, 'arm_init'):
|
||||||
|
# Show warning for older node packages
|
||||||
|
arm.log.warn(f'Node {self.bl_idname} has no arm_init function and might not work correctly!')
|
||||||
|
else:
|
||||||
|
self.arm_init(context)
|
||||||
|
|
||||||
|
arm.live_patch.send_event('ln_create', self)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, ntree):
|
def poll(cls, ntree):
|
||||||
return ntree.bl_idname == 'ArmLogicTreeType'
|
return ntree.bl_idname == 'ArmLogicTreeType'
|
||||||
|
@ -48,6 +63,68 @@ class ArmLogicTreeNode(bpy.types.Node):
|
||||||
def on_unregister(cls):
|
def on_unregister(cls):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_tree(self):
|
||||||
|
return self.id_data
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
"""Called if the node was updated in some way, for example
|
||||||
|
if socket connections change. This callback is not called if
|
||||||
|
socket values were changed.
|
||||||
|
"""
|
||||||
|
def num_connected(sockets):
|
||||||
|
return sum([socket.is_linked for socket in sockets])
|
||||||
|
|
||||||
|
# If a link between sockets is removed, there is currently no
|
||||||
|
# _reliable_ way in the Blender API to check which connection
|
||||||
|
# was removed (*).
|
||||||
|
#
|
||||||
|
# So instead we just check _if_ the number of links or sockets
|
||||||
|
# has changed (the update function is called before and after
|
||||||
|
# each link removal). Because we listen for those updates in
|
||||||
|
# general, we automatically also listen to link creation events,
|
||||||
|
# which is more stable than using the dedicated callback for
|
||||||
|
# that (`insert_link()`), because adding links can remove other
|
||||||
|
# links and we would need to react to that as well.
|
||||||
|
#
|
||||||
|
# (*) https://devtalk.blender.org/t/how-to-detect-which-link-was-deleted-by-user-in-node-editor
|
||||||
|
|
||||||
|
self_id = self.as_pointer()
|
||||||
|
|
||||||
|
current_state = (len(self.inputs), num_connected(self.inputs), len(self.outputs), num_connected(self.outputs))
|
||||||
|
if self_id not in last_node_state:
|
||||||
|
# Lazily initialize the last_node_state dict to also store
|
||||||
|
# state for nodes that already exist in the tree
|
||||||
|
last_node_state[self_id] = current_state
|
||||||
|
|
||||||
|
if last_node_state[self_id] != current_state:
|
||||||
|
arm.live_patch.send_event('ln_update_sockets', self)
|
||||||
|
last_node_state[self_id] = current_state
|
||||||
|
|
||||||
|
def free(self):
|
||||||
|
"""Called before the node is deleted."""
|
||||||
|
arm.live_patch.send_event('ln_delete', self)
|
||||||
|
|
||||||
|
def copy(self, node):
|
||||||
|
"""Called if the node was copied. `self` holds the copied node,
|
||||||
|
`node` the original one.
|
||||||
|
"""
|
||||||
|
arm.live_patch.send_event('ln_copy', (self, node))
|
||||||
|
|
||||||
|
def on_prop_update(self, context: bpy.types.Context, prop_name: str):
|
||||||
|
"""Called if a property created with a function from the
|
||||||
|
arm_props module is changed. If the property has a custom update
|
||||||
|
function, it is called before `on_prop_update()`.
|
||||||
|
"""
|
||||||
|
arm.live_patch.send_event('ln_update_prop', (self, prop_name))
|
||||||
|
|
||||||
|
def on_socket_val_update(self, context: bpy.types.Context, socket: bpy.types.NodeSocket):
|
||||||
|
arm.live_patch.send_event('ln_socket_val', (self, socket))
|
||||||
|
|
||||||
|
def insert_link(self, link: bpy.types.NodeLink):
|
||||||
|
"""Called on *both* nodes when a link between two nodes is created."""
|
||||||
|
# arm.live_patch.send_event('ln_insert_link', (self, link))
|
||||||
|
pass
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
# needs to be overridden by individual node classes with arm_version>1
|
# needs to be overridden by individual node classes with arm_version>1
|
||||||
"""(only called if the node's version is inferior to the node class's version)
|
"""(only called if the node's version is inferior to the node class's version)
|
||||||
|
@ -115,7 +192,7 @@ class ArmNodeAddInputButton(bpy.types.Operator):
|
||||||
bl_options = {'UNDO', 'INTERNAL'}
|
bl_options = {'UNDO', 'INTERNAL'}
|
||||||
|
|
||||||
node_index: StringProperty(name='Node Index', default='')
|
node_index: StringProperty(name='Node Index', default='')
|
||||||
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
|
socket_type: StringProperty(name='Socket Type', default='ArmDynamicSocket')
|
||||||
name_format: StringProperty(name='Name Format', default='Input {0}')
|
name_format: StringProperty(name='Name Format', default='Input {0}')
|
||||||
index_name_offset: IntProperty(name='Index Name Offset', default=0)
|
index_name_offset: IntProperty(name='Index Name Offset', default=0)
|
||||||
|
|
||||||
|
@ -126,7 +203,7 @@ class ArmNodeAddInputButton(bpy.types.Operator):
|
||||||
|
|
||||||
# Reset to default again for subsequent calls of this operator
|
# Reset to default again for subsequent calls of this operator
|
||||||
self.node_index = ''
|
self.node_index = ''
|
||||||
self.socket_type = 'NodeSocketShader'
|
self.socket_type = 'ArmDynamicSocket'
|
||||||
self.name_format = 'Input {0}'
|
self.name_format = 'Input {0}'
|
||||||
self.index_name_offset = 0
|
self.index_name_offset = 0
|
||||||
|
|
||||||
|
@ -138,7 +215,7 @@ class ArmNodeAddInputValueButton(bpy.types.Operator):
|
||||||
bl_label = 'Add Input'
|
bl_label = 'Add Input'
|
||||||
bl_options = {'UNDO', 'INTERNAL'}
|
bl_options = {'UNDO', 'INTERNAL'}
|
||||||
node_index: StringProperty(name='Node Index', default='')
|
node_index: StringProperty(name='Node Index', default='')
|
||||||
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
|
socket_type: StringProperty(name='Socket Type', default='ArmDynamicSocket')
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
global array_nodes
|
global array_nodes
|
||||||
|
@ -185,7 +262,7 @@ class ArmNodeAddOutputButton(bpy.types.Operator):
|
||||||
bl_options = {'UNDO', 'INTERNAL'}
|
bl_options = {'UNDO', 'INTERNAL'}
|
||||||
|
|
||||||
node_index: StringProperty(name='Node Index', default='')
|
node_index: StringProperty(name='Node Index', default='')
|
||||||
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
|
socket_type: StringProperty(name='Socket Type', default='ArmDynamicSocket')
|
||||||
name_format: StringProperty(name='Name Format', default='Output {0}')
|
name_format: StringProperty(name='Name Format', default='Output {0}')
|
||||||
index_name_offset: IntProperty(name='Index Name Offset', default=0)
|
index_name_offset: IntProperty(name='Index Name Offset', default=0)
|
||||||
|
|
||||||
|
@ -196,7 +273,7 @@ class ArmNodeAddOutputButton(bpy.types.Operator):
|
||||||
|
|
||||||
# Reset to default again for subsequent calls of this operator
|
# Reset to default again for subsequent calls of this operator
|
||||||
self.node_index = ''
|
self.node_index = ''
|
||||||
self.socket_type = 'NodeSocketShader'
|
self.socket_type = 'ArmDynamicSocket'
|
||||||
self.name_format = 'Output {0}'
|
self.name_format = 'Output {0}'
|
||||||
self.index_name_offset = 0
|
self.index_name_offset = 0
|
||||||
|
|
||||||
|
@ -225,8 +302,8 @@ class ArmNodeAddInputOutputButton(bpy.types.Operator):
|
||||||
bl_options = {'UNDO', 'INTERNAL'}
|
bl_options = {'UNDO', 'INTERNAL'}
|
||||||
|
|
||||||
node_index: StringProperty(name='Node Index', default='')
|
node_index: StringProperty(name='Node Index', default='')
|
||||||
in_socket_type: StringProperty(name='In Socket Type', default='NodeSocketShader')
|
in_socket_type: StringProperty(name='In Socket Type', default='ArmDynamicSocket')
|
||||||
out_socket_type: StringProperty(name='Out Socket Type', default='NodeSocketShader')
|
out_socket_type: StringProperty(name='Out Socket Type', default='ArmDynamicSocket')
|
||||||
in_name_format: StringProperty(name='In Name Format', default='Input {0}')
|
in_name_format: StringProperty(name='In Name Format', default='Input {0}')
|
||||||
out_name_format: StringProperty(name='Out Name Format', default='Output {0}')
|
out_name_format: StringProperty(name='Out Name Format', default='Output {0}')
|
||||||
in_index_name_offset: IntProperty(name='Index Name Offset', default=0)
|
in_index_name_offset: IntProperty(name='Index Name Offset', default=0)
|
||||||
|
@ -241,8 +318,8 @@ class ArmNodeAddInputOutputButton(bpy.types.Operator):
|
||||||
|
|
||||||
# Reset to default again for subsequent calls of this operator
|
# Reset to default again for subsequent calls of this operator
|
||||||
self.node_index = ''
|
self.node_index = ''
|
||||||
self.in_socket_type = 'NodeSocketShader'
|
self.in_socket_type = 'ArmDynamicSocket'
|
||||||
self.out_socket_type = 'NodeSocketShader'
|
self.out_socket_type = 'ArmDynamicSocket'
|
||||||
self.in_name_format = 'Input {0}'
|
self.in_name_format = 'Input {0}'
|
||||||
self.out_name_format = 'Output {0}'
|
self.out_name_format = 'Output {0}'
|
||||||
self.in_index_name_offset = 0
|
self.in_index_name_offset = 0
|
||||||
|
|
267
blender/arm/logicnode/arm_props.py
Normal file
267
blender/arm/logicnode/arm_props.py
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
"""Custom bpy property creators for logic nodes. Please be aware that
|
||||||
|
the code in this file is usually run once at registration and not for
|
||||||
|
each individual node instance when it is created.
|
||||||
|
|
||||||
|
The functions for creating typed properties wrap the private __haxe_prop
|
||||||
|
function to allow for IDE autocompletion.
|
||||||
|
|
||||||
|
Some default parameters in the signature of functions in this module are
|
||||||
|
mutable (common Python pitfall, be aware of this!), but because they
|
||||||
|
don't get accessed later it doesn't matter here and we keep it this way
|
||||||
|
for parity with the Blender API.
|
||||||
|
"""
|
||||||
|
from typing import Any, Callable, Sequence, Union
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
|
||||||
|
|
||||||
|
def __haxe_prop(prop_type: Callable, prop_name: str, *args, **kwargs) -> Any:
|
||||||
|
"""Declares a logic node property as a property that will be
|
||||||
|
used ingame for a logic node."""
|
||||||
|
update_callback: Callable = kwargs.get('update', None)
|
||||||
|
if update_callback is None:
|
||||||
|
def wrapper(self: bpy.types.Node, context: bpy.types.Context):
|
||||||
|
self.on_prop_update(context, prop_name)
|
||||||
|
kwargs['update'] = wrapper
|
||||||
|
else:
|
||||||
|
def wrapper(self: bpy.types.Node, context: bpy.types.Context):
|
||||||
|
update_callback(self, context)
|
||||||
|
self.on_prop_update(context, prop_name)
|
||||||
|
kwargs['update'] = wrapper
|
||||||
|
|
||||||
|
# Tags are not allowed on classes other than bpy.types.ID or
|
||||||
|
# bpy.types.Bone, remove them here to prevent registration errors
|
||||||
|
if 'tags' in kwargs:
|
||||||
|
del kwargs['tags']
|
||||||
|
|
||||||
|
return prop_type(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeBoolProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*, # force passing further arguments as keywords, see PEP 3102
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default=False,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> 'bpy.types.BoolProperty':
|
||||||
|
"""Declares a new BoolProperty that has a Haxe counterpart with the
|
||||||
|
given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(BoolProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeBoolVectorProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default: list = (False, False, False),
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
size: int = 3,
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> list['bpy.types.BoolProperty']:
|
||||||
|
"""Declares a new BoolVectorProperty that has a Haxe counterpart
|
||||||
|
with the given prop_name (Python and Haxe names must be identical
|
||||||
|
for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(BoolVectorProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeCollectionProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
type=None,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set()
|
||||||
|
) -> 'bpy.types.CollectionProperty':
|
||||||
|
"""Declares a new CollectionProperty that has a Haxe counterpart
|
||||||
|
with the given prop_name (Python and Haxe names must be identical
|
||||||
|
for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(CollectionProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeEnumProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
items: Sequence,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default: Union[str, set[str]] = None,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> 'bpy.types.EnumProperty':
|
||||||
|
"""Declares a new EnumProperty that has a Haxe counterpart with the
|
||||||
|
given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(EnumProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeFloatProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default=0.0,
|
||||||
|
min: float = -3.402823e+38,
|
||||||
|
max: float = 3.402823e+38,
|
||||||
|
soft_min: float = -3.402823e+38,
|
||||||
|
soft_max: float = 3.402823e+38,
|
||||||
|
step: int = 3,
|
||||||
|
precision: int = 2,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
unit: str = 'NONE',
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> 'bpy.types.FloatProperty':
|
||||||
|
"""Declares a new FloatProperty that has a Haxe counterpart with the
|
||||||
|
given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(FloatProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeFloatVectorProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default: list = (0.0, 0.0, 0.0),
|
||||||
|
min: float = 'sys.float_info.min',
|
||||||
|
max: float = 'sys.float_info.max',
|
||||||
|
soft_min: float = 'sys.float_info.min',
|
||||||
|
soft_max: float = 'sys.float_info.max',
|
||||||
|
step: int = 3,
|
||||||
|
precision: int = 2,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
unit: str = 'NONE',
|
||||||
|
size: int = 3,
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> list['bpy.types.FloatProperty']:
|
||||||
|
"""Declares a new FloatVectorProperty that has a Haxe counterpart
|
||||||
|
with the given prop_name (Python and Haxe names must be identical
|
||||||
|
for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(FloatVectorProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeIntProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default=0,
|
||||||
|
min: int = -2**31,
|
||||||
|
max: int = 2**31 - 1,
|
||||||
|
soft_min: int = -2**31,
|
||||||
|
soft_max: int = 2**31 - 1,
|
||||||
|
step: int = 1,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> 'bpy.types.IntProperty':
|
||||||
|
"""Declares a new IntProperty that has a Haxe counterpart with the
|
||||||
|
given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(IntProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeIntVectorProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default: list = (0, 0, 0),
|
||||||
|
min: int = -2**31,
|
||||||
|
max: int = 2**31 - 1,
|
||||||
|
soft_min: int = -2**31,
|
||||||
|
soft_max: int = 2**31 - 1,
|
||||||
|
step: int = 1,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
size: int = 3,
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> list['bpy.types.IntProperty']:
|
||||||
|
"""Declares a new IntVectorProperty that has a Haxe counterpart with
|
||||||
|
the given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(IntVectorProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def HaxePointerProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
type=None,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
poll=None,
|
||||||
|
update=None
|
||||||
|
) -> 'bpy.types.PointerProperty':
|
||||||
|
"""Declares a new PointerProperty that has a Haxe counterpart with
|
||||||
|
the given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(PointerProperty, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
def RemoveHaxeProperty(cls, attr: str):
|
||||||
|
RemoveProperty(cls, attr)
|
||||||
|
|
||||||
|
|
||||||
|
def HaxeStringProperty(
|
||||||
|
prop_name: str,
|
||||||
|
*,
|
||||||
|
name: str = "",
|
||||||
|
description: str = "",
|
||||||
|
default: str = "",
|
||||||
|
maxlen: int = 0,
|
||||||
|
options: set = {'ANIMATABLE'},
|
||||||
|
override: set = set(),
|
||||||
|
tags: set = set(),
|
||||||
|
subtype: str = 'NONE',
|
||||||
|
update=None,
|
||||||
|
get=None,
|
||||||
|
set=None
|
||||||
|
) -> 'bpy.types.StringProperty':
|
||||||
|
"""Declares a new StringProperty that has a Haxe counterpart with
|
||||||
|
the given prop_name (Python and Haxe names must be identical for now).
|
||||||
|
"""
|
||||||
|
return __haxe_prop(StringProperty, **locals())
|
|
@ -1,10 +1,14 @@
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.props import PointerProperty
|
from bpy.props import *
|
||||||
from bpy.types import NodeSocket
|
from bpy.types import NodeSocket
|
||||||
|
|
||||||
import arm.utils
|
import arm.utils
|
||||||
|
|
||||||
|
|
||||||
|
def _on_update_socket(self, context):
|
||||||
|
self.node.on_socket_val_update(context, self)
|
||||||
|
|
||||||
|
|
||||||
class ArmCustomSocket(NodeSocket):
|
class ArmCustomSocket(NodeSocket):
|
||||||
"""
|
"""
|
||||||
A custom socket that can be used to define more socket types for
|
A custom socket that can be used to define more socket types for
|
||||||
|
@ -41,7 +45,7 @@ class ArmAnimActionSocket(ArmCustomSocket):
|
||||||
arm_socket_type = 'STRING'
|
arm_socket_type = 'STRING'
|
||||||
|
|
||||||
default_value_get: PointerProperty(name='Action', type=bpy.types.Action) # legacy version of the line after this one
|
default_value_get: PointerProperty(name='Action', type=bpy.types.Action) # legacy version of the line after this one
|
||||||
default_value_raw: PointerProperty(name='Action', type=bpy.types.Action)
|
default_value_raw: PointerProperty(name='Action', type=bpy.types.Action, update=_on_update_socket)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -81,13 +85,114 @@ class ArmArraySocket(ArmCustomSocket):
|
||||||
return 0.8, 0.4, 0.0, 1
|
return 0.8, 0.4, 0.0, 1
|
||||||
|
|
||||||
|
|
||||||
|
class ArmBoolSocket(ArmCustomSocket):
|
||||||
|
bl_idname = 'ArmBoolSocket'
|
||||||
|
bl_label = 'Boolean Socket'
|
||||||
|
arm_socket_type = 'BOOLEAN'
|
||||||
|
|
||||||
|
default_value_raw: BoolProperty(
|
||||||
|
name='Value',
|
||||||
|
description='Input value used for unconnected socket',
|
||||||
|
update=_on_update_socket
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
draw_socket_layout(self, layout)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.8, 0.651, 0.839, 1
|
||||||
|
|
||||||
|
def get_default_value(self):
|
||||||
|
return self.default_value_raw
|
||||||
|
|
||||||
|
|
||||||
|
class ArmColorSocket(ArmCustomSocket):
|
||||||
|
bl_idname = 'ArmColorSocket'
|
||||||
|
bl_label = 'Color Socket'
|
||||||
|
arm_socket_type = 'RGBA'
|
||||||
|
|
||||||
|
default_value_raw: FloatVectorProperty(
|
||||||
|
name='Value',
|
||||||
|
size=4,
|
||||||
|
subtype='COLOR',
|
||||||
|
min=0.0,
|
||||||
|
max=1.0,
|
||||||
|
description='Input value used for unconnected socket',
|
||||||
|
update=_on_update_socket
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
draw_socket_layout(self, layout)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.78, 0.78, 0.161, 1
|
||||||
|
|
||||||
|
def get_default_value(self):
|
||||||
|
return self.default_value_raw
|
||||||
|
|
||||||
|
|
||||||
|
class ArmDynamicSocket(ArmCustomSocket):
|
||||||
|
bl_idname = 'ArmDynamicSocket'
|
||||||
|
bl_label = 'Dynamic Socket'
|
||||||
|
arm_socket_type = 'NONE'
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
layout.label(text=self.name)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.388, 0.78, 0.388, 1
|
||||||
|
|
||||||
|
|
||||||
|
class ArmFloatSocket(ArmCustomSocket):
|
||||||
|
bl_idname = 'ArmFloatSocket'
|
||||||
|
bl_label = 'Float Socket'
|
||||||
|
arm_socket_type = 'VALUE'
|
||||||
|
|
||||||
|
default_value_raw: FloatProperty(
|
||||||
|
name='Value',
|
||||||
|
description='Input value used for unconnected socket',
|
||||||
|
precision=3,
|
||||||
|
update=_on_update_socket
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
draw_socket_layout(self, layout)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.631, 0.631, 0.631, 1
|
||||||
|
|
||||||
|
def get_default_value(self):
|
||||||
|
return self.default_value_raw
|
||||||
|
|
||||||
|
|
||||||
|
class ArmIntSocket(ArmCustomSocket):
|
||||||
|
bl_idname = 'ArmIntSocket'
|
||||||
|
bl_label = 'Integer Socket'
|
||||||
|
arm_socket_type = 'INT'
|
||||||
|
|
||||||
|
default_value_raw: IntProperty(
|
||||||
|
name='Value',
|
||||||
|
description='Input value used for unconnected socket',
|
||||||
|
update=_on_update_socket
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
draw_socket_layout(self, layout)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.059, 0.522, 0.149, 1
|
||||||
|
|
||||||
|
def get_default_value(self):
|
||||||
|
return self.default_value_raw
|
||||||
|
|
||||||
|
|
||||||
class ArmObjectSocket(ArmCustomSocket):
|
class ArmObjectSocket(ArmCustomSocket):
|
||||||
bl_idname = 'ArmNodeSocketObject'
|
bl_idname = 'ArmNodeSocketObject'
|
||||||
bl_label = 'Object Socket'
|
bl_label = 'Object Socket'
|
||||||
arm_socket_type = 'OBJECT'
|
arm_socket_type = 'OBJECT'
|
||||||
|
|
||||||
default_value_get: PointerProperty(name='Object', type=bpy.types.Object) # legacy version of the line after this one
|
default_value_get: PointerProperty(name='Object', type=bpy.types.Object) # legacy version of the line after this one
|
||||||
default_value_raw: PointerProperty(name='Object', type=bpy.types.Object)
|
default_value_raw: PointerProperty(name='Object', type=bpy.types.Object, update=_on_update_socket)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -115,15 +220,82 @@ class ArmObjectSocket(ArmCustomSocket):
|
||||||
return 0.15, 0.55, 0.75, 1
|
return 0.15, 0.55, 0.75, 1
|
||||||
|
|
||||||
|
|
||||||
def register():
|
class ArmStringSocket(ArmCustomSocket):
|
||||||
bpy.utils.register_class(ArmActionSocket)
|
bl_idname = 'ArmStringSocket'
|
||||||
bpy.utils.register_class(ArmAnimActionSocket)
|
bl_label = 'String Socket'
|
||||||
bpy.utils.register_class(ArmArraySocket)
|
arm_socket_type = 'STRING'
|
||||||
bpy.utils.register_class(ArmObjectSocket)
|
|
||||||
|
default_value_raw: StringProperty(
|
||||||
|
name='Value',
|
||||||
|
description='Input value used for unconnected socket',
|
||||||
|
update=_on_update_socket
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
draw_socket_layout_split(self, layout)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.439, 0.698, 1, 1
|
||||||
|
|
||||||
|
def get_default_value(self):
|
||||||
|
return self.default_value_raw
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
class ArmVectorSocket(ArmCustomSocket):
|
||||||
bpy.utils.unregister_class(ArmObjectSocket)
|
bl_idname = 'ArmVectorSocket'
|
||||||
bpy.utils.unregister_class(ArmArraySocket)
|
bl_label = 'Vector Socket'
|
||||||
bpy.utils.unregister_class(ArmAnimActionSocket)
|
arm_socket_type = 'VECTOR'
|
||||||
bpy.utils.unregister_class(ArmActionSocket)
|
|
||||||
|
default_value_raw: FloatVectorProperty(
|
||||||
|
name='Value',
|
||||||
|
size=3,
|
||||||
|
description='Input value used for unconnected socket',
|
||||||
|
update=_on_update_socket
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw(self, context, layout, node, text):
|
||||||
|
if not self.is_output and not self.is_linked:
|
||||||
|
col = layout.column(align=True)
|
||||||
|
col.prop(self, 'default_value_raw', text='')
|
||||||
|
else:
|
||||||
|
layout.label(text=self.name)
|
||||||
|
|
||||||
|
def draw_color(self, context, node):
|
||||||
|
return 0.388, 0.388, 0.78, 1
|
||||||
|
|
||||||
|
def get_default_value(self):
|
||||||
|
return self.default_value_raw
|
||||||
|
|
||||||
|
|
||||||
|
def draw_socket_layout(socket: bpy.types.NodeSocket, layout: bpy.types.UILayout, prop_name='default_value_raw'):
|
||||||
|
if not socket.is_output and not socket.is_linked:
|
||||||
|
layout.prop(socket, prop_name, text=socket.name)
|
||||||
|
else:
|
||||||
|
layout.label(text=socket.name)
|
||||||
|
|
||||||
|
|
||||||
|
def draw_socket_layout_split(socket: bpy.types.NodeSocket, layout: bpy.types.UILayout, prop_name='default_value_raw'):
|
||||||
|
if not socket.is_output and not socket.is_linked:
|
||||||
|
# Blender layouts use 0.4 splits
|
||||||
|
layout = layout.split(factor=0.4, align=True)
|
||||||
|
|
||||||
|
layout.label(text=socket.name)
|
||||||
|
|
||||||
|
if not socket.is_output and not socket.is_linked:
|
||||||
|
layout.prop(socket, prop_name, text='')
|
||||||
|
|
||||||
|
|
||||||
|
REG_CLASSES = (
|
||||||
|
ArmActionSocket,
|
||||||
|
ArmAnimActionSocket,
|
||||||
|
ArmArraySocket,
|
||||||
|
ArmBoolSocket,
|
||||||
|
ArmColorSocket,
|
||||||
|
ArmDynamicSocket,
|
||||||
|
ArmFloatSocket,
|
||||||
|
ArmIntSocket,
|
||||||
|
ArmObjectSocket,
|
||||||
|
ArmStringSocket,
|
||||||
|
ArmVectorSocket,
|
||||||
|
)
|
||||||
|
register, unregister = bpy.utils.register_classes_factory(REG_CLASSES)
|
||||||
|
|
|
@ -10,17 +10,16 @@ class ArrayNode(ArmLogicTreeNode):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketShader'
|
op.socket_type = 'ArmDynamicSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,12 @@ class ArrayAddNode(ArmLogicTreeNode):
|
||||||
super(ArrayAddNode, self).__init__()
|
super(ArrayAddNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayAddNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketBool', 'Modify Original', default_value=True)
|
self.add_input('ArmBoolSocket', 'Modify Original', default_value=True)
|
||||||
self.add_input('NodeSocketBool', 'Unique Values')
|
self.add_input('ArmBoolSocket', 'Unique Values')
|
||||||
self.add_input('NodeSocketShader', 'Value')
|
self.add_input('ArmDynamicSocket', 'Value')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('ArmNodeSocketArray', 'Array')
|
self.add_output('ArmNodeSocketArray', 'Array')
|
||||||
|
@ -31,6 +30,6 @@ class ArrayAddNode(ArmLogicTreeNode):
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input_value', text='Add Input', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input_value', text='Add Input', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketShader'
|
op.socket_type = 'ArmDynamicSocket'
|
||||||
op2 = row.operator('arm.node_remove_input_value', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input_value', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
|
@ -11,17 +11,16 @@ class BooleanArrayNode(ArmLogicTreeNode):
|
||||||
super(BooleanArrayNode, self).__init__()
|
super(BooleanArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(BooleanArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketBool'
|
op.socket_type = 'ArmBoolSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -11,17 +11,16 @@ class ColorArrayNode(ArmLogicTreeNode):
|
||||||
super(ColorArrayNode, self).__init__()
|
super(ColorArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ColorArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketColor'
|
op.socket_type = 'ArmColorSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,8 @@ class ArrayContainsNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Contains'
|
bl_label = 'Array Contains'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayContainsNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketShader', 'Value')
|
self.add_input('ArmDynamicSocket', 'Value')
|
||||||
|
|
||||||
self.add_output('NodeSocketBool', 'Contains')
|
self.add_output('ArmBoolSocket', 'Contains')
|
||||||
|
|
|
@ -11,17 +11,16 @@ class FloatArrayNode(ArmLogicTreeNode):
|
||||||
super(FloatArrayNode, self).__init__()
|
super(FloatArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(FloatArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketFloat'
|
op.socket_type = 'ArmFloatSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,8 @@ class ArrayGetNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Get'
|
bl_label = 'Array Get'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayGetNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketInt', 'Index')
|
self.add_input('ArmIntSocket', 'Index')
|
||||||
|
|
||||||
self.add_output('NodeSocketShader', 'Value')
|
self.add_output('ArmDynamicSocket', 'Value')
|
||||||
|
|
|
@ -11,17 +11,16 @@ class IntegerArrayNode(ArmLogicTreeNode):
|
||||||
super(IntegerArrayNode, self).__init__()
|
super(IntegerArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(IntegerArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array')
|
self.add_output('ArmNodeSocketArray', 'Array')
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketInt'
|
op.socket_type = 'ArmIntSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,7 @@ class ArrayLengthNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Length'
|
bl_label = 'Array Length'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayLengthNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
|
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
|
@ -7,12 +7,11 @@ class ArrayLoopNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Loop'
|
bl_label = 'Array Loop'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayLoopNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Loop')
|
self.add_output('ArmNodeSocketAction', 'Loop')
|
||||||
self.add_output('NodeSocketShader', 'Value')
|
self.add_output('ArmDynamicSocket', 'Value')
|
||||||
self.add_output('NodeSocketInt', 'Index')
|
self.add_output('ArmIntSocket', 'Index')
|
||||||
self.add_output('ArmNodeSocketAction', 'Done')
|
self.add_output('ArmNodeSocketAction', 'Done')
|
||||||
|
|
|
@ -11,10 +11,9 @@ class ObjectArrayNode(ArmLogicTreeNode):
|
||||||
super(ObjectArrayNode, self).__init__()
|
super(ObjectArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ObjectArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
|
@ -8,8 +8,7 @@ class ArrayPopNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Pop'
|
bl_label = 'Array Pop'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayPopNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
|
|
||||||
self.add_output('NodeSocketShader', 'Value')
|
self.add_output('ArmDynamicSocket', 'Value')
|
||||||
|
|
|
@ -8,11 +8,10 @@ class ArrayRemoveIndexNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Remove by Index'
|
bl_label = 'Array Remove by Index'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayRemoveIndexNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketInt', 'Index')
|
self.add_input('ArmIntSocket', 'Index')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('NodeSocketShader', 'Value')
|
self.add_output('ArmDynamicSocket', 'Value')
|
||||||
|
|
|
@ -11,20 +11,19 @@ class ArrayRemoveValueNode(ArmLogicTreeNode):
|
||||||
# def __init__(self):
|
# def __init__(self):
|
||||||
# array_nodes[str(id(self))] = self
|
# array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayRemoveValueNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketShader', 'Value')
|
self.add_input('ArmDynamicSocket', 'Value')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('NodeSocketShader', 'Value')
|
self.add_output('ArmDynamicSocket', 'Value')
|
||||||
|
|
||||||
# def draw_buttons(self, context, layout):
|
# def draw_buttons(self, context, layout):
|
||||||
# row = layout.row(align=True)
|
# row = layout.row(align=True)
|
||||||
|
|
||||||
# op = row.operator('arm.node_add_input_value', text='New', icon='PLUS', emboss=True)
|
# op = row.operator('arm.node_add_input_value', text='New', icon='PLUS', emboss=True)
|
||||||
# op.node_index = str(id(self))
|
# op.node_index = str(id(self))
|
||||||
# op.socket_type = 'NodeSocketShader'
|
# op.socket_type = 'ArmDynamicSocket'
|
||||||
# op2 = row.operator('arm.node_remove_input_value', text='', icon='X', emboss=True)
|
# op2 = row.operator('arm.node_remove_input_value', text='', icon='X', emboss=True)
|
||||||
# op2.node_index = str(id(self))
|
# op2.node_index = str(id(self))
|
||||||
|
|
|
@ -6,11 +6,10 @@ class ArraySetNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Set'
|
bl_label = 'Array Set'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArraySetNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketInt', 'Index')
|
self.add_input('ArmIntSocket', 'Index')
|
||||||
self.add_input('NodeSocketShader', 'Value')
|
self.add_input('ArmDynamicSocket', 'Value')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -8,8 +8,7 @@ class ArrayShiftNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Shift'
|
bl_label = 'Array Shift'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArrayShiftNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
|
|
||||||
self.add_output('NodeSocketShader', 'Value')
|
self.add_output('ArmDynamicSocket', 'Value')
|
||||||
|
|
|
@ -8,10 +8,9 @@ class ArraySliceNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Slice'
|
bl_label = 'Array Slice'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArraySliceNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketInt', 'Index')
|
self.add_input('ArmIntSocket', 'Index')
|
||||||
self.add_input('NodeSocketInt', 'End')
|
self.add_input('ArmIntSocket', 'End')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array')
|
self.add_output('ArmNodeSocketArray', 'Array')
|
||||||
|
|
|
@ -8,11 +8,10 @@ class ArraySpliceNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Array Splice'
|
bl_label = 'Array Splice'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ArraySpliceNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketArray', 'Array')
|
self.add_input('ArmNodeSocketArray', 'Array')
|
||||||
self.add_input('NodeSocketInt', 'Index')
|
self.add_input('ArmIntSocket', 'Index')
|
||||||
self.add_input('NodeSocketInt', 'Length')
|
self.add_input('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -11,17 +11,16 @@ class StringArrayNode(ArmLogicTreeNode):
|
||||||
super(StringArrayNode, self).__init__()
|
super(StringArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(StringArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketString'
|
op.socket_type = 'ArmStringSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -11,17 +11,16 @@ class VectorArrayNode(ArmLogicTreeNode):
|
||||||
super(VectorArrayNode, self).__init__()
|
super(VectorArrayNode, self).__init__()
|
||||||
array_nodes[str(id(self))] = self
|
array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(VectorArrayNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
self.add_output('ArmNodeSocketArray', 'Array', is_var=True)
|
||||||
self.add_output('NodeSocketInt', 'Length')
|
self.add_output('ArmIntSocket', 'Length')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|
||||||
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
op = row.operator('arm.node_add_input', text='New', icon='PLUS', emboss=True)
|
||||||
op.node_index = str(id(self))
|
op.node_index = str(id(self))
|
||||||
op.socket_type = 'NodeSocketVector'
|
op.socket_type = 'ArmVectorSocket'
|
||||||
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
op2 = row.operator('arm.node_remove_input', text='', icon='X', emboss=True)
|
||||||
op2.node_index = str(id(self))
|
op2.node_index = str(id(self))
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,5 @@ class ActiveCameraNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Camera Active'
|
bl_label = 'Get Camera Active'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ActiveCameraNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketObject', 'Camera')
|
self.add_output('ArmNodeSocketObject', 'Camera')
|
||||||
|
|
|
@ -8,8 +8,7 @@ class GetCameraFovNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Camera FOV'
|
bl_label = 'Get Camera FOV'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(GetCameraFovNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
|
|
||||||
self.add_output('NodeSocketFloat', 'FOV')
|
self.add_output('ArmFloatSocket', 'FOV')
|
||||||
|
|
|
@ -8,8 +8,7 @@ class SetCameraNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Camera Active'
|
bl_label = 'Set Camera Active'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetCameraNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Camera')
|
self.add_input('ArmNodeSocketObject', 'Camera')
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,9 @@ class SetCameraFovNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Camera FOV'
|
bl_label = 'Set Camera FOV'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetCameraFovNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Camera')
|
self.add_input('ArmNodeSocketObject', 'Camera')
|
||||||
self.add_input('NodeSocketFloat', 'FOV', default_value=0.9)
|
self.add_input('ArmFloatSocket', 'FOV', default_value=0.9)
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,8 +6,7 @@ class CanvasGetCheckboxNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Checkbox'
|
bl_label = 'Get Canvas Checkbox'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetCheckboxNode, self).init(context)
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
|
||||||
|
|
||||||
self.add_output('NodeSocketBool', 'Is Checked')
|
self.add_output('ArmBoolSocket', 'Is Checked')
|
||||||
|
|
|
@ -6,8 +6,7 @@ class CanvasGetInputTextNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Input Text'
|
bl_label = 'Get Canvas Input Text'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetInputTextNode, self).init(context)
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
|
||||||
|
|
||||||
self.add_output('NodeSocketString', 'Text')
|
self.add_output('ArmStringSocket', 'Text')
|
||||||
|
|
|
@ -6,11 +6,10 @@ class CanvasGetLocationNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Location'
|
bl_label = 'Get Canvas Location'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetLocationNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('NodeSocketInt', 'X')
|
self.add_output('ArmIntSocket', 'X')
|
||||||
self.add_output('NodeSocketInt', 'Y')
|
self.add_output('ArmIntSocket', 'Y')
|
||||||
|
|
|
@ -6,8 +6,7 @@ class CanvasGetPositionNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Position'
|
bl_label = 'Get Canvas Position'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetPositionNode, self).init(context)
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
|
||||||
|
|
||||||
self.add_output('NodeSocketInt', 'Position')
|
self.add_output('ArmIntSocket', 'Position')
|
||||||
|
|
|
@ -6,11 +6,10 @@ class CanvasGetPBNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Progress Bar'
|
bl_label = 'Get Canvas Progress Bar'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetPBNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('NodeSocketInt', 'At')
|
self.add_output('ArmIntSocket', 'At')
|
||||||
self.add_output('NodeSocketInt', 'Max')
|
self.add_output('ArmIntSocket', 'Max')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasGetRotationNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Rotation'
|
bl_label = 'Get Canvas Rotation'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetRotationNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('NodeSocketFloat', 'Rad')
|
self.add_output('ArmFloatSocket', 'Rad')
|
||||||
|
|
|
@ -6,11 +6,10 @@ class CanvasGetScaleNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Scale'
|
bl_label = 'Get Canvas Scale'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetScaleNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('NodeSocketInt', 'Height')
|
self.add_output('ArmIntSocket', 'Height')
|
||||||
self.add_output('NodeSocketInt', 'Width')
|
self.add_output('ArmIntSocket', 'Width')
|
||||||
|
|
|
@ -6,8 +6,7 @@ class CanvasGetSliderNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Slider'
|
bl_label = 'Get Canvas Slider'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetSliderNode, self).init(context)
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
|
||||||
|
|
||||||
self.add_output('NodeSocketFloat', 'Float')
|
self.add_output('ArmFloatSocket', 'Float')
|
||||||
|
|
|
@ -9,8 +9,7 @@ class CanvasGetVisibleNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Get Canvas Visible'
|
bl_label = 'Get Canvas Visible'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasGetVisibleNode, self).init(context)
|
self.inputs.new('ArmStringSocket', 'Element')
|
||||||
self.inputs.new('NodeSocketString', 'Element')
|
|
||||||
|
|
||||||
self.outputs.new('NodeSocketBool', 'Is Visible')
|
self.outputs.new('ArmBoolSocket', 'Is Visible')
|
||||||
|
|
|
@ -6,24 +6,26 @@ class OnCanvasElementNode(ArmLogicTreeNode):
|
||||||
bl_label = 'On Canvas Element'
|
bl_label = 'On Canvas Element'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
property0: EnumProperty(
|
property0: HaxeEnumProperty(
|
||||||
|
'property0',
|
||||||
items=[('click', 'Click', 'Listen to mouse clicks'),
|
items=[('click', 'Click', 'Listen to mouse clicks'),
|
||||||
('hover', 'Hover', 'Listen to mouse hover')],
|
('hover', 'Hover', 'Listen to mouse hover')],
|
||||||
name='Listen to', default='click')
|
name='Listen to', default='click')
|
||||||
property1: EnumProperty(
|
property1: HaxeEnumProperty(
|
||||||
|
'property1',
|
||||||
items=[('started', 'Started', 'Started'),
|
items=[('started', 'Started', 'Started'),
|
||||||
('down', 'Down', 'Down'),
|
('down', 'Down', 'Down'),
|
||||||
('released', 'Released', 'Released')],
|
('released', 'Released', 'Released')],
|
||||||
name='Status', default='started')
|
name='Status', default='started')
|
||||||
property2: EnumProperty(
|
property2: HaxeEnumProperty(
|
||||||
|
'property2',
|
||||||
items=[('left', 'Left', 'Left mouse button'),
|
items=[('left', 'Left', 'Left mouse button'),
|
||||||
('middle', 'Middle', 'Middle mouse button'),
|
('middle', 'Middle', 'Middle mouse button'),
|
||||||
('right', 'Right', 'Right mouse button')],
|
('right', 'Right', 'Right mouse button')],
|
||||||
name='Mouse Button', default='left')
|
name='Mouse Button', default='left')
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnCanvasElementNode, self).init(context)
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasSetAssetNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Asset'
|
bl_label = 'Set Canvas Asset'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetAssetNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Asset')
|
self.add_input('ArmStringSocket', 'Asset')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasSetCheckBoxNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Checkbox'
|
bl_label = 'Set Canvas Checkbox'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetCheckBoxNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketBool', 'Check')
|
self.add_input('ArmBoolSocket', 'Check')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,11 +6,10 @@ class CanvasSetLocationNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Location'
|
bl_label = 'Set Canvas Location'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetLocationNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketFloat', 'X')
|
self.add_input('ArmFloatSocket', 'X')
|
||||||
self.add_input('NodeSocketFloat', 'Y')
|
self.add_input('ArmFloatSocket', 'Y')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,11 +6,10 @@ class CanvasSetPBNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Progress Bar'
|
bl_label = 'Set Canvas Progress Bar'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetPBNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketInt', 'At')
|
self.add_input('ArmIntSocket', 'At')
|
||||||
self.add_input('NodeSocketInt', 'Max')
|
self.add_input('ArmIntSocket', 'Max')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasSetRotationNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Rotation'
|
bl_label = 'Set Canvas Rotation'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetRotationNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketFloat', 'Rad')
|
self.add_input('ArmFloatSocket', 'Rad')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,11 +6,10 @@ class CanvasSetScaleNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Scale'
|
bl_label = 'Set Canvas Scale'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetScaleNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketInt', 'Height')
|
self.add_input('ArmIntSocket', 'Height')
|
||||||
self.add_input('NodeSocketInt', 'Width')
|
self.add_input('ArmIntSocket', 'Width')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasSetSliderNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Slider'
|
bl_label = 'Set Canvas Slider'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetSliderNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketFloat', 'Float')
|
self.add_input('ArmFloatSocket', 'Float')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasSetTextNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Text'
|
bl_label = 'Set Canvas Text'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetTextNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketString', 'Text')
|
self.add_input('ArmStringSocket', 'Text')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,13 +6,12 @@ class CanvasSetTextColorNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Text Color'
|
bl_label = 'Set Canvas Text Color'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetTextColorNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketFloat', 'R')
|
self.add_input('ArmFloatSocket', 'R')
|
||||||
self.add_input('NodeSocketFloat', 'G')
|
self.add_input('ArmFloatSocket', 'G')
|
||||||
self.add_input('NodeSocketFloat', 'B')
|
self.add_input('ArmFloatSocket', 'B')
|
||||||
self.add_input('NodeSocketFloat', 'A')
|
self.add_input('ArmFloatSocket', 'A')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -6,10 +6,9 @@ class CanvasSetVisibleNode(ArmLogicTreeNode):
|
||||||
bl_label = 'Set Canvas Visible'
|
bl_label = 'Set Canvas Visible'
|
||||||
arm_version = 1
|
arm_version = 1
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(CanvasSetVisibleNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketString', 'Element')
|
self.add_input('ArmStringSocket', 'Element')
|
||||||
self.add_input('NodeSocketBool', 'Visible')
|
self.add_input('ArmBoolSocket', 'Visible')
|
||||||
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -14,9 +14,8 @@ class GetMouseLockNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Input'
|
arm_category = 'Input'
|
||||||
arm_section = 'mouse'
|
arm_section = 'mouse'
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(GetMouseLockNode, self).init(context)
|
self.outputs.new('ArmBoolSocket', 'Is Locked')
|
||||||
self.outputs.new('NodeSocketBool', 'Is Locked')
|
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
if self.arm_version not in (0, 1):
|
if self.arm_version not in (0, 1):
|
||||||
|
|
|
@ -14,9 +14,8 @@ class GetMouseVisibleNode(ArmLogicTreeNode):
|
||||||
arm_section = 'mouse'
|
arm_section = 'mouse'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(GetMouseVisibleNode, self).init(context)
|
self.outputs.new('ArmBoolSocket', 'Is Visible')
|
||||||
self.outputs.new('NodeSocketBool', 'Is Visible')
|
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
if self.arm_version not in (0, 1):
|
if self.arm_version not in (0, 1):
|
||||||
|
|
|
@ -11,11 +11,10 @@ class MouseCoordsNode(ArmLogicTreeNode):
|
||||||
arm_section = 'mouse'
|
arm_section = 'mouse'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(MouseCoordsNode, self).init(context)
|
self.add_output('ArmVectorSocket', 'Coords')
|
||||||
self.add_output('NodeSocketVector', 'Coords')
|
self.add_output('ArmVectorSocket', 'Movement')
|
||||||
self.add_output('NodeSocketVector', 'Movement')
|
self.add_output('ArmIntSocket', 'Wheel')
|
||||||
self.add_output('NodeSocketInt', 'Wheel')
|
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
if self.arm_version not in (0, 1):
|
if self.arm_version not in (0, 1):
|
||||||
|
|
|
@ -11,7 +11,8 @@ class OnGamepadNode(ArmLogicTreeNode):
|
||||||
arm_section = 'gamepad'
|
arm_section = 'gamepad'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
property0: EnumProperty(
|
property0: HaxeEnumProperty(
|
||||||
|
'property0',
|
||||||
items = [('Down', 'Down', 'Down'),
|
items = [('Down', 'Down', 'Down'),
|
||||||
('Started', 'Started', 'Started'),
|
('Started', 'Started', 'Started'),
|
||||||
('Released', 'Released', 'Released')],
|
('Released', 'Released', 'Released')],
|
||||||
|
@ -19,7 +20,8 @@ class OnGamepadNode(ArmLogicTreeNode):
|
||||||
# ('Moved Right', 'Moved Right', 'Moved Right'),],
|
# ('Moved Right', 'Moved Right', 'Moved Right'),],
|
||||||
name='', default='Started')
|
name='', default='Started')
|
||||||
|
|
||||||
property1: EnumProperty(
|
property1: HaxeEnumProperty(
|
||||||
|
'property1',
|
||||||
items = [('cross', 'cross / a', 'cross / a'),
|
items = [('cross', 'cross / a', 'cross / a'),
|
||||||
('circle', 'circle / b', 'circle / b'),
|
('circle', 'circle / b', 'circle / b'),
|
||||||
('square', 'square / x', 'square / x'),
|
('square', 'square / x', 'square / x'),
|
||||||
|
@ -40,10 +42,9 @@ class OnGamepadNode(ArmLogicTreeNode):
|
||||||
('touchpad', 'touchpad', 'touchpad'),],
|
('touchpad', 'touchpad', 'touchpad'),],
|
||||||
name='', default='cross')
|
name='', default='cross')
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnGamepadNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_input('NodeSocketInt', 'Gamepad')
|
self.add_input('ArmIntSocket', 'Gamepad')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
layout.prop(self, 'property0')
|
layout.prop(self, 'property0')
|
||||||
|
|
|
@ -11,13 +11,15 @@ class OnKeyboardNode(ArmLogicTreeNode):
|
||||||
arm_section = 'keyboard'
|
arm_section = 'keyboard'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
property0: EnumProperty(
|
property0: HaxeEnumProperty(
|
||||||
|
'property0',
|
||||||
items = [('Down', 'Down', 'Down'),
|
items = [('Down', 'Down', 'Down'),
|
||||||
('Started', 'Started', 'Started'),
|
('Started', 'Started', 'Started'),
|
||||||
('Released', 'Released', 'Released')],
|
('Released', 'Released', 'Released')],
|
||||||
name='', default='Started')
|
name='', default='Started')
|
||||||
|
|
||||||
property1: EnumProperty(
|
property1: HaxeEnumProperty(
|
||||||
|
'property1',
|
||||||
items = [('a', 'a', 'a'),
|
items = [('a', 'a', 'a'),
|
||||||
('b', 'b', 'b'),
|
('b', 'b', 'b'),
|
||||||
('c', 'c', 'c'),
|
('c', 'c', 'c'),
|
||||||
|
@ -72,8 +74,7 @@ class OnKeyboardNode(ArmLogicTreeNode):
|
||||||
('down', 'down', 'down'),],
|
('down', 'down', 'down'),],
|
||||||
name='', default='space')
|
name='', default='space')
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnKeyboardNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
@ -11,20 +11,21 @@ class OnMouseNode(ArmLogicTreeNode):
|
||||||
arm_section = 'mouse'
|
arm_section = 'mouse'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
property0: EnumProperty(
|
property0: HaxeEnumProperty(
|
||||||
|
'property0',
|
||||||
items = [('Down', 'Down', 'Down'),
|
items = [('Down', 'Down', 'Down'),
|
||||||
('Started', 'Started', 'Started'),
|
('Started', 'Started', 'Started'),
|
||||||
('Released', 'Released', 'Released'),
|
('Released', 'Released', 'Released'),
|
||||||
('Moved', 'Moved', 'Moved')],
|
('Moved', 'Moved', 'Moved')],
|
||||||
name='', default='Down')
|
name='', default='Down')
|
||||||
property1: EnumProperty(
|
property1: HaxeEnumProperty(
|
||||||
|
'property1',
|
||||||
items = [('left', 'left', 'left'),
|
items = [('left', 'left', 'left'),
|
||||||
('right', 'right', 'right'),
|
('right', 'right', 'right'),
|
||||||
('middle', 'middle', 'middle')],
|
('middle', 'middle', 'middle')],
|
||||||
name='', default='left')
|
name='', default='left')
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnMouseNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
@ -11,15 +11,15 @@ class OnSurfaceNode(ArmLogicTreeNode):
|
||||||
arm_section = 'surface'
|
arm_section = 'surface'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
property0: EnumProperty(
|
property0: HaxeEnumProperty(
|
||||||
|
'property0',
|
||||||
items = [('Touched', 'Touched', 'Touched'),
|
items = [('Touched', 'Touched', 'Touched'),
|
||||||
('Started', 'Started', 'Started'),
|
('Started', 'Started', 'Started'),
|
||||||
('Released', 'Released', 'Released'),
|
('Released', 'Released', 'Released'),
|
||||||
('Moved', 'Moved', 'Moved')],
|
('Moved', 'Moved', 'Moved')],
|
||||||
name='', default='Touched')
|
name='', default='Touched')
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnSurfaceNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
@ -11,15 +11,15 @@ class OnVirtualButtonNode(ArmLogicTreeNode):
|
||||||
arm_section = 'virtual'
|
arm_section = 'virtual'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
property0: EnumProperty(
|
property0: HaxeEnumProperty(
|
||||||
|
'property0',
|
||||||
items = [('Down', 'Down', 'Down'),
|
items = [('Down', 'Down', 'Down'),
|
||||||
('Started', 'Started', 'Started'),
|
('Started', 'Started', 'Started'),
|
||||||
('Released', 'Released', 'Released')],
|
('Released', 'Released', 'Released')],
|
||||||
name='', default='Started')
|
name='', default='Started')
|
||||||
property1: StringProperty(name='', default='button')
|
property1: HaxeStringProperty('property1', name='', default='button')
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(OnVirtualButtonNode, self).init(context)
|
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
@ -10,8 +10,7 @@ class PauseActionNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Animation'
|
arm_category = 'Animation'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(PauseActionNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -11,8 +11,7 @@ class PauseTilesheetNode(ArmLogicTreeNode):
|
||||||
arm_section = 'tilesheet'
|
arm_section = 'tilesheet'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(PauseTilesheetNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -10,8 +10,7 @@ class PauseTraitNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Trait'
|
arm_category = 'Trait'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(PauseTraitNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketShader', 'Trait')
|
self.add_input('ArmDynamicSocket', 'Trait')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -10,11 +10,10 @@ class PlayActionNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Animation'
|
arm_category = 'Animation'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(PlayActionNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('ArmNodeSocketAnimAction', 'Action')
|
self.add_input('ArmNodeSocketAnimAction', 'Action')
|
||||||
self.add_input('NodeSocketFloat', 'Blend', default_value=0.2)
|
self.add_input('ArmFloatSocket', 'Blend', default_value=0.2)
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
self.add_output('ArmNodeSocketAction', 'Done')
|
self.add_output('ArmNodeSocketAction', 'Done')
|
||||||
|
|
|
@ -10,8 +10,7 @@ class ResumeActionNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Animation'
|
arm_category = 'Animation'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ResumeActionNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -10,8 +10,7 @@ class ResumeTilesheetNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Animation'
|
arm_category = 'Animation'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ResumeTilesheetNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -10,8 +10,7 @@ class ResumeTraitNode(ArmLogicTreeNode):
|
||||||
arm_category = 'Trait'
|
arm_category = 'Trait'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ResumeTraitNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketShader', 'Trait')
|
self.add_input('ArmDynamicSocket', 'Trait')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -11,12 +11,11 @@ class RotateObjectAroundAxisNode(ArmLogicTreeNode):
|
||||||
arm_section = 'rotation'
|
arm_section = 'rotation'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(RotateObjectAroundAxisNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketVector', 'Axis', default_value=[0, 0, 1])
|
self.add_input('ArmVectorSocket', 'Axis', default_value=[0, 0, 1])
|
||||||
self.add_input('NodeSocketFloat', 'Angle')
|
self.add_input('ArmFloatSocket', 'Angle')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
|
|
|
@ -11,9 +11,8 @@ class ScaleObjectNode(ArmLogicTreeNode):
|
||||||
arm_section = 'scale'
|
arm_section = 'scale'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ScaleObjectNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('ArmNodeSocketObject', 'Object')
|
self.add_input('ArmNodeSocketObject', 'Object')
|
||||||
self.add_input('NodeSocketVector', 'Scale')
|
self.add_input('ArmVectorSocket', 'Scale')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
|
@ -11,10 +11,9 @@ class SetMouseLockNode(ArmLogicTreeNode):
|
||||||
arm_section = 'mouse'
|
arm_section = 'mouse'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(SetMouseLockNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketBool', 'Lock')
|
self.add_input('ArmBoolSocket', 'Lock')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
|
|
|
@ -11,10 +11,9 @@ class ShowMouseNode(ArmLogicTreeNode):
|
||||||
arm_section = 'mouse'
|
arm_section = 'mouse'
|
||||||
arm_version = 2
|
arm_version = 2
|
||||||
|
|
||||||
def init(self, context):
|
def arm_init(self, context):
|
||||||
super(ShowMouseNode, self).init(context)
|
|
||||||
self.add_input('ArmNodeSocketAction', 'In')
|
self.add_input('ArmNodeSocketAction', 'In')
|
||||||
self.add_input('NodeSocketBool', 'Show')
|
self.add_input('ArmBoolSocket', 'Show')
|
||||||
self.add_output('ArmNodeSocketAction', 'Out')
|
self.add_output('ArmNodeSocketAction', 'Out')
|
||||||
|
|
||||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue