armory/blender/arm/make_logic.py

110 lines
3.9 KiB
Python
Raw Normal View History

2016-09-23 00:34:42 +02:00
import bpy
from bpy.types import NodeTree, Node, NodeSocket
from bpy.props import *
import os
import sys
2017-03-15 12:30:14 +01:00
import arm.nodes_logic as nodes_logic
import arm.nodes as nodes
import arm.utils
2016-09-23 00:34:42 +02:00
# Generating node sources
2016-10-19 13:28:06 +02:00
def build_node_trees():
s = bpy.data.filepath.split(os.path.sep)
s.pop()
fp = os.path.sep.join(s)
os.chdir(fp)
2016-09-23 00:34:42 +02:00
# Make sure package dir exists
2016-10-17 00:02:51 +02:00
nodes_path = 'Sources/' + bpy.data.worlds['Arm'].arm_project_package.replace(".", "/") + "/node"
if not os.path.exists(nodes_path):
os.makedirs(nodes_path)
# Export node scripts
for node_group in bpy.data.node_groups:
if node_group.bl_idname == 'ArmLogicTreeType': # Build only game trees
node_group.use_fake_user = True # Keep fake references for now
2016-10-19 13:28:06 +02:00
build_node_tree(node_group)
2016-09-23 00:34:42 +02:00
2016-10-19 13:28:06 +02:00
def build_node_tree(node_group):
2016-10-17 00:02:51 +02:00
path = 'Sources/' + bpy.data.worlds['Arm'].arm_project_package.replace('.', '/') + '/node/'
2017-03-15 12:30:14 +01:00
node_group_name = arm.utils.safe_source_name(node_group.name)
2016-09-23 00:34:42 +02:00
with open(path + node_group_name + '.hx', 'w') as f:
2016-10-17 00:02:51 +02:00
f.write('package ' + bpy.data.worlds['Arm'].arm_project_package + '.node;\n\n')
f.write('import armory.logicnode.*;\n\n')
2017-03-06 02:29:03 +01:00
f.write('@:keep class ' + node_group_name + ' extends armory.Trait {\n\n')
f.write('\tpublic function new() { super(); notifyOnAdd(add); }\n\n')
f.write('\tfunction add() {\n')
# Make sure root node exists
roots = get_root_nodes(node_group)
created_nodes = []
for rn in roots:
name = '_' + rn.name.replace('.', '_').replace(' ', '')
buildNode(node_group, rn, f, created_nodes)
f.write('\t}\n')
f.write('}\n')
2016-09-23 00:34:42 +02:00
def buildNode(node_group, node, f, created_nodes):
# Get node name
name = '_' + node.name.replace('.', '_').replace(' ', '')
2016-09-23 00:34:42 +02:00
# Check if node already exists
for n in created_nodes:
if n == name:
return name
2016-09-23 00:34:42 +02:00
# Create node
type = node.name.split(".")[0].replace(' ', '') + "Node"
2017-03-06 02:29:03 +01:00
f.write('\t\tvar ' + name + ' = new ' + type + '(this);\n')
created_nodes.append(name)
# Properties
if hasattr(node, "property0"):
f.write('\t\t' + name + '.property0 = "' + node.property0 + '";\n')
if hasattr(node, "property1"):
f.write('\t\t' + name + '.property1 = "' + node.property1 + '";\n')
if hasattr(node, "property2"):
f.write('\t\t' + name + '.property2 = "' + node.property2 + '";\n')
if hasattr(node, "property3"):
f.write('\t\t' + name + '.property3 = "' + node.property3 + '";\n')
if hasattr(node, "property4"):
f.write('\t\t' + name + '.property4 = "' + node.property4 + '";\n')
# Create inputs
for inp in node.inputs:
# Is linked - find node
inpname = ''
if inp.is_linked:
2016-10-19 13:28:06 +02:00
n = nodes.find_node_by_link(node_group, node, inp)
inpname = buildNode(node_group, n, f, created_nodes)
# Not linked - create node with default values
else:
inpname = build_default_node(inp)
# Add input
2017-03-06 02:29:03 +01:00
f.write('\t\t' + name + '.addInput(' + inpname + ');\n')
return name
2016-09-23 00:34:42 +02:00
def get_root_nodes(node_group):
roots = []
for n in node_group.nodes:
2017-03-06 02:29:03 +01:00
linked = False
for o in n.outputs:
if o.is_linked:
linked = True
break
if not linked: # Assume node with no connected outputs as roots
roots.append(n)
return roots
2016-09-23 00:34:42 +02:00
def build_default_node(inp):
inpname = ''
if inp.type == "VECTOR":
2017-03-06 02:29:03 +01:00
inpname = 'new VectorNode(this, ' + str(inp.default_value[0]) + ', ' + str(inp.default_value[1]) + ", " + str(inp.default_value[2]) + ')'
elif inp.type == "VALUE":
2017-03-06 02:29:03 +01:00
inpname = 'new FloatNode(this, ' + str(inp.default_value) + ')'
elif inp.type == 'BOOLEAN':
2017-03-06 02:29:03 +01:00
inpname = 'new BoolNode(this, ' + str(inp.default_value).lower() + ')'
return inpname