Did the haxe part of the ongoing update.
Also fixed a ton of bugs in the python part. NOTE: this requires a yet-to-be-done commit to Iron to work.
This commit is contained in:
parent
bd67667a6e
commit
1d0a6d7955
|
@ -19,7 +19,7 @@ class QuaternionMathNode extends LogicNode {
|
||||||
|
|
||||||
override function get(from: Int): Dynamic {
|
override function get(from: Int): Dynamic {
|
||||||
switch (property0) {
|
switch (property0) {
|
||||||
// 1 argument: Module, Normalize, GetEuler
|
// 1 argument: Module, Normalize
|
||||||
case "Module": {
|
case "Module": {
|
||||||
var q: Quat = inputs[0].get();
|
var q: Quat = inputs[0].get();
|
||||||
if (q == null) return null;
|
if (q == null) return null;
|
||||||
|
@ -32,159 +32,106 @@ class QuaternionMathNode extends LogicNode {
|
||||||
res_q.setFrom(q);
|
res_q.setFrom(q);
|
||||||
res_q = res_q.normalize();
|
res_q = res_q.normalize();
|
||||||
}
|
}
|
||||||
case "GetEuler": {
|
|
||||||
var q: Quat = inputs[0].get();
|
|
||||||
if (q == null) return null;
|
|
||||||
res_q.setFrom(q);
|
|
||||||
res_v = res_q.getEuler();
|
|
||||||
}
|
|
||||||
// 2 arguments: FromTo, FromMat, FromRotationMat, ToAxisAngle
|
|
||||||
case "FromTo": {
|
|
||||||
var v1: Vec4 = inputs[0].get();
|
|
||||||
var v2: Vec4 = inputs[1].get();
|
|
||||||
if ((v1 == null) || (v2 == null)) return null;
|
|
||||||
res_q.fromTo(v1, v2);
|
|
||||||
}
|
|
||||||
case "FromMat": {
|
|
||||||
var q: Quat = inputs[0].get();
|
|
||||||
var m: Mat4 = inputs[1].get();
|
|
||||||
if ((q == null) || (m == null)) return null;
|
|
||||||
res_q.setFrom(q);
|
|
||||||
res_q = res_q.fromMat(m);
|
|
||||||
}
|
|
||||||
case "FromRotationMat": {
|
|
||||||
var q: Quat = inputs[0].get();
|
|
||||||
var m: Mat4 = inputs[1].get();
|
|
||||||
if ((q == null) || (m == null)) return null;
|
|
||||||
res_q.setFrom(q);
|
|
||||||
res_q = res_q.fromRotationMat(m);
|
|
||||||
}
|
|
||||||
case "ToAxisAngle": {
|
|
||||||
var q: Quat = inputs[0].get();
|
|
||||||
var v: Vec4 = inputs[1].get();
|
|
||||||
if ((q == null) || (v == null)) return null;
|
|
||||||
res_q.setFrom(q);
|
|
||||||
res_f = res_q.toAxisAngle(v);
|
|
||||||
}
|
|
||||||
// # 3 arguments: Lerp, Slerp, FromAxisAngle, FromEuler
|
|
||||||
case "Lerp": {
|
|
||||||
var from: Quat = inputs[0].get();
|
|
||||||
var to: Quat = inputs[1].get();
|
|
||||||
var f: Float = inputs[2].get();
|
|
||||||
if ((from == null) || (to == null)) return null;
|
|
||||||
res_q = res_q.lerp(from, to, f);
|
|
||||||
}
|
|
||||||
case "Slerp": {
|
|
||||||
var from: Quat = inputs[0].get();
|
|
||||||
var to: Quat = inputs[1].get();
|
|
||||||
var f: Float = inputs[2].get();
|
|
||||||
if ((from == null) || (to == null)) return null;
|
|
||||||
res_q = res_q.slerp(from, to, f);
|
|
||||||
}
|
|
||||||
case "FromAxisAngle": {
|
|
||||||
var q: Quat = inputs[0].get();
|
|
||||||
var axis: Vec4 = inputs[1].get();
|
|
||||||
var angle: Float = inputs[2].get();
|
|
||||||
if ((q == null) || (axis == null)) return null;
|
|
||||||
res_q.setFrom(q);
|
|
||||||
res_q = res_q.fromAxisAngle(axis, angle);
|
|
||||||
}
|
|
||||||
case "FromEuler": {
|
|
||||||
var x: Float = inputs[0].get();
|
|
||||||
var y: Float = inputs[1].get();
|
|
||||||
var z: Float = inputs[2].get();
|
|
||||||
res_q = res_q.fromEuler(x, y, z);
|
|
||||||
}
|
|
||||||
// Many arguments: Add, Subtract, DotProduct, Multiply
|
// Many arguments: Add, Subtract, DotProduct, Multiply
|
||||||
case "Add": {
|
case "Add": {
|
||||||
var q: Quat = inputs[0].get();
|
res_v = inputs[0].get();
|
||||||
if (q == null) return null;
|
res_f = inputs[1].get();
|
||||||
res_q.setFrom(q);
|
if (res_v == null || res_f == null) return null;
|
||||||
var q2 = new Quat();
|
|
||||||
|
res_q.set(res_v.x, res_v.y, res_v.z, res_f);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
while (i < inputs.length) {
|
while (2*i+1 < inputs.length) {
|
||||||
q2 = inputs[i].get();
|
res_v = inputs[2*i].get();
|
||||||
if (q2 == null) return null;
|
res_f = inputs[2*i+1].get();
|
||||||
res_q.add(q2);
|
if (res_v == null || res_f == null) return null;
|
||||||
|
res_q.x += res_v.x;
|
||||||
|
res_q.y += res_v.y;
|
||||||
|
res_q.z += res_v.z;
|
||||||
|
res_q.w += res_f;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "Subtract": {
|
case "Subtract": {
|
||||||
var q: Quat = inputs[0].get();
|
res_v = inputs[0].get();
|
||||||
if (q == null) return null;
|
res_f = inputs[1].get();
|
||||||
res_q.setFrom(q);
|
if (res_v == null || res_f == null) return null;
|
||||||
var q2 = new Quat();
|
|
||||||
|
res_q.set(res_v.x, res_v.y, res_v.z, res_f);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
while (i < inputs.length) {
|
while (2*i+1 < inputs.length) {
|
||||||
q2 = inputs[i].get();
|
res_v = inputs[2*i].get();
|
||||||
if (q2 == null) return null;
|
res_f = inputs[2*i+1].get();
|
||||||
res_q.sub(q2);
|
if (res_v == null || res_f == null) return null;
|
||||||
|
res_q.x -= res_v.x;
|
||||||
|
res_q.y -= res_v.y;
|
||||||
|
res_q.z -= res_v.z;
|
||||||
|
res_q.w -= res_f;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "Multiply": {
|
case "Multiply": {
|
||||||
var q: Quat = inputs[0].get();
|
res_v = inputs[0].get();
|
||||||
if (q == null) return null;
|
res_f = inputs[1].get();
|
||||||
res_q.setFrom(q);
|
if (res_v == null || res_f == null) return null;
|
||||||
var q2 = new Quat();
|
|
||||||
|
res_q.set(res_v.x, res_v.y, res_v.z, res_f);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
while (i < inputs.length) {
|
while (2*i+1 < inputs.length) {
|
||||||
q2 = inputs[i].get();
|
res_v = inputs[2*i].get();
|
||||||
if (q2 == null) return null;
|
res_f = inputs[2*i+1].get();
|
||||||
res_q.mult(q2);
|
if (res_v == null || res_f == null) return null;
|
||||||
|
var temp_q = new Quat(res_v.x, res_v.y, res_v.z, res_f);
|
||||||
|
res_q.mult(temp_q);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "MultiplyFloats": {
|
case "MultiplyFloats": {
|
||||||
var q: Quat = inputs[0].get();
|
res_v = inputs[0].get();
|
||||||
if (q == null) return null;
|
res_f = inputs[1].get();
|
||||||
res_q.setFrom(q);
|
if (res_v == null || res_f == null) return null;
|
||||||
|
|
||||||
|
res_q.set(res_v.x, res_v.y, res_v.z, res_f);
|
||||||
var f: Float = 1.0;
|
var f: Float = 1.0;
|
||||||
var i = 1;
|
var i = 2;
|
||||||
while (i < inputs.length) {
|
while (i < inputs.length) {
|
||||||
f = inputs[i].get();
|
f *= inputs[i].get();
|
||||||
res_q.scale(f);
|
if (f == null) return null;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
res_q.scale(f);
|
||||||
}
|
}
|
||||||
case "DotProduct": {
|
case "DotProduct": { // what this does with more than 2 terms is not *remotely* intuitive. Heck, you could consider it a footgun!
|
||||||
var q: Quat = inputs[0].get();
|
|
||||||
if (q == null) return null;
|
res_v = inputs[0].get();
|
||||||
res_q.setFrom(q);
|
var temp_f = inputs[1].get();
|
||||||
var q2 = new Quat();
|
if (res_v == null || temp_f == null) return null;
|
||||||
|
|
||||||
|
res_q.set(res_v.x, res_v.y, res_v.z, temp_f);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
while (i < inputs.length) {
|
while (2*i+1 < inputs.length) {
|
||||||
q2 = inputs[i].get();
|
res_v = inputs[2*i].get();
|
||||||
if (q2 == null) return null;
|
temp_f = inputs[2*i+1].get();
|
||||||
res_f = res_q.dot(q2);
|
if (res_v == null || temp_f == null) return null;
|
||||||
|
var temp_q = new Quat(res_v.x, res_v.y, res_v.z, temp_f);
|
||||||
|
res_f = res_q.dot(temp_q);
|
||||||
res_q.set(res_f, res_f, res_f, res_f);
|
res_q.set(res_f, res_f, res_f, res_f);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Return and check separator
|
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case 0: {
|
case 0: {
|
||||||
if (property0 == 'GetEuler')
|
return res_q;
|
||||||
return res_v;
|
|
||||||
else
|
|
||||||
return res_q;
|
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
if (property1) {
|
if (property0 == "DotProduct" || property0 == "Module") {
|
||||||
return res_q.x;
|
|
||||||
} else {
|
|
||||||
return res_f;
|
return res_f;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
case 2:
|
default: {
|
||||||
if (property1) return res_q.y;
|
return null;
|
||||||
case 3:
|
}
|
||||||
if (property1) return res_q.z;
|
|
||||||
case 4:
|
|
||||||
if (property1) return res_q.w;
|
|
||||||
case 5:
|
|
||||||
if (property1) return res_f;
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,17 +17,21 @@ class RotationMathNode extends LogicNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
override function get(from: Int): Dynamic {
|
override function get(from: Int): Dynamic {
|
||||||
var q: Quat = inputs[0].get();
|
//var q: Quat = inputs[0].get();
|
||||||
if (q==null) return null;
|
//if (q==null) return null;
|
||||||
|
|
||||||
var res_q: Quat = new Quat();
|
//var res_q: Quat = new Quat();
|
||||||
switch (property0) {
|
switch (property0) {
|
||||||
// 1 argument: Normalize, Inverse
|
// 1 argument: Normalize, Inverse
|
||||||
case "Normalize": {
|
case "Normalize": {
|
||||||
|
var q: Quat = inputs[0].get();
|
||||||
|
if (q==null) return null;
|
||||||
res_q.setFrom(q);
|
res_q.setFrom(q);
|
||||||
res_q = res_q.normalize();
|
res_q = res_q.normalize();
|
||||||
}
|
}
|
||||||
case "Inverse": {
|
case "Inverse": {
|
||||||
|
var q: Quat = inputs[0].get();
|
||||||
|
if (q==null) return null;
|
||||||
var modl = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
|
var modl = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
|
||||||
modl = -1/modl;
|
modl = -1/modl;
|
||||||
res_q.w = -q.w*modl;
|
res_q.w = -q.w*modl;
|
||||||
|
@ -72,17 +76,19 @@ class RotationMathNode extends LogicNode {
|
||||||
// # 3 arguments: Lerp, Slerp, FromAxisAngle, FromEuler
|
// # 3 arguments: Lerp, Slerp, FromAxisAngle, FromEuler
|
||||||
case "Lerp": {
|
case "Lerp": {
|
||||||
//var from = q;
|
//var from = q;
|
||||||
|
var from: Quat = inputs[0].get();
|
||||||
var to: Quat = inputs[1].get();
|
var to: Quat = inputs[1].get();
|
||||||
var f: Float = inputs[2].get();
|
var f: Float = inputs[2].get();
|
||||||
if ((f == null) || (to == null)) return null;
|
if ((from == null) || (f == null) || (to == null)) return null;
|
||||||
res_q = res_q.lerp(q, to, f);
|
res_q = res_q.lerp(from, to, f);
|
||||||
}
|
}
|
||||||
case "Slerp": {
|
case "Slerp": {
|
||||||
//var from = q;
|
//var from = q;
|
||||||
|
var from:Quat = inputs[0].get();
|
||||||
var to: Quat = inputs[1].get();
|
var to: Quat = inputs[1].get();
|
||||||
var f: Float = inputs[2].get();
|
var f: Float = inputs[2].get();
|
||||||
if ((f == null) || (to == null)) return null;
|
if ((from == null) || (f == null) || (to == null)) return null;
|
||||||
res_q = res_q.slerp(q, to, f);
|
res_q = res_q.slerp(from, to, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res_q;
|
return res_q;
|
||||||
|
|
|
@ -38,6 +38,9 @@ class RotationNode extends LogicNode {
|
||||||
//var inp0 = inputs[0].get();
|
//var inp0 = inputs[0].get();
|
||||||
//var inp
|
//var inp
|
||||||
//if (inputs[0].get())
|
//if (inputs[0].get())
|
||||||
|
if (inputs.length == 0){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
switch (property0){
|
switch (property0){
|
||||||
case "Quaternion": {
|
case "Quaternion": {
|
||||||
|
|
|
@ -50,7 +50,7 @@ class SeparateRotationNode extends LogicNode {
|
||||||
case "Deg": return toDEG*aa_angle_cache;
|
case "Deg": return toDEG*aa_angle_cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "Quat":
|
case "Quaternion":
|
||||||
switch(from){
|
switch(from){
|
||||||
case 0: return new Vec4(q.x,q.y,q.z);
|
case 0: return new Vec4(q.x,q.y,q.z);
|
||||||
case 1: return q.w;
|
case 1: return q.w;
|
||||||
|
|
|
@ -7,6 +7,8 @@ import armory.trait.physics.RigidBody;
|
||||||
|
|
||||||
class SetRotationNode extends LogicNode {
|
class SetRotationNode extends LogicNode {
|
||||||
|
|
||||||
|
public var property0: String; // UNUSED
|
||||||
|
|
||||||
public function new(tree: LogicTree) {
|
public function new(tree: LogicTree) {
|
||||||
super(tree);
|
super(tree);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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
|
||||||
|
from arm.logicnode.arm_sockets import ArmCustomSocket
|
||||||
|
|
||||||
# Pass NodeReplacment forward to individual node modules that import arm_nodes
|
# Pass NodeReplacment forward to individual node modules that import arm_nodes
|
||||||
from arm.logicnode.replacement import NodeReplacement
|
from arm.logicnode.replacement import NodeReplacement
|
||||||
|
@ -83,7 +84,13 @@ class ArmLogicTreeNode(bpy.types.Node):
|
||||||
socket = self.inputs.new(socket_type, socket_name)
|
socket = self.inputs.new(socket_type, socket_name)
|
||||||
|
|
||||||
if default_value is not None:
|
if default_value is not None:
|
||||||
socket.default_value = default_value
|
if isinstance(socket, ArmCustomSocket):
|
||||||
|
if socket.arm_socket_type != 'NONE':
|
||||||
|
socket.default_value_raw = default_value
|
||||||
|
else:
|
||||||
|
raise ValueError('specified a default value for an input node that doesn\'t accept one')
|
||||||
|
else:
|
||||||
|
socket.default_value = default_value
|
||||||
|
|
||||||
if is_var and not socket.display_shape.endswith('_DOT'):
|
if is_var and not socket.display_shape.endswith('_DOT'):
|
||||||
socket.display_shape += '_DOT'
|
socket.display_shape += '_DOT'
|
||||||
|
|
|
@ -97,7 +97,7 @@ class ArmRotationSocket(ArmCustomSocket):
|
||||||
|
|
||||||
|
|
||||||
def on_mode_update(self, context):
|
def on_mode_update(self, context):
|
||||||
if self.default_value_mode == 'Quat':
|
if self.default_value_mode == 'Quaternion':
|
||||||
summ = abs(self.default_value_s0)
|
summ = abs(self.default_value_s0)
|
||||||
summ+= abs(self.default_value_s1)
|
summ+= abs(self.default_value_s1)
|
||||||
summ+= abs(self.default_value_s2)
|
summ+= abs(self.default_value_s2)
|
||||||
|
@ -116,10 +116,10 @@ class ArmRotationSocket(ArmCustomSocket):
|
||||||
def convert_to_quaternion(part1,part2,param1,param2,param3):
|
def convert_to_quaternion(part1,part2,param1,param2,param3):
|
||||||
"""converts a representation of rotation into a quaternion.
|
"""converts a representation of rotation into a quaternion.
|
||||||
``part1`` is a vector, ``part2`` is a scalar or None,
|
``part1`` is a vector, ``part2`` is a scalar or None,
|
||||||
``param1`` is in ('Quat', 'EulerAngles', 'AxisAngle'),
|
``param1`` is in ('Quaternion', 'EulerAngles', 'AxisAngle'),
|
||||||
``param2`` is in ('Rad','Deg') for both EulerAngles and AxisAngle,
|
``param2`` is in ('Rad','Deg') for both EulerAngles and AxisAngle,
|
||||||
``param3`` is a len-3 string like "XYZ", for EulerAngles """
|
``param3`` is a len-3 string like "XYZ", for EulerAngles """
|
||||||
if param1 == 'Quat':
|
if param1=='Quaternion':
|
||||||
qx, qy, qz = part1[0], part1[1], part1[2]
|
qx, qy, qz = part1[0], part1[1], part1[2]
|
||||||
qw = part2
|
qw = part2
|
||||||
# need to normalize the quaternion for a rotation (having it be 0 is not an option)
|
# need to normalize the quaternion for a rotation (having it be 0 is not an option)
|
||||||
|
@ -183,7 +183,7 @@ class ArmRotationSocket(ArmCustomSocket):
|
||||||
part1,
|
part1,
|
||||||
self.default_value_s3,
|
self.default_value_s3,
|
||||||
self.default_value_mode,
|
self.default_value_mode,
|
||||||
self.defualt_value_unit,
|
self.default_value_unit,
|
||||||
self.default_value_order
|
self.default_value_order
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ class ArmRotationSocket(ArmCustomSocket):
|
||||||
coll.prop(self, 'default_value_s0', text='X')
|
coll.prop(self, 'default_value_s0', text='X')
|
||||||
coll.prop(self, 'default_value_s1', text='Y')
|
coll.prop(self, 'default_value_s1', text='Y')
|
||||||
coll.prop(self, 'default_value_s2', text='Z')
|
coll.prop(self, 'default_value_s2', text='Z')
|
||||||
elif self.default_value_mode == 'Quat':
|
elif self.default_value_mode == 'Quaternion':
|
||||||
coll.prop(self, 'default_value_s0', text='X')
|
coll.prop(self, 'default_value_s0', text='X')
|
||||||
coll.prop(self, 'default_value_s1', text='Y')
|
coll.prop(self, 'default_value_s1', text='Y')
|
||||||
coll.prop(self, 'default_value_s2', text='Z')
|
coll.prop(self, 'default_value_s2', text='Z')
|
||||||
|
@ -223,7 +223,7 @@ class ArmRotationSocket(ArmCustomSocket):
|
||||||
default_value_mode: EnumProperty(
|
default_value_mode: EnumProperty(
|
||||||
items=[('EulerAngles', 'Euler Angles', 'Euler Angles'),
|
items=[('EulerAngles', 'Euler Angles', 'Euler Angles'),
|
||||||
('AxisAngle', 'Axis/Angle', 'Axis/Angle'),
|
('AxisAngle', 'Axis/Angle', 'Axis/Angle'),
|
||||||
('Quat', 'Quaternion', 'Quaternion')],
|
('Quaternion', 'Quaternion', 'Quaternion')],
|
||||||
name='', default='EulerAngles',
|
name='', default='EulerAngles',
|
||||||
update=on_mode_update)
|
update=on_mode_update)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from arm.logicnode.arm_nodes import *
|
from arm.logicnode.arm_nodes import *
|
||||||
|
from arm.logicnode.arm_sockets import ArmRotationSocket as Rotation
|
||||||
|
|
||||||
class QuaternionMathNode(ArmLogicTreeNode):
|
class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
"""Mathematical operations on quaternions."""
|
"""Mathematical operations on quaternions."""
|
||||||
|
@ -194,7 +195,7 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
|
|
||||||
for link in self.inputs[0].links: # 0 or 1
|
for link in self.inputs[0].links: # 0 or 1
|
||||||
node_tree.links.new(link.from_socket, newself.inputs[0])
|
node_tree.links.new(link.from_socket, newself.inputs[0])
|
||||||
elif self.property0 == 'ToEuler':
|
elif self.property0 == 'FromEuler':
|
||||||
newself = node_tree.nodes.new('LNRotationNode')
|
newself = node_tree.nodes.new('LNRotationNode')
|
||||||
ret.append(newself)
|
ret.append(newself)
|
||||||
preconv = node_tree.nodes.new('LNVectorNode')
|
preconv = node_tree.nodes.new('LNVectorNode')
|
||||||
|
@ -220,7 +221,7 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
newself.property1='Rad'
|
newself.property1='Rad'
|
||||||
|
|
||||||
for link in self.inputs[0].links: # 0 or 1
|
for link in self.inputs[0].links: # 0 or 1
|
||||||
node_tree.links.new(link.from_node, newself.inputs[0])
|
node_tree.links.new(link.from_socket, newself.inputs[0])
|
||||||
elif self.property0 == 'FromAxisAngle':
|
elif self.property0 == 'FromAxisAngle':
|
||||||
newself = node_tree.nodes.new('LNRotationNode')
|
newself = node_tree.nodes.new('LNRotationNode')
|
||||||
ret.append(newself)
|
ret.append(newself)
|
||||||
|
@ -229,22 +230,28 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
|
|
||||||
newself.inputs[0].default_value = self.inputs[1].default_value
|
newself.inputs[0].default_value = self.inputs[1].default_value
|
||||||
for link in self.inputs[1].links: # 0 or 1
|
for link in self.inputs[1].links: # 0 or 1
|
||||||
node_tree.links.new(link.from_node, newself.inputs[0])
|
node_tree.links.new(link.from_socket, newself.inputs[0])
|
||||||
newself.inputs[1].default_value = self.inputs[2].default_value
|
newself.inputs[1].default_value = self.inputs[2].default_value
|
||||||
for link in self.inputs[2].links: # 0 or 1
|
for link in self.inputs[2].links: # 0 or 1
|
||||||
node_tree.links.new(link.from_node, newself.inputs[1])
|
node_tree.links.new(link.from_socket, newself.inputs[1])
|
||||||
elif self.property0 in ('FromMat','FromRotationMat'):
|
elif self.property0 in ('FromMat','FromRotationMat'):
|
||||||
newself = node_tree.nodes.new('LNSeparateTransformNode')
|
newself = node_tree.nodes.new('LNSeparateTransformNode')
|
||||||
ret.append(newself)
|
ret.append(newself)
|
||||||
for link in self.inputs[1].links: # 0 or 1
|
for link in self.inputs[1].links: # 0 or 1
|
||||||
node_tree.links.new(link.from_node, newself.inputs[0])
|
node_tree.links.new(link.from_socket, newself.inputs[0])
|
||||||
|
|
||||||
elif self.property0 in ('Lerp','Slerp','FromTo'):
|
elif self.property0 in ('Lerp','Slerp','FromTo'):
|
||||||
newself = node_tree.nodes.new('LNRotationMathNode')
|
newself = node_tree.nodes.new('LNRotationMathNode')
|
||||||
ret.append(newself)
|
ret.append(newself)
|
||||||
newself.property0 = self.property0
|
newself.property0 = self.property0
|
||||||
|
|
||||||
for in1, in2 in zip(self.inputs, newself.inputs):
|
for in1, in2 in zip(self.inputs, newself.inputs):
|
||||||
if in1.bl_idname in ('NodeSocketFloat', 'NodeSocketVector'):
|
if in2.bl_idname == 'ArmNodeSocketRotation':
|
||||||
|
in2.default_value_raw = Rotation.convert_to_quaternion(
|
||||||
|
in1.default_value,0,
|
||||||
|
'EulerAngles','Rad','XZY'
|
||||||
|
)
|
||||||
|
elif in1.bl_idname in ('NodeSocketFloat', 'NodeSocketVector'):
|
||||||
in2.default_value = in1.default_value
|
in2.default_value = in1.default_value
|
||||||
for link in in1.links:
|
for link in in1.links:
|
||||||
node_tree.links.new(link.from_socket, in2)
|
node_tree.links.new(link.from_socket, in2)
|
||||||
|
@ -264,15 +271,20 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
convnode = node_tree.nodes.new('LNSeparateRotationNode')
|
convnode = node_tree.nodes.new('LNSeparateRotationNode')
|
||||||
convnode.property0 = 'Quaternion'
|
convnode.property0 = 'Quaternion'
|
||||||
ret.append(convnode)
|
ret.append(convnode)
|
||||||
|
if i_in_2 >= len(newself.inputs):
|
||||||
|
newself.ensure_input_socket(i_in_2, 'NodeSocketVector', 'Quaternion %d XYZ'%(i_in_1))
|
||||||
|
newself.ensure_input_socket(i_in_2+1, 'NodeSocketFloat', 'Quaternion %d W'%(i_in_1), 1.0)
|
||||||
node_tree.links.new(convnode.outputs[0], newself.inputs[i_in_2])
|
node_tree.links.new(convnode.outputs[0], newself.inputs[i_in_2])
|
||||||
node_tree.links.new(convnode.outputs[1], newself.inputs[i_in_2+1])
|
node_tree.links.new(convnode.outputs[1], newself.inputs[i_in_2+1])
|
||||||
for link in in1.links:
|
for link in in1.links:
|
||||||
node_tree.links.new(link.from_socket, convnode.inputs[0])
|
node_tree.links.new(link.from_socket, convnode.inputs[0])
|
||||||
i_in_2 +=1
|
i_in_2 +=2
|
||||||
i_in_1 +=2
|
i_in_1 +=1
|
||||||
elif in1.bl_idname == 'NodeSocketfloat':
|
elif in1.bl_idname == 'NodeSocketFloat':
|
||||||
for link in in1.links:
|
for link in in1.links:
|
||||||
node_tree.links.new(link.from_socket, newself.inputs[i_in_2])
|
node_tree.links.new(link.from_socket, newself.inputs[i_in_2])
|
||||||
|
i_in_1 +=1
|
||||||
|
i_in_2 +=1
|
||||||
else:
|
else:
|
||||||
raise ValueError('get_replacement_node() for is not LNQuaternionMathNode V1->V2 is not prepared to deal with an input socket of type %s. This is a bug to report to the developers' %in1.bl_idname)
|
raise ValueError('get_replacement_node() for is not LNQuaternionMathNode V1->V2 is not prepared to deal with an input socket of type %s. This is a bug to report to the developers' %in1.bl_idname)
|
||||||
|
|
||||||
|
@ -281,7 +293,8 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
if self.property0 in ('FromEuler','FromMat','FromRotationMat','FromAxisAngle','Lerp','Slerp','FromTo'):
|
if self.property0 in ('FromEuler','FromMat','FromRotationMat','FromAxisAngle','Lerp','Slerp','FromTo'):
|
||||||
# the new self returns a rotation
|
# the new self returns a rotation
|
||||||
for link in self.outputs[0].links:
|
for link in self.outputs[0].links:
|
||||||
node_tree.links.new(newself.outputs[0], link.to_socket)
|
out_sock_i = int( self.property0.endswith('Mat') )
|
||||||
|
node_tree.links.new(newself.outputs[out_sock_i], link.to_socket)
|
||||||
elif self.property0 in ('DotProduct','Module'):
|
elif self.property0 in ('DotProduct','Module'):
|
||||||
# new self returns a float
|
# new self returns a float
|
||||||
for link in self.outputs[1 + 4*int(self.property1)].links:
|
for link in self.outputs[1 + 4*int(self.property1)].links:
|
||||||
|
@ -328,13 +341,22 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
conv = node_tree.nodes.new('LNSeparateVectorNode')
|
conv = node_tree.nodes.new('LNSeparateVectorNode')
|
||||||
ret.append(conv)
|
ret.append(conv)
|
||||||
node_tree.links.new(newself.outputs[0], conv.inputs[0])
|
node_tree.links.new(newself.outputs[0], conv.inputs[0])
|
||||||
for link in xlinks:
|
for link in xlinks:
|
||||||
node_tree.links.new(conv.outputs[0], link.to_socket)
|
node_tree.links.new(conv.outputs[0], link.to_socket)
|
||||||
for link in ylinks:
|
for link in ylinks:
|
||||||
node_tree.links.new(conv.outputs[1], link.to_socket)
|
node_tree.links.new(conv.outputs[1], link.to_socket)
|
||||||
for link in zlinks:
|
for link in zlinks:
|
||||||
node_tree.links.new(conv.outputs[2], link.to_socket)
|
node_tree.links.new(conv.outputs[2], link.to_socket)
|
||||||
|
|
||||||
|
for node in ret: # update the labels on the node's displays
|
||||||
|
if node.bl_idname == 'LNSeparateRotationNode':
|
||||||
|
node.on_property_update(None)
|
||||||
|
elif node.bl_idname == 'LNRotationNode':
|
||||||
|
node.on_property_update(None)
|
||||||
|
elif node.bl_idname == 'LNRotationMathNode':
|
||||||
|
node.on_update_operation(None)
|
||||||
|
elif node.bl_idname == 'LNQuaternionMathNode':
|
||||||
|
node.set_enum(node.get_enum())
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from arm.logicnode.arm_nodes import *
|
from arm.logicnode.arm_nodes import *
|
||||||
|
from mathutils import Vector
|
||||||
|
|
||||||
class QuaternionMathNode(ArmLogicTreeNode):
|
class RotationMathNode(ArmLogicTreeNode):
|
||||||
"""Mathematical operations on rotations."""
|
"""Mathematical operations on rotations."""
|
||||||
bl_idname = 'LNRotationMathNode'
|
bl_idname = 'LNRotationMathNode'
|
||||||
bl_label = 'Rotation Math'
|
bl_label = 'Rotation Math'
|
||||||
|
@ -54,7 +55,7 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
for socket in sink_sockets:
|
for socket in sink_sockets:
|
||||||
self.id_data.links.new(self.inputs[socket_number], socket)
|
self.id_data.links.new(self.inputs[socket_number], socket)
|
||||||
|
|
||||||
def on_update_operation(self, context):
|
def on_property_update(self, context):
|
||||||
# Checking the selection of another operation
|
# Checking the selection of another operation
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,13 +74,13 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
self.ensure_input_socket(2, "NodeSocketFloat", "Interpolation factor")
|
self.ensure_input_socket(2, "NodeSocketFloat", "Interpolation factor")
|
||||||
|
|
||||||
elif self.property0 == 'FromTo':
|
elif self.property0 == 'FromTo':
|
||||||
self.ensure_input_socket(0, "ArmNodeSocketRotation", "From")
|
self.ensure_input_socket(0, "NodeSocketVector", "From")
|
||||||
self.ensure_input_socket(1, "ArmNodeSocketRotation", "To")
|
self.ensure_input_socket(1, "NodeSocketVector", "To")
|
||||||
|
|
||||||
# Rotation as argument 1:
|
# Rotation as argument 1:
|
||||||
if self.property0 in ('Compose','Lerp','Slerp'):
|
if self.property0 in ('Compose','Lerp','Slerp'):
|
||||||
if self.inputs[1].bl_idname != "ArmNodeSocketRotation":
|
if self.inputs[1].bl_idname != "ArmNodeSocketRotation":
|
||||||
self.replace_input_socket(1, "ArmNodeSocketRotation", "Quaternion 2")
|
self.replace_input_socket(1, "ArmNodeSocketRotation", "Rotation 2")
|
||||||
if self.property0 == 'Compose':
|
if self.property0 == 'Compose':
|
||||||
self.inputs[1].name = "Inner quaternion"
|
self.inputs[1].name = "Inner quaternion"
|
||||||
# Float as argument 1:
|
# Float as argument 1:
|
||||||
|
@ -105,15 +106,15 @@ class QuaternionMathNode(ArmLogicTreeNode):
|
||||||
('FromTo', 'From To', 'From direction To direction'),
|
('FromTo', 'From To', 'From direction To direction'),
|
||||||
#('FromRotationMat', 'From Rotation Mat', 'From Rotation Mat')
|
#('FromRotationMat', 'From Rotation Mat', 'From Rotation Mat')
|
||||||
],
|
],
|
||||||
name='', default='Compose', update=on_update_operation)
|
name='', default='Compose', update=on_property_update)
|
||||||
|
|
||||||
#def __init__(self):
|
#def __init__(self):
|
||||||
# array_nodes[str(id(self))] = self
|
# array_nodes[str(id(self))] = self
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
super(QuaternionMathNode, self).init(context)
|
super(RotationMathNode, self).init(context)
|
||||||
self.add_input('ArmNodeSocketRotation', 'Quaternion 0', default_value=[0.0, 0.0, 0.0])
|
self.add_input('ArmNodeSocketRotation', 'Outer rotation', default_value=Vector((0.0, 0.0, 0.0, 1.0)) )
|
||||||
self.add_input('ArmNodeSocketRotation', 'Quaternion 1', default_value=[0.0, 0.0, 0.0])
|
self.add_input('ArmNodeSocketRotation', 'Inner rotation', default_value=Vector((0.0, 0.0, 0.0, 1.0)))
|
||||||
self.add_output('ArmNodeSocketRotation', 'Result')
|
self.add_output('ArmNodeSocketRotation', 'Result')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
@ -17,13 +17,13 @@ class SeparateRotationNode(ArmLogicTreeNode):
|
||||||
|
|
||||||
def on_property_update(self, context):
|
def on_property_update(self, context):
|
||||||
"""called by the EnumProperty, used to update the node socket labels"""
|
"""called by the EnumProperty, used to update the node socket labels"""
|
||||||
if self.property0 == "Quat":
|
if self.property0 == 'Quaternion':
|
||||||
self.outputs[0].name = "Quaternion XYZ"
|
self.outputs[0].name = "Quaternion XYZ"
|
||||||
self.outputs[1].name = "Quaternion W"
|
self.outputs[1].name = "Quaternion W"
|
||||||
elif self.property0 == "EulerAngles":
|
elif self.property0 == 'EulerAngles':
|
||||||
self.outputs[0].name = "Euler Angles"
|
self.outputs[0].name = "Euler Angles"
|
||||||
self.outputs[1].name = "[unused for Euler output]"
|
self.outputs[1].name = "[unused for Euler output]"
|
||||||
elif self.property0.startswith("AxisAngle"):
|
elif self.property0 == 'AxisAngle':
|
||||||
self.outputs[0].name = "Axis"
|
self.outputs[0].name = "Axis"
|
||||||
self.outputs[1].name = "Angle"
|
self.outputs[1].name = "Angle"
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue