Live patch: add support for node property updates
This commit is contained in:
parent
202138304a
commit
4387d774cc
|
@ -9,7 +9,7 @@ import armory.trait.physics.RigidBody;
|
|||
class AddRigidBodyNode extends LogicNode {
|
||||
|
||||
public var property0: String;//Shape
|
||||
public var property1: String;//Advanced
|
||||
public var property1: Bool;//Advanced
|
||||
public var object: Object;
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
|
@ -38,8 +38,7 @@ class AddRigidBodyNode extends LogicNode {
|
|||
|
||||
var shape: Shape = 1;
|
||||
|
||||
if(property1 == 'true')
|
||||
{
|
||||
if (property1) {
|
||||
margin = inputs[9].get();
|
||||
marginLen = inputs[10].get();
|
||||
linDamp = inputs[11].get();
|
||||
|
@ -49,34 +48,29 @@ class AddRigidBodyNode extends LogicNode {
|
|||
angVelThreshold = inputs[15].get();
|
||||
group = inputs[16].get();
|
||||
mask = inputs[17].get();
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (object == null) return;
|
||||
|
||||
#if arm_physics
|
||||
var rb: RigidBody = object.getTrait(RigidBody);
|
||||
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(rb == null)
|
||||
{
|
||||
|
||||
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 (rb == null) {
|
||||
switch (property0){
|
||||
|
||||
case 'Box':
|
||||
case "Box":
|
||||
shape = Box;
|
||||
case 'Sphere':
|
||||
case "Sphere":
|
||||
shape = Sphere;
|
||||
case 'Capsule':
|
||||
case "Capsule":
|
||||
shape = Capsule;
|
||||
case 'Cone':
|
||||
case "Cone":
|
||||
shape = Cone;
|
||||
case 'Cylinder':
|
||||
case "Cylinder":
|
||||
shape = Cylinder;
|
||||
case 'Convex Hull':
|
||||
case "Convex Hull":
|
||||
shape = ConvexHull;
|
||||
case 'Mesh':
|
||||
case "Mesh":
|
||||
shape = Mesh;
|
||||
}
|
||||
|
||||
|
@ -84,15 +78,14 @@ class AddRigidBodyNode extends LogicNode {
|
|||
rb.animated = animated;
|
||||
rb.staticObj = ! active;
|
||||
rb.isTriggerObject(trigger);
|
||||
if(property1 == 'true')
|
||||
{
|
||||
|
||||
if (property1) {
|
||||
rb.linearDamping = linDamp;
|
||||
rb.angularDamping = angDamp;
|
||||
if(margin) rb.collisionMargin = marginLen;
|
||||
if(useDeactiv) {
|
||||
if (margin) rb.collisionMargin = marginLen;
|
||||
if (useDeactiv) {
|
||||
rb.setUpDeactivation(true, linearVelThreshold, angVelThreshold, 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object.addTrait(rb);
|
||||
|
|
|
@ -3,7 +3,7 @@ package armory.logicnode;
|
|||
class MathNode extends LogicNode {
|
||||
|
||||
public var property0: String; // Operation
|
||||
public var property1: String; // Clamp
|
||||
public var property1: Bool; // Clamp
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
|
@ -80,8 +80,8 @@ class MathNode extends LogicNode {
|
|||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ class MixNode extends LogicNode {
|
|||
|
||||
public var property0: String; // Type
|
||||
public var property1: String; // Ease
|
||||
public var property2: String; // Clamp
|
||||
public var property2: Bool; // Clamp
|
||||
|
||||
var ease: Float->Float = null;
|
||||
|
||||
|
@ -50,7 +50,9 @@ class MixNode extends LogicNode {
|
|||
var v2: Float = inputs[2].get();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@ package armory.logicnode;
|
|||
#if arm_physics
|
||||
import armory.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
|
||||
#end
|
||||
import iron.object.Object;
|
||||
|
||||
class PhysicsConstraintNode extends LogicNode {
|
||||
|
||||
public var property0: String;//Linear or Angular
|
||||
public var property1: String;//Axis
|
||||
public var property2: String;//Is a spring
|
||||
public var value1: Float;//Lower limit or Spring Stiffness
|
||||
public var value2: Float;//Upper limit or Spring Damping
|
||||
public var property0: String; //Linear or Angular
|
||||
public var property1: String; //Axis
|
||||
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
|
||||
public var isAngular: Bool;
|
||||
public var axis: ConstraintAxis;
|
||||
public var isSpring: Bool;
|
||||
|
@ -24,27 +23,13 @@ class PhysicsConstraintNode extends LogicNode {
|
|||
value1 = inputs[0].get();
|
||||
value2 = inputs[1].get();
|
||||
|
||||
if(property0 == 'Linear') {
|
||||
isAngular = false;
|
||||
}
|
||||
else{
|
||||
isAngular = true;
|
||||
}
|
||||
|
||||
if(property2 == 'true'){
|
||||
isSpring = true;
|
||||
}
|
||||
else {
|
||||
isSpring = false;
|
||||
}
|
||||
isAngular = property0 != "Linear";
|
||||
isSpring = property2;
|
||||
|
||||
switch (property1){
|
||||
case 'X':
|
||||
axis = X;
|
||||
case 'Y':
|
||||
axis = Y;
|
||||
case 'Z':
|
||||
axis = Z;
|
||||
case "X": axis = X;
|
||||
case "Y": axis = Y;
|
||||
case "Z": axis = Z;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -7,7 +7,7 @@ class VectorMixNode extends LogicNode {
|
|||
|
||||
public var property0: String; // Type
|
||||
public var property1: String; // Ease
|
||||
public var property2: String; // Clamp
|
||||
public var property2: Bool; // Clamp
|
||||
|
||||
var v = new Vec4();
|
||||
|
||||
|
@ -57,7 +57,7 @@ class VectorMixNode extends LogicNode {
|
|||
v.y = v1.y + (v2.y - v1.y) * 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,5 +45,15 @@ class LivePatch extends iron.Trait {
|
|||
}
|
||||
toNode.inputs[toIndex] = new LogicNodeInput(fromNode, fromIndex);
|
||||
}
|
||||
|
||||
public static function patchUpdateNodeProp(treeName: String, nodeName: String, propName: String, value: Dynamic) {
|
||||
var tree = LogicTree.nodeTrees[treeName];
|
||||
if (tree == null) return;
|
||||
|
||||
var node = tree.nodes[nodeName];
|
||||
if (node == null) return;
|
||||
|
||||
Reflect.setField(node, propName, value);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
|
|
@ -153,8 +153,7 @@ def send_event(event_id: str, opt_data: Any = None):
|
|||
# This event is called twice for a connection but we only need
|
||||
# send it once
|
||||
if node == link.from_node:
|
||||
node_tree = node.get_tree()
|
||||
tree_name = arm.node_utils.get_export_tree_name(node_tree)
|
||||
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
|
||||
|
@ -167,6 +166,18 @@ def send_event(event_id: str, opt_data: Any = None):
|
|||
js = f'LivePatch.patchCreateNodeLink("{tree_name}", "{from_node_name}", "{to_node_name}", "{from_index}", "{to_index}");'
|
||||
write_patch(js)
|
||||
|
||||
if 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(node, prop_name)
|
||||
|
||||
js = f'LivePatch.patchUpdateNodeProp("{tree_name}", "{node_name}", "{prop_name}", {value});'
|
||||
write_patch(js)
|
||||
|
||||
|
||||
def on_operator(operator_id: str):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import itertools
|
||||
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
|
||||
|
||||
import bpy.types
|
||||
|
@ -8,7 +8,9 @@ from bpy.props import *
|
|||
from nodeitems_utils import NodeItem
|
||||
|
||||
import arm # we cannot import arm.livepatch here or we have a circular import
|
||||
# Pass NodeReplacement forward to individual node modules that import arm_nodes
|
||||
# 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
|
||||
import arm.node_utils
|
||||
|
||||
|
@ -52,6 +54,13 @@ class ArmLogicTreeNode(bpy.types.Node):
|
|||
def get_tree(self):
|
||||
return self.id_data
|
||||
|
||||
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 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))
|
||||
|
|
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 *
|
||||
|
||||
# Property parameter name `set` shadows built-in type `set`
|
||||
__set = set
|
||||
|
||||
|
||||
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 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 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 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 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 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 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 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 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 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 counterpart with the
|
||||
given prop_name (Python and Haxe names must be identical for now).
|
||||
"""
|
||||
return __haxe_prop(StringProperty, **locals())
|
|
@ -6,16 +6,19 @@ class OnCanvasElementNode(ArmLogicTreeNode):
|
|||
bl_label = 'On Canvas Element'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items=[('click', 'Click', 'Listen to mouse clicks'),
|
||||
('hover', 'Hover', 'Listen to mouse hover')],
|
||||
name='Listen to', default='click')
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items=[('started', 'Started', 'Started'),
|
||||
('down', 'Down', 'Down'),
|
||||
('released', 'Released', 'Released')],
|
||||
name='Status', default='started')
|
||||
property2: EnumProperty(
|
||||
property2: HaxeEnumProperty(
|
||||
'property2',
|
||||
items=[('left', 'Left', 'Left mouse button'),
|
||||
('middle', 'Middle', 'Middle mouse button'),
|
||||
('right', 'Right', 'Right mouse button')],
|
||||
|
|
|
@ -11,7 +11,8 @@ class OnGamepadNode(ArmLogicTreeNode):
|
|||
arm_section = 'gamepad'
|
||||
arm_version = 2
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Down', 'Down', 'Down'),
|
||||
('Started', 'Started', 'Started'),
|
||||
('Released', 'Released', 'Released')],
|
||||
|
@ -19,7 +20,8 @@ class OnGamepadNode(ArmLogicTreeNode):
|
|||
# ('Moved Right', 'Moved Right', 'Moved Right'),],
|
||||
name='', default='Started')
|
||||
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('cross', 'cross / a', 'cross / a'),
|
||||
('circle', 'circle / b', 'circle / b'),
|
||||
('square', 'square / x', 'square / x'),
|
||||
|
|
|
@ -11,13 +11,15 @@ class OnKeyboardNode(ArmLogicTreeNode):
|
|||
arm_section = 'keyboard'
|
||||
arm_version = 2
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Down', 'Down', 'Down'),
|
||||
('Started', 'Started', 'Started'),
|
||||
('Released', 'Released', 'Released')],
|
||||
name='', default='Started')
|
||||
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('a', 'a', 'a'),
|
||||
('b', 'b', 'b'),
|
||||
('c', 'c', 'c'),
|
||||
|
|
|
@ -11,13 +11,15 @@ class OnMouseNode(ArmLogicTreeNode):
|
|||
arm_section = 'mouse'
|
||||
arm_version = 2
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Down', 'Down', 'Down'),
|
||||
('Started', 'Started', 'Started'),
|
||||
('Released', 'Released', 'Released'),
|
||||
('Moved', 'Moved', 'Moved')],
|
||||
name='', default='Down')
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('left', 'left', 'left'),
|
||||
('right', 'right', 'right'),
|
||||
('middle', 'middle', 'middle')],
|
||||
|
|
|
@ -11,7 +11,8 @@ class OnSurfaceNode(ArmLogicTreeNode):
|
|||
arm_section = 'surface'
|
||||
arm_version = 2
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Touched', 'Touched', 'Touched'),
|
||||
('Started', 'Started', 'Started'),
|
||||
('Released', 'Released', 'Released'),
|
||||
|
|
|
@ -11,12 +11,13 @@ class OnVirtualButtonNode(ArmLogicTreeNode):
|
|||
arm_section = 'virtual'
|
||||
arm_version = 2
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Down', 'Down', 'Down'),
|
||||
('Started', 'Started', 'Started'),
|
||||
('Released', 'Released', 'Released')],
|
||||
name='', default='Started')
|
||||
property1: StringProperty(name='', default='button')
|
||||
property1: HaxeStringProperty('property1', name='', default='button')
|
||||
|
||||
def init(self, context):
|
||||
super(OnVirtualButtonNode, self).init(context)
|
||||
|
|
|
@ -10,7 +10,7 @@ class OnEventNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
arm_section = 'custom'
|
||||
|
||||
property0: StringProperty(name='', default='')
|
||||
property0: HaxeStringProperty('property0', name='', default='')
|
||||
|
||||
def init(self, context):
|
||||
super(OnEventNode, self).init(context)
|
||||
|
|
|
@ -10,7 +10,8 @@ class OnUpdateNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNOnUpdateNode'
|
||||
bl_label = 'On Update'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Update', 'Update', 'Update'),
|
||||
('Late Update', 'Late Update', 'Late Update'),
|
||||
('Physics Pre-Update', 'Physics Pre-Update', 'Physics Pre-Update')],
|
||||
|
|
|
@ -15,7 +15,8 @@ class GamepadNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
arm_section = 'gamepad'
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('started', 'Started', 'The gamepad button starts to be pressed'),
|
||||
('down', 'Down', 'The gamepad button is pressed'),
|
||||
('released', 'Released', 'The gamepad button stops being pressed')],
|
||||
|
@ -23,7 +24,8 @@ class GamepadNode(ArmLogicTreeNode):
|
|||
# ('Moved Right', 'Moved Right', 'Moved Right'),],
|
||||
name='', default='down')
|
||||
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('cross', 'cross / a', 'cross / a'),
|
||||
('circle', 'circle / b', 'circle / b'),
|
||||
('square', 'square / x', 'square / x'),
|
||||
|
|
|
@ -7,13 +7,15 @@ class KeyboardNode(ArmLogicTreeNode):
|
|||
arm_section = 'keyboard'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('started', 'Started', 'The keyboard button starts to be pressed'),
|
||||
('down', 'Down', 'The keyboard button is pressed'),
|
||||
('released', 'Released', 'The keyboard button stops being pressed')],
|
||||
name='', default='down')
|
||||
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('a', 'a', 'a'),
|
||||
('b', 'b', 'b'),
|
||||
('c', 'c', 'c'),
|
||||
|
|
|
@ -7,13 +7,15 @@ class MouseNode(ArmLogicTreeNode):
|
|||
arm_section = 'mouse'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('started', 'Started', 'The mouse button startes to be pressed'),
|
||||
('down', 'Down', 'The mouse button is pressed'),
|
||||
('released', 'Released', 'The mouse button stops being pressed'),
|
||||
('moved', 'Moved', 'Moved')],
|
||||
name='', default='down')
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('left', 'Left', 'Left mouse button'),
|
||||
('middle', 'Middle', 'Middle mouse button'),
|
||||
('right', 'Right', 'Right mouse button')],
|
||||
|
|
|
@ -14,7 +14,8 @@ class SetCursorStateNode(ArmLogicTreeNode):
|
|||
arm_section = 'mouse'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('hide locked', 'Hide Locked', 'The mouse cursor is hidden and locked'),
|
||||
('hide', 'Hide', 'The mouse cursor is hidden'),
|
||||
('lock', 'Lock', 'The mouse cursor is locked'),
|
||||
|
|
|
@ -7,7 +7,8 @@ class SurfaceNode(ArmLogicTreeNode):
|
|||
arm_section = 'surface'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('started', 'Started', 'The screen surface starts to be touched'),
|
||||
('down', 'Down', 'The screen surface is touched'),
|
||||
('released', 'Released', 'The screen surface stops being touched'),
|
||||
|
|
|
@ -7,12 +7,13 @@ class VirtualButtonNode(ArmLogicTreeNode):
|
|||
arm_section = 'virtual'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('started', 'Started', 'The virtual button starts to be pressed'),
|
||||
('down', 'Down', 'The virtual button is pressed'),
|
||||
('released', 'Released', 'The virtual button stops being pressed')],
|
||||
name='', default='down')
|
||||
property1: StringProperty(name='', default='button')
|
||||
property1: HaxeStringProperty('property1', name='', default='button')
|
||||
|
||||
def init(self, context):
|
||||
super(VirtualButtonNode, self).init(context)
|
||||
|
|
|
@ -20,7 +20,8 @@ class GateNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
|
||||
min_inputs = 3
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Equal', 'Equal', 'Equal'),
|
||||
('Almost Equal', 'Almost Equal', 'Almost Equal'),
|
||||
('Greater', 'Greater', 'Greater'),
|
||||
|
@ -31,7 +32,7 @@ class GateNode(ArmLogicTreeNode):
|
|||
('And', 'And', 'And')],
|
||||
name='', default='Equal',
|
||||
update=remove_extra_inputs)
|
||||
property1: FloatProperty(name='Tolerance', description='Precision for float compare', default=0.0001)
|
||||
property1: HaxeFloatProperty('property1', name='Tolerance', description='Precision for float compare', default=0.0001)
|
||||
|
||||
def __init__(self):
|
||||
super(GateNode, self).__init__()
|
||||
|
|
|
@ -18,7 +18,7 @@ class MaterialNode(ArmLogicTreeNode):
|
|||
return self.property0.name
|
||||
return arm.utils.asset_name(bpy.data.materials[self.property0.name])
|
||||
|
||||
property0: PointerProperty(name='', type=bpy.types.Material)
|
||||
property0: HaxePointerProperty('property0', name='', type=bpy.types.Material)
|
||||
|
||||
def init(self, context):
|
||||
super(MaterialNode, self).init(context)
|
||||
|
|
|
@ -10,7 +10,8 @@ class CompareNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNCompareNode'
|
||||
bl_label = 'Compare'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Equal', 'Equal', 'Equal'),
|
||||
('Almost Equal', 'Almost Equal', 'Almost Equal'),
|
||||
('Greater', 'Greater', 'Greater'),
|
||||
|
@ -22,7 +23,7 @@ class CompareNode(ArmLogicTreeNode):
|
|||
name='', default='Equal',
|
||||
update=remove_extra_inputs)
|
||||
min_inputs = 2
|
||||
property1: FloatProperty(name='Tolerance', description='Precision for float compare', default=0.0001)
|
||||
property1: HaxeFloatProperty('property1', name='Tolerance', description='Precision for float compare', default=0.0001)
|
||||
|
||||
def __init__(self):
|
||||
super(CompareNode, self).__init__()
|
||||
|
|
|
@ -64,7 +64,8 @@ class MathNode(ArmLogicTreeNode):
|
|||
self.inputs.remove(self.inputs.values()[-1])
|
||||
self['property0'] = value
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Add', 'Add', 'Add'),
|
||||
('Multiply', 'Multiply', 'Multiply'),
|
||||
('Sine', 'Sine', 'Sine'),
|
||||
|
@ -92,11 +93,7 @@ class MathNode(ArmLogicTreeNode):
|
|||
('Exponent', 'Exponent', 'Exponent')],
|
||||
name='', default='Add', set=set_enum, get=get_enum)
|
||||
|
||||
@property
|
||||
def property1(self):
|
||||
return 'true' if self.property1_ else 'false'
|
||||
|
||||
property1_: BoolProperty(name='Clamp', default=False)
|
||||
property1: HaxeBoolProperty('property1', name='Clamp', default=False)
|
||||
|
||||
def __init__(self):
|
||||
array_nodes[str(id(self))] = self
|
||||
|
@ -109,7 +106,7 @@ class MathNode(ArmLogicTreeNode):
|
|||
self.add_output('NodeSocketFloat', 'Result')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property1_')
|
||||
layout.prop(self, 'property1')
|
||||
layout.prop(self, 'property0')
|
||||
# Many arguments: Add, Subtract, Multiply, Divide
|
||||
if (self.get_count_in(self.property0) == 0):
|
||||
|
|
|
@ -155,8 +155,8 @@ class MathExpressionNode(ArmLogicTreeNode):
|
|||
def get_exp(self):
|
||||
return self.get('property0', 'a + b')
|
||||
|
||||
property0: StringProperty(name='', description='Expression (operation: +, -, *, /, ^, (, ), %)', set=set_exp, get=get_exp)
|
||||
property1: BoolProperty(name='Clamp', default=False)
|
||||
property0: HaxeStringProperty('property0', name='', description='Expression (operation: +, -, *, /, ^, (, ), %)', set=set_exp, get=get_exp)
|
||||
property1: HaxeBoolProperty('property1', name='Clamp', default=False)
|
||||
|
||||
def __init__(self):
|
||||
array_nodes[str(id(self))] = self
|
||||
|
|
|
@ -7,7 +7,8 @@ class MatrixMathNode(ArmLogicTreeNode):
|
|||
arm_section = 'matrix'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Multiply', 'Multiply', 'Multiply')],
|
||||
name='', default='Multiply')
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ class MixNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNMixNode'
|
||||
bl_label = 'Mix'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Linear', 'Linear', 'Linear'),
|
||||
('Sine', 'Sine', 'Sine'),
|
||||
('Quad', 'Quad', 'Quad'),
|
||||
|
@ -19,18 +20,15 @@ class MixNode(ArmLogicTreeNode):
|
|||
('Elastic', 'Elastic', 'Elastic'),
|
||||
],
|
||||
name='', default='Linear')
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('In', 'In', 'In'),
|
||||
('Out', 'Out', 'Out'),
|
||||
('InOut', 'InOut', 'InOut'),
|
||||
],
|
||||
name='', default='Out')
|
||||
|
||||
@property
|
||||
def property2(self):
|
||||
return 'true' if self.property2_ else 'false'
|
||||
|
||||
property2_: BoolProperty(name='Clamp', default=False)
|
||||
property2: HaxeBoolProperty('property2', name='Clamp', default=False)
|
||||
|
||||
def init(self, context):
|
||||
super(MixNode, self).init(context)
|
||||
|
@ -41,6 +39,6 @@ class MixNode(ArmLogicTreeNode):
|
|||
self.add_output('NodeSocketFloat', 'Result')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property2_')
|
||||
layout.prop(self, 'property2')
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
|
|
|
@ -7,7 +7,8 @@ class VectorMixNode(ArmLogicTreeNode):
|
|||
arm_section = 'vector'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Linear', 'Linear', 'Linear'),
|
||||
('Sine', 'Sine', 'Sine'),
|
||||
('Quad', 'Quad', 'Quad'),
|
||||
|
@ -21,18 +22,15 @@ class VectorMixNode(ArmLogicTreeNode):
|
|||
('Elastic', 'Elastic', 'Elastic'),
|
||||
],
|
||||
name='', default='Linear')
|
||||
property1: EnumProperty(
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('In', 'In', 'In'),
|
||||
('Out', 'Out', 'Out'),
|
||||
('InOut', 'InOut', 'InOut'),
|
||||
],
|
||||
name='', default='Out')
|
||||
|
||||
@property
|
||||
def property2(self):
|
||||
return 'true' if self.property2_ else 'false'
|
||||
|
||||
property2_: BoolProperty(name='Clamp', default=False)
|
||||
property2: HaxeBoolProperty('property2', name='Clamp', default=False)
|
||||
|
||||
def init(self, context):
|
||||
super(VectorMixNode, self).init(context)
|
||||
|
@ -43,7 +41,7 @@ class VectorMixNode(ArmLogicTreeNode):
|
|||
self.add_output('NodeSocketVector', 'Result')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property2_')
|
||||
layout.prop(self, 'property2')
|
||||
layout.prop(self, 'property0')
|
||||
if self.property0 != 'Linear':
|
||||
layout.prop(self, 'property1')
|
||||
|
|
|
@ -41,7 +41,7 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
|||
if (self.property0 == 'ToAxisAngle'):
|
||||
self.add_output('NodeSocketFloat', 'To Axis Angle') # ToAxisAngle
|
||||
|
||||
property1: BoolProperty(name='Separator Out', default=False, set=set_bool, get=get_bool)
|
||||
property1: HaxeBoolProperty('property1', name='Separator Out', default=False, set=set_bool, get=get_bool)
|
||||
|
||||
@staticmethod
|
||||
def get_enum_id_value(obj, prop_name, value):
|
||||
|
@ -132,7 +132,8 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
|||
self.add_output('NodeSocketFloat', 'Module')
|
||||
self['property0'] = value
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Add', 'Add', 'Add'),
|
||||
('Subtract', 'Subtract', 'Subtract'),
|
||||
('DotProduct', 'Dot Product', 'Dot Product'),
|
||||
|
|
|
@ -10,12 +10,7 @@ class ScreenToWorldSpaceNode(ArmLogicTreeNode):
|
|||
min_outputs = 2
|
||||
max_outputs = 8
|
||||
|
||||
# Separator
|
||||
@property
|
||||
def property0(self):
|
||||
return True if self.property0_ else False
|
||||
|
||||
property0_: BoolProperty(name='Separator Out', default=False)
|
||||
property0: HaxeBoolProperty('property0', name='Separator Out', default=False)
|
||||
|
||||
def init(self, context):
|
||||
super(ScreenToWorldSpaceNode, self).init(context)
|
||||
|
@ -26,8 +21,8 @@ class ScreenToWorldSpaceNode(ArmLogicTreeNode):
|
|||
self.add_output('NodeSocketVector', 'Direction')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0_') # Separator Out
|
||||
if self.property0_:
|
||||
layout.prop(self, 'property0') # Separator Out
|
||||
if self.property0:
|
||||
if len(self.outputs) < self.max_outputs:
|
||||
self.outputs.remove(self.outputs.values()[-1]) # Direction vector
|
||||
self.add_output('NodeSocketFloat', 'X') # World X
|
||||
|
|
|
@ -42,7 +42,7 @@ class VectorMathNode(ArmLogicTreeNode):
|
|||
if (self.property0 == 'Dot Product'):
|
||||
self.add_output('NodeSocketFloat', 'Scalar') # Scalar
|
||||
|
||||
property1: BoolProperty(name='Separator Out', default=False, set=set_bool, get=get_bool)
|
||||
property1: HaxeBoolProperty('property1', name='Separator Out', default=False, set=set_bool, get=get_bool)
|
||||
|
||||
@staticmethod
|
||||
def get_enum_id_value(obj, prop_name, value):
|
||||
|
@ -105,7 +105,8 @@ class VectorMathNode(ArmLogicTreeNode):
|
|||
self.add_output('NodeSocketFloat', 'Length')
|
||||
self['property0'] = value
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Add', 'Add', 'Add'),
|
||||
('Dot Product', 'Dot Product', 'Dot Product'),
|
||||
('Multiply', 'Multiply', 'Multiply'),
|
||||
|
|
|
@ -15,7 +15,7 @@ class CallGroupNode(ArmLogicTreeNode):
|
|||
def property0(self):
|
||||
return arm.utils.safesrc(bpy.data.worlds['Arm'].arm_project_package) + '.node.' + arm.utils.safesrc(self.property0_.name)
|
||||
|
||||
property0_: PointerProperty(name='Group', type=bpy.types.NodeTree)
|
||||
property0_: HaxePointerProperty('property0', name='Group', type=bpy.types.NodeTree)
|
||||
|
||||
def init(self, context):
|
||||
super(CallGroupNode, self).init(context)
|
||||
|
|
|
@ -6,7 +6,8 @@ class SetDebugConsoleSettings(ArmLogicTreeNode):
|
|||
bl_label = 'Set Debug Console Settings'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('left', 'Anchor Left', 'Anchor debug console in the top left'),
|
||||
('center', 'Anchor Center', 'Anchor debug console in the top center'),
|
||||
('right', 'Anchor Right', 'Anchor the debug console in the top right')],
|
||||
|
|
|
@ -9,7 +9,7 @@ class ExpressionNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
arm_section = 'haxe'
|
||||
|
||||
property0: StringProperty(name='', default='')
|
||||
property0: HaxeStringProperty('property0', name='', default='')
|
||||
|
||||
def init(self, context):
|
||||
super(ExpressionNode, self).init(context)
|
||||
|
|
|
@ -15,7 +15,7 @@ class ScriptNode(ArmLogicTreeNode):
|
|||
return bpy.data.texts[self.property0_].as_string() if self.property0_ in bpy.data.texts else ''
|
||||
|
||||
|
||||
property0_: StringProperty(name='Text', default='')
|
||||
property0_: HaxeStringProperty('property0', name='Text', default='')
|
||||
|
||||
def init(self, context):
|
||||
super(ScriptNode, self).init(context)
|
||||
|
|
|
@ -7,7 +7,8 @@ class GetChildNode(ArmLogicTreeNode):
|
|||
arm_section = 'relations'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('By Name', 'By Name', 'By Name'),
|
||||
('Contains', 'Contains', 'Contains'),
|
||||
('Starts With', 'Starts With', 'Starts With'),
|
||||
|
|
|
@ -9,7 +9,7 @@ class MeshNode(ArmLogicTreeNode):
|
|||
bl_label = 'Mesh'
|
||||
arm_version = 1
|
||||
|
||||
property0_get: PointerProperty(name='', type=bpy.types.Mesh)
|
||||
property0_get: HaxePointerProperty('property0_get', name='', type=bpy.types.Mesh)
|
||||
|
||||
def init(self, context):
|
||||
super(MeshNode, self).init(context)
|
||||
|
|
|
@ -9,7 +9,8 @@ class SetVisibleNode(ArmLogicTreeNode):
|
|||
arm_section = 'props'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('object', 'Object', 'All object componenets visibility'),
|
||||
('mesh', 'Mesh', 'Mesh visibility only'),
|
||||
('shadow', 'Shadow', 'Shadow visibility only'),
|
||||
|
|
|
@ -6,7 +6,8 @@ class SpawnObjectByNameNode(ArmLogicTreeNode):
|
|||
bl_label = 'Spawn Object By Name'
|
||||
arm_version = 1
|
||||
|
||||
property0: PointerProperty(
|
||||
property0: HaxePointerProperty(
|
||||
'property0',
|
||||
type=bpy.types.Scene, name='Scene',
|
||||
description='The scene from which to take the object')
|
||||
|
||||
|
|
|
@ -59,18 +59,16 @@ class AddRigidBodyNode(ArmLogicTreeNode):
|
|||
further down."""
|
||||
self.update_sockets(context)
|
||||
|
||||
@property
|
||||
def property1(self):
|
||||
return 'true' if self.property1_ else 'false'
|
||||
|
||||
property1_: BoolProperty(
|
||||
property1: HaxeBoolProperty(
|
||||
'property1',
|
||||
name="Advanced",
|
||||
description="Show advanced options",
|
||||
default=False,
|
||||
update=update_advanced
|
||||
)
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Box', 'Box', 'Box'),
|
||||
('Sphere', 'Sphere', 'Sphere'),
|
||||
('Capsule', 'Capsule', 'Capsule'),
|
||||
|
@ -122,5 +120,5 @@ class AddRigidBodyNode(ArmLogicTreeNode):
|
|||
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, "property1_")
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, "property1")
|
||||
layout.prop(self, 'property0')
|
||||
|
|
|
@ -124,7 +124,8 @@ class AddPhysicsConstraintNode(ArmLogicTreeNode):
|
|||
|
||||
self['property0'] = value
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Fixed', 'Fixed', 'Fixed'),
|
||||
('Point', 'Point', 'Point'),
|
||||
('Hinge', 'Hinge', 'Hinge'),
|
||||
|
|
|
@ -16,7 +16,8 @@ class OnContactNode(ArmLogicTreeNode):
|
|||
arm_section = 'contact'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('begin', 'Begin', 'The contact between the rigid bodies begins'),
|
||||
('overlap', 'Overlap', 'The contact between the rigid bodies is happening'),
|
||||
('end', 'End', 'The contact between the rigid bodies ends')],
|
||||
|
|
|
@ -7,7 +7,8 @@ class OnContactArrayNode(ArmLogicTreeNode):
|
|||
arm_section = 'contact'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('begin', 'Begin', 'The contact between the rigid bodies begins'),
|
||||
('overlap', 'Overlap', 'The contact between the rigid bodies is happening'),
|
||||
('end', 'End', 'The contact between the rigid bodies ends')],
|
||||
|
|
|
@ -10,7 +10,8 @@ class OnVolumeTriggerNode(ArmLogicTreeNode):
|
|||
bl_label = 'On Volume Trigger'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('begin', 'Begin', 'The contact between the rigid bodies begins'),
|
||||
('overlap', 'Overlap', 'The contact between the rigid bodies is happening'),
|
||||
('end', 'End', 'The contact between the rigid bodies ends')],
|
||||
|
|
|
@ -26,32 +26,21 @@ class PhysicsConstraintNode(ArmLogicTreeNode):
|
|||
def update_spring(self, context):
|
||||
self.update_sockets(context)
|
||||
|
||||
property0: EnumProperty(
|
||||
items = [('Linear', 'Linear', 'Linear'),
|
||||
('Angular', 'Angular', 'Angular')],
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items=[('Linear', 'Linear', 'Linear'),
|
||||
('Angular', 'Angular', 'Angular')],
|
||||
name='Type', default='Linear')
|
||||
|
||||
@property
|
||||
def property1(self):
|
||||
if(self.property1_ == 'X'):
|
||||
return 'X'
|
||||
if(self.property1_ == 'Y'):
|
||||
return 'Y'
|
||||
if(self.property1_ == 'Z'):
|
||||
return 'Z'
|
||||
|
||||
property1_: EnumProperty(
|
||||
items = [('X', 'X', 'X'),
|
||||
('Y', 'Y', 'Y'),
|
||||
('Z', 'Z', 'Z')],
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items=[('X', 'X', 'X'),
|
||||
('Y', 'Y', 'Y'),
|
||||
('Z', 'Z', 'Z')],
|
||||
name='Axis', default='X')
|
||||
|
||||
@property
|
||||
def property2(self):
|
||||
if(self.property2_):
|
||||
return 'true' if self.property2_ else 'false'
|
||||
|
||||
property2_: BoolProperty(
|
||||
property2: HaxeBoolProperty(
|
||||
'property2',
|
||||
name="Spring",
|
||||
description="Is a spring constraint",
|
||||
default=False,
|
||||
|
@ -66,14 +55,13 @@ class PhysicsConstraintNode(ArmLogicTreeNode):
|
|||
self.add_input('NodeSocketFloat', 'Lower limit')
|
||||
self.add_input('NodeSocketFloat', 'Upper limit')
|
||||
self.add_output('NodeSocketShader', 'Constraint')
|
||||
|
||||
def update_sockets(self, context):
|
||||
|
||||
while (len(self.inputs) > 0):
|
||||
def update_sockets(self, context):
|
||||
while len(self.inputs) > 0:
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
|
||||
# Add dynamic input sockets
|
||||
if self.property2_:
|
||||
if self.property2:
|
||||
self.add_input('NodeSocketFloat', 'Stiffness', 10.0)
|
||||
self.add_input('NodeSocketFloat', 'Damping', 0.5)
|
||||
else:
|
||||
|
@ -82,6 +70,5 @@ class PhysicsConstraintNode(ArmLogicTreeNode):
|
|||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1_')
|
||||
layout.prop(self, 'property2_')
|
||||
|
||||
layout.prop(self, 'property1')
|
||||
layout.prop(self, 'property2')
|
||||
|
|
|
@ -7,7 +7,8 @@ class SetActivationStateNode(ArmLogicTreeNode):
|
|||
bl_icon = 'NONE'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('inactive', 'Inactive', 'The rigid body simulation is deactivated'),
|
||||
('active', 'Active', 'The rigid body simulation is activated'),
|
||||
('always active', 'Always Active', 'The rigid body simulation is never deactivated'),
|
||||
|
|
|
@ -12,7 +12,8 @@ class VolumeTriggerNode(ArmLogicTreeNode):
|
|||
arm_section = 'misc'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('begin', 'Begin', 'The contact between the rigid bodies begins'),
|
||||
('overlap', 'Overlap', 'The contact between the rigid bodies is happening'),
|
||||
('end', 'End', 'The contact between the rigid bodies ends')],
|
||||
|
|
|
@ -32,7 +32,8 @@ class ColorgradingSetGlobalNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
|
||||
# TODO: RRESET FILE OPTION FOR THE BELOW
|
||||
property0 : EnumProperty(
|
||||
property0 : HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('RGB', 'RGB', 'RGB'),
|
||||
('Uniform', 'Uniform', 'Uniform')],
|
||||
name='Mode', default='Uniform', update=update_node)
|
||||
|
|
|
@ -32,7 +32,8 @@ class ColorgradingSetHighlightNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
|
||||
# TODO: RRESET FILE OPTION FOR THE BELOW
|
||||
property0 : EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('RGB', 'RGB', 'RGB'),
|
||||
('Uniform', 'Uniform', 'Uniform')],
|
||||
name='Mode', default='Uniform', update=update_node)
|
||||
|
|
|
@ -32,7 +32,8 @@ class ColorgradingSetMidtoneNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
|
||||
# TODO: RRESET FILE OPTION FOR THE BELOW
|
||||
property0 : EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('RGB', 'RGB', 'RGB'),
|
||||
('Uniform', 'Uniform', 'Uniform')],
|
||||
name='Mode', default='Uniform', update=update_node)
|
||||
|
|
|
@ -32,7 +32,8 @@ class ColorgradingSetShadowNode(ArmLogicTreeNode):
|
|||
arm_version = 1
|
||||
|
||||
# TODO: RRESET FILE OPTION FOR THE BELOW
|
||||
property0 : EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('RGB', 'RGB', 'RGB'),
|
||||
('Uniform', 'Uniform', 'Uniform')],
|
||||
name='Mode', default='Uniform', update=update_node)
|
||||
|
|
|
@ -5,7 +5,8 @@ class RpMSAANode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNRpMSAANode'
|
||||
bl_label = 'Set MSAA Quality'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('1', '1', '1'),
|
||||
('2', '2', '2'),
|
||||
('4', '4', '4'),
|
||||
|
|
|
@ -5,7 +5,8 @@ class RpConfigNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNRpConfigNode'
|
||||
bl_label = 'Set Post Process Quality'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('SSGI', 'SSGI', 'SSGI'),
|
||||
('SSR', 'SSR', 'SSR'),
|
||||
('Bloom', 'Bloom', 'Bloom'),
|
||||
|
|
|
@ -21,7 +21,8 @@ class SetShaderUniformNode(ArmLogicTreeNode):
|
|||
elif self.property0 in ('vec2', 'vec3', 'vec4'):
|
||||
self.add_input('NodeSocketVector', 'Vector')
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('int', 'int', 'int'),
|
||||
('float', 'float', 'float'),
|
||||
('vec2', 'vec2', 'vec2'),
|
||||
|
|
|
@ -5,7 +5,8 @@ class RpShadowQualityNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNRpShadowQualityNode'
|
||||
bl_label = 'Set Shadows Quality'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('High', 'High', 'High'),
|
||||
('Medium', 'Medium', 'Medium'),
|
||||
('Low', 'Low', 'Low')
|
||||
|
|
|
@ -5,7 +5,8 @@ class RpSuperSampleNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNRpSuperSampleNode'
|
||||
bl_label = 'Set SSAA Quality'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('1', '1', '1'),
|
||||
('1.5', '1.5', '1.5'),
|
||||
('2', '2', '2'),
|
||||
|
|
|
@ -12,7 +12,7 @@ class GroupNode(ArmLogicTreeNode):
|
|||
arm_section = 'collection'
|
||||
arm_version = 1
|
||||
|
||||
property0: PointerProperty(name='', type=bpy.types.Collection)
|
||||
property0: HaxePointerProperty('property0', name='', type=bpy.types.Collection)
|
||||
|
||||
def init(self, context):
|
||||
super(GroupNode, self).init(context)
|
||||
|
|
|
@ -9,7 +9,7 @@ class SceneNode(ArmLogicTreeNode):
|
|||
bl_label = 'Scene'
|
||||
arm_version = 1
|
||||
|
||||
property0_get: PointerProperty(name='', type=bpy.types.Scene)
|
||||
property0_get: HaxePointerProperty('property0_get', name='', type=bpy.types.Scene)
|
||||
|
||||
def init(self, context):
|
||||
super(SceneNode, self).init(context)
|
||||
|
|
|
@ -28,7 +28,7 @@ class SpawnCollectionNode(ArmLogicTreeNode):
|
|||
arm_section = 'collection'
|
||||
arm_version = 1
|
||||
|
||||
property0: PointerProperty(name='Collection', type=bpy.types.Collection)
|
||||
property0: HaxePointerProperty('property0', name='Collection', type=bpy.types.Collection)
|
||||
|
||||
def init(self, context):
|
||||
super(SpawnCollectionNode, self).init(context)
|
||||
|
|
|
@ -31,25 +31,30 @@ class PlaySoundNode(ArmLogicTreeNode):
|
|||
bl_width_default = 200
|
||||
arm_version = 1
|
||||
|
||||
property0: PointerProperty(name='', type=bpy.types.Sound)
|
||||
property1: BoolProperty(
|
||||
property0: HaxePointerProperty('property0', name='', type=bpy.types.Sound)
|
||||
property1: HaxeBoolProperty(
|
||||
'property1',
|
||||
name='Loop',
|
||||
description='Play the sound in a loop',
|
||||
default=False)
|
||||
property2: BoolProperty(
|
||||
property2: HaxeBoolProperty(
|
||||
'property2',
|
||||
name='Retrigger',
|
||||
description='Play the sound from the beginning every time',
|
||||
default=False)
|
||||
property3: BoolProperty(
|
||||
property3: HaxeBoolProperty(
|
||||
'property3',
|
||||
name='Use Custom Sample Rate',
|
||||
description='If enabled, override the default sample rate',
|
||||
default=False)
|
||||
property4: IntProperty(
|
||||
property4: HaxeIntProperty(
|
||||
'property4',
|
||||
name='Sample Rate',
|
||||
description='Set the sample rate used to play this sound',
|
||||
default=44100,
|
||||
min=0)
|
||||
property5: BoolProperty(
|
||||
property5: HaxeBoolProperty(
|
||||
'property5',
|
||||
name='Stream',
|
||||
description='Stream the sound from disk',
|
||||
default=False
|
||||
|
|
|
@ -5,7 +5,8 @@ class CaseStringNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNCaseStringNode'
|
||||
bl_label = 'String Case'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Upper Case', 'Upper Case', 'Upper Case'),
|
||||
('Lower Case', 'Lower Case', 'Lower Case'),
|
||||
],
|
||||
|
|
|
@ -5,7 +5,8 @@ class ContainsStringNode(ArmLogicTreeNode):
|
|||
bl_idname = 'LNContainsStringNode'
|
||||
bl_label = 'String Contains'
|
||||
arm_version = 1
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Contains', 'Contains', 'Contains'),
|
||||
('Starts With', 'Starts With', 'Starts With'),
|
||||
('Ends With', 'Ends With', 'Ends With'),
|
||||
|
|
|
@ -8,7 +8,7 @@ class TraitNode(ArmLogicTreeNode):
|
|||
bl_label = 'Trait'
|
||||
arm_version = 1
|
||||
|
||||
property0: StringProperty(name='', default='')
|
||||
property0: HaxeStringProperty('property0', name='', default='')
|
||||
|
||||
def init(self, context):
|
||||
super(TraitNode, self).init(context)
|
||||
|
|
|
@ -7,7 +7,8 @@ class GetWorldNode(ArmLogicTreeNode):
|
|||
arm_section = 'rotation'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Right', 'Right', 'The object right (X) direction'),
|
||||
('Look', 'Look', 'The object look (Y) direction'),
|
||||
('Up', 'Up', 'The object up (Z) direction')],
|
||||
|
|
|
@ -7,7 +7,8 @@ class LookAtNode(ArmLogicTreeNode):
|
|||
arm_section = 'rotation'
|
||||
arm_version = 1
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('X', ' X', 'X'),
|
||||
('-X', '-X', '-X'),
|
||||
('Y', ' Y', 'Y'),
|
||||
|
|
|
@ -40,10 +40,11 @@ class RotateObjectNode(ArmLogicTreeNode):
|
|||
else:
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
property0: EnumProperty(
|
||||
items = [('Euler Angles', 'Euler Angles', 'Euler Angles'),
|
||||
('Angle Axies (Radians)', 'Angle Axies (Radians)', 'Angle Axies (Radians)'),
|
||||
('Angle Axies (Degrees)', 'Angle Axies (Degrees)', 'Angle Axies (Degrees)'),
|
||||
('Quaternion', 'Quaternion', 'Quaternion')],
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items=[('Euler Angles', 'Euler Angles', 'Euler Angles'),
|
||||
('Angle Axies (Radians)', 'Angle Axies (Radians)', 'Angle Axies (Radians)'),
|
||||
('Angle Axies (Degrees)', 'Angle Axies (Degrees)', 'Angle Axies (Degrees)'),
|
||||
('Quaternion', 'Quaternion', 'Quaternion')],
|
||||
name='', default='Euler Angles',
|
||||
update = on_property_update)
|
||||
update=on_property_update)
|
||||
|
|
|
@ -33,7 +33,8 @@ class SetRotationNode(ArmLogicTreeNode):
|
|||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Euler Angles', 'Euler Angles', 'Euler Angles'),
|
||||
('Angle Axies (Radians)', 'Angle Axies (Radians)', 'Angle Axies (Radians)'),
|
||||
('Angle Axies (Degrees)', 'Angle Axies (Degrees)', 'Angle Axies (Degrees)'),
|
||||
|
|
|
@ -31,7 +31,8 @@ class VectorFromTransformNode(ArmLogicTreeNode):
|
|||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
property0: EnumProperty(
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Right', 'Right', 'The transform right (X) direction'),
|
||||
('Look', 'Look', 'The transform look (Y) direction'),
|
||||
('Up', 'Up', 'The transform up (Z) direction'),
|
||||
|
|
|
@ -158,26 +158,9 @@ def build_node(node: bpy.types.Node, f: TextIO) -> Optional[str]:
|
|||
f.write(f'\t\tthis.nodes["{name[1:]}"] = {name};\n')
|
||||
|
||||
# Properties
|
||||
for i in range(0, 10):
|
||||
prop_name = 'property' + str(i) + '_get'
|
||||
prop_found = hasattr(node, prop_name)
|
||||
if not prop_found:
|
||||
prop_name = 'property' + str(i)
|
||||
prop_found = hasattr(node, prop_name)
|
||||
if prop_found:
|
||||
prop = getattr(node, prop_name)
|
||||
if isinstance(prop, str):
|
||||
prop = '"' + str(prop) + '"'
|
||||
elif isinstance(prop, bool):
|
||||
prop = str(prop).lower()
|
||||
elif hasattr(prop, 'name'): # PointerProperty
|
||||
prop = '"' + str(prop.name) + '"'
|
||||
else:
|
||||
if prop is None:
|
||||
prop = 'null'
|
||||
else:
|
||||
prop = str(prop)
|
||||
f.write('\t\t' + name + '.property' + str(i) + ' = ' + prop + ';\n')
|
||||
for prop_name in arm.node_utils.get_haxe_property_names(node):
|
||||
prop = arm.node_utils.haxe_format_prop(node, prop_name)
|
||||
f.write('\t\t' + name + '.' + prop_name + ' = ' + prop + ';\n')
|
||||
|
||||
# Create inputs
|
||||
for inp in node.inputs:
|
||||
|
@ -284,23 +267,16 @@ def build_default_node(inp: bpy.types.NodeSocket):
|
|||
|
||||
if is_custom_socket:
|
||||
# ArmCustomSockets need to implement get_default_value()
|
||||
default_value = inp.get_default_value()
|
||||
if isinstance(default_value, str):
|
||||
default_value = '"{:s}"'.format(default_value.replace('"', '\\"') )
|
||||
default_value = arm.node_utils.haxe_format_socket_val(inp.get_default_value())
|
||||
inp_type = inp.arm_socket_type # any custom socket's `type` is "VALUE". might as well have valuable type information for custom nodes as well.
|
||||
else:
|
||||
if hasattr(inp, 'default_value'):
|
||||
default_value = inp.default_value
|
||||
else:
|
||||
default_value = None
|
||||
if isinstance(default_value, str):
|
||||
default_value = '"{:s}"'.format(default_value.replace('"', '\\"') )
|
||||
default_value = arm.node_utils.haxe_format_socket_val(default_value)
|
||||
inp_type = inp.type
|
||||
|
||||
# Don't write 'None' into the Haxe code
|
||||
if default_value is None:
|
||||
default_value = 'null'
|
||||
|
||||
if inp_type == 'VECTOR':
|
||||
return f'new armory.logicnode.VectorNode(this, {default_value[0]}, {default_value[1]}, {default_value[2]})'
|
||||
elif inp_type == 'RGBA':
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Type, Union
|
||||
from typing import Any, Generator, Type, Union
|
||||
|
||||
import bpy
|
||||
from bpy.types import NodeSocket, NodeInputs, NodeOutputs
|
||||
|
@ -83,6 +83,50 @@ def get_export_node_name(node: bpy.types.Node) -> str:
|
|||
return '_' + arm.utils.safesrc(node.name)
|
||||
|
||||
|
||||
def get_haxe_property_names(node: bpy.types.Node) -> Generator[str, None, None]:
|
||||
"""Generator that yields the names of all node properties that have
|
||||
a counterpart in the node's Haxe class.
|
||||
"""
|
||||
for i in range(0, 10):
|
||||
prop_name = f'property{i}_get'
|
||||
prop_found = hasattr(node, prop_name)
|
||||
if not prop_found:
|
||||
prop_name = f'property{i}'
|
||||
prop_found = hasattr(node, prop_name)
|
||||
if prop_found:
|
||||
yield prop_name
|
||||
|
||||
|
||||
def haxe_format_socket_val(socket_val: Any) -> str:
|
||||
"""Formats a socket value to be valid Haxe syntax."""
|
||||
if isinstance(socket_val, str):
|
||||
socket_val = '"{:s}"'.format(socket_val.replace('"', '\\"'))
|
||||
|
||||
elif socket_val is None:
|
||||
# Don't write 'None' into the Haxe code
|
||||
socket_val = 'null'
|
||||
|
||||
return socket_val
|
||||
|
||||
|
||||
def haxe_format_prop(node: bpy.types.Node, prop_name: str) -> str:
|
||||
"""Formats a property value to be valid Haxe syntax."""
|
||||
prop_value = getattr(node, prop_name)
|
||||
if isinstance(prop_value, str):
|
||||
prop_value = '"' + str(prop_value) + '"'
|
||||
elif isinstance(prop_value, bool):
|
||||
prop_value = str(prop_value).lower()
|
||||
elif hasattr(prop_value, 'name'): # PointerProperty
|
||||
prop_value = '"' + str(prop_value.name) + '"'
|
||||
else:
|
||||
if prop_value is None:
|
||||
prop_value = 'null'
|
||||
else:
|
||||
prop_value = str(prop_value)
|
||||
|
||||
return prop_value
|
||||
|
||||
|
||||
def nodetype_to_nodeitem(node_type: Type[bpy.types.Node]) -> NodeItem:
|
||||
"""Create a NodeItem from a given node class."""
|
||||
# Internal node types seem to have no bl_idname attribute
|
||||
|
|
Loading…
Reference in a new issue