Node scripting

This commit is contained in:
Lubos Lenco 2015-11-26 15:36:17 +01:00
parent f1a1f53b84
commit 7e1052be90
13 changed files with 340 additions and 5 deletions

View file

@ -0,0 +1,16 @@
package cycles.node;
class BoolNode extends Node {
public var b:Bool;
public function new() {
super();
}
public static function create(_b:Bool) {
var n = new BoolNode();
n.b = _b;
return n;
}
}

View file

@ -0,0 +1,16 @@
package cycles.node;
class FloatNode extends Node {
public var f:Float;
public function new() {
super();
}
public static function create(_f:Float) {
var n = new FloatNode();
n.f = _f;
return n;
}
}

View file

@ -0,0 +1,16 @@
package cycles.node;
class IntNode extends Node {
public var i:Int;
public function new() {
super();
}
public static function create(_i:Int) {
var n = new IntNode();
n.i = _i;
return n;
}
}

View file

@ -0,0 +1,28 @@
package cycles.node;
import cycles.trait.NodeExecutor;
class Node {
var executor:NodeExecutor;
var parents:Array<Node> = [];
public var inputs:Array<Dynamic> = [];
public function new() {}
public function start(executor:NodeExecutor, parent:Node = null) {
this.executor = executor;
if (parent != null) parents.push(parent);
for (inp in inputs) inp.start(executor, this);
inputChanged();
}
public function inputChanged() {
for (p in parents) {
p.inputChanged();
}
}
}

View file

@ -0,0 +1,24 @@
package cycles.node;
class ScaleValueNode extends FloatNode {
public static inline var _factor = 0; // Float
public static inline var _value = 1; // Float
public function new() {
super();
}
public override function inputChanged() {
f = inputs[_value].f * inputs[_factor].f;
super.inputChanged();
}
public static function create(factor:Float, value:Float) {
var n = new ScaleValueNode();
n.inputs.push(FloatNode.create(factor));
n.inputs.push(FloatNode.create(value));
return n;
}
}

View file

@ -0,0 +1,22 @@
package cycles.node;
class SineNode extends FloatNode {
public static inline var _value = 0; // Float
public function new() {
super();
}
public override function inputChanged() {
f = Math.sin(inputs[_value].f);
super.inputChanged();
}
public static function create(value:Float) {
var n = new SineNode();
n.inputs.push(FloatNode.create(value));
return n;
}
}

View file

@ -0,0 +1,16 @@
package cycles.node;
class StringNode extends Node {
public var s:String;
public function new() {
super();
}
public static function create(_s:String) {
var n = new StringNode();
n.s = _s;
return n;
}
}

View file

@ -0,0 +1,76 @@
package cycles.node;
import cycles.trait.NodeExecutor;
class TimeNode extends FloatNode {
public static inline var _startTime = 0; // Float
public static inline var _stopTime = 1; // Float
public static inline var _scale = 2; // Float
public static inline var _enabled = 3; // Bool
public static inline var _loop = 4; // Bool
public static inline var _reflect = 5; // Bool
public function new() {
super();
}
public override function start(executor:NodeExecutor, parent:Node = null) {
super.start(executor, parent);
f = inputs[_startTime].f;
executor.registerUpdate(update);
}
function update() {
if (inputs[_enabled].b) {
f += lue.sys.Time.delta * inputs[_scale].f;
// Time out
if (inputs[_stopTime].f > 0) {
if (inputs[_scale].f > 0 && f >= inputs[_stopTime].f ||
inputs[_scale].f < 0 && f <= inputs[_startTime].f) {
// Loop
if (inputs[_loop].b) {
// Reflect
if (inputs[_reflect].b) {
if (inputs[_scale].f > 0) {
f = inputs[_stopTime].f;
}
else {
f = inputs[_startTime].f;
}
inputs[_scale].f *= -1;
}
// Reset
else {
f = inputs[_startTime].f;
}
}
// Stop
else {
f = inputs[_stopTime].f;
inputs[_enabled].b = false;
}
}
}
inputChanged();
}
}
public static function create(startTime:Float, stopTime:Float, enabled:Bool, loop:Bool, reflect:Bool) {
var n = new TimeNode();
n.inputs.push(FloatNode.create(startTime));
n.inputs.push(FloatNode.create(stopTime));
n.inputs.push(BoolNode.create(enabled));
n.inputs.push(BoolNode.create(loop));
n.inputs.push(BoolNode.create(reflect));
return n;
}
}

View file

@ -0,0 +1,65 @@
package cycles.node;
import lue.math.Mat4;
import lue.math.Vec3;
import lue.math.Quat;
class TransformNode extends Node {
public static inline var _position = 0; // Vector
public static inline var _rotation = 1; // Vector
public static inline var _scale = 2; // Vector
public var transform:lue.node.Transform;
var matrix:Mat4;
var pos:Vec3;
var rot:Quat;
var scale:Vec3;
public function new() {
super();
matrix = new Mat4();
pos = new Vec3();
rot = new Quat();
scale = new Vec3();
}
public override function inputChanged() {
// Build matrix
pos.set(inputs[_position].inputs[VectorNode._x].f,
inputs[_position].inputs[VectorNode._y].f,
inputs[_position].inputs[VectorNode._z].f);
rot.initRotate(inputs[_rotation].inputs[VectorNode._x].f,
inputs[_rotation].inputs[VectorNode._y].f,
inputs[_rotation].inputs[VectorNode._z].f);
scale.set(inputs[_scale].inputs[VectorNode._x].f,
inputs[_scale].inputs[VectorNode._y].f,
inputs[_scale].inputs[VectorNode._z].f);
rot.saveToMatrix(matrix);
matrix.scale(scale);
matrix._41 = pos.x;
matrix._42 = pos.y;
matrix._43 = pos.z;
// Append to transform
transform.append = matrix;
transform.dirty = true;
super.inputChanged();
}
public static function create(positionX:Float, positionY:Float, positionZ:Float,
rotationX:Float, rotationY:Float, rotationZ:Float,
scaleX:Float, scaleY:Float, scaleZ:Float):TransformNode {
var n = new TransformNode();
n.inputs.push(VectorNode.create(positionX, positionY, positionZ));
n.inputs.push(VectorNode.create(rotationX, rotationY, rotationZ));
n.inputs.push(VectorNode.create(scaleX, scaleY, scaleZ));
return n;
}
}

View file

@ -0,0 +1,20 @@
package cycles.node;
class VectorNode extends Node {
public static inline var _x = 0; // Float
public static inline var _y = 1; // Float
public static inline var _z = 2; // Float
public function new() {
super();
}
public static function create(x:Float, y:Float, z:Float):VectorNode {
var n = new VectorNode();
n.inputs.push(FloatNode.create(x));
n.inputs.push(FloatNode.create(y));
n.inputs.push(FloatNode.create(z));
return n;
}
}

View file

@ -0,0 +1,30 @@
package cycles.trait;
import lue.trait.Trait;
class NodeExecutor extends Trait {
var baseNode:cycles.node.Node;
var nodeUpdates:Array<Void->Void> = [];
public function new() {
super();
requestUpdate(update);
}
public function start(baseNode:cycles.node.Node) {
this.baseNode = baseNode;
baseNode.start(this);
}
function update() {
for (f in nodeUpdates) {
f();
}
}
public function registerUpdate(f:Void->Void) {
nodeUpdates.push(f);
}
}

View file

@ -631,8 +631,8 @@ def buildNodeTree(node_group):
f.write('package ' + bpy.data.worlds[0].TargetProjectPackage + ';\n\n')
f.write('import cycles.node.*;\n\n')
f.write('class ' + node_group_name + ' extends cycles.trait.NodeExecutor {\n\n')
f.write('\tpublic function new() { super(); }\n\n')
f.write('\toverride function onItemAdd() {\n')
f.write('\tpublic function new() { super(); requestAdd(add); }\n\n')
f.write('\tfunction add() {\n')
# Make sure root node exists
if rn != None:
name = '_' + rn.name.replace(".", "_").replace("@", "")
@ -657,7 +657,7 @@ def buildNode(node_group, node, f, created_nodes):
# Variables
if type == "TransformNode":
f.write('\t\t' + name + '.transform = owner.transform;\n')
f.write('\t\t' + name + '.transform = node.transform;\n')
# Create inputs
for inp in node.inputs:

View file

@ -1279,10 +1279,16 @@ class LueExporter(bpy.types.Operator, ExportHelper):
if t.enabled_prop == False:
continue
x = Object()
x.type = t.type_prop
x.class_name = t.class_name_prop
if t.type_prop == 'Nodes':
x.type = 'Script'
x.class_name = t.nodes_name_prop.replace('.', '_')
else:
x.type = t.type_prop
x.class_name = t.class_name_prop
o.traits.append(x)
if not hasattr(o, 'nodes'):
o.nodes = []
for subnode in node.children: