math_nodes.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. from .node_common import *
  2. from .base_definitions import MantisNode
  3. from .math_nodes_socket_templates import *
  4. def TellClasses():
  5. return [
  6. MathStaticInt,
  7. MathStaticFloat,
  8. MathStaticVector,
  9. ]
  10. def math_operation(operation, a, b):
  11. match operation:
  12. case "ADD":
  13. return a+b
  14. case "SUBTRACT":
  15. return a-b
  16. case "MULTIPLY":
  17. return a*b
  18. case "DIVIDE":
  19. return a/b
  20. case "FLOOR_DIVIDE":
  21. return a//b
  22. case "MODULUS":
  23. return a%b
  24. case "POWER":
  25. return a**b
  26. case "ABSOLUTE":
  27. return abs(a)
  28. case "MAXIMUM":
  29. return max(a, b)
  30. case "MINIMUM":
  31. return min(a, b)
  32. case "GREATER THAN":
  33. return float(a > b)
  34. case "LESS THAN":
  35. return float(a < b)
  36. case "ARCTAN2":
  37. from math import atan2
  38. return atan2(a,b)
  39. case "FLOOR":
  40. from math import floor
  41. return floor(a)
  42. case "CEIL":
  43. from math import ceil
  44. return ceil(a)
  45. case "ROUND":
  46. return round(a)
  47. #*#-------------------------------#++#-------------------------------#*#
  48. # M A T H N O D E S
  49. #*#-------------------------------#++#-------------------------------#*#
  50. class MathStaticInt(MantisNode):
  51. '''A node representing an armature object'''
  52. def __init__(self, signature, base_tree):
  53. super().__init__(signature, base_tree, StaticIntSockets)
  54. self.init_parameters()
  55. self.node_type = "UTILITY"
  56. def bPrepare(self, bContext = None,):
  57. a = self.evaluate_input("Int A"); b = self.evaluate_input("Int B")
  58. result = math_operation(self.evaluate_input("Operation"), a, b)
  59. self.parameters["Result Int"] = int(result)
  60. self.prepared, self.executed = True, True
  61. class MathStaticFloat(MantisNode):
  62. '''A node representing an armature object'''
  63. def __init__(self, signature, base_tree):
  64. super().__init__(signature, base_tree, StaticFloatSockets)
  65. self.init_parameters()
  66. self.node_type = "UTILITY"
  67. def bPrepare(self, bContext = None,):
  68. a = self.evaluate_input("Float A"); b = self.evaluate_input("Float B")
  69. result = math_operation(self.evaluate_input("Operation"), a, b)
  70. self.parameters["Result Float"] = result
  71. self.prepared, self.executed = True, True
  72. class MathStaticVector(MantisNode):
  73. '''A node representing an armature object'''
  74. def __init__(self, signature, base_tree):
  75. super().__init__(signature, base_tree, StaticVectorSockets)
  76. self.init_parameters()
  77. self.node_type = "UTILITY"
  78. def bPrepare(self, bContext = None,):
  79. from mathutils import Vector
  80. a = Vector(self.evaluate_input("Vector A")).copy()
  81. b = Vector(self.evaluate_input("Vector B")).copy()
  82. s = self.evaluate_input("Scalar A")
  83. if hasattr(s, '__iter__'):
  84. average = lambda iterable : sum(iterable)/len(iterable)
  85. s = average(s)
  86. f_result = float("NaN")
  87. v_result = None
  88. if self.evaluate_input("Operation") == "ADD":
  89. v_result = a+b
  90. if self.evaluate_input("Operation") == "SUBTRACT":
  91. v_result = a-b
  92. if self.evaluate_input("Operation") == "MULTIPLY":
  93. v_result = a*b
  94. if self.evaluate_input("Operation") == "DIVIDE":
  95. v_result = Vector((0,0,0)) # channel-wise division
  96. for i, (axis_a, axis_b) in enumerate(zip(a,b)):
  97. v_result[i] = axis_a/axis_b
  98. if self.evaluate_input("Operation") == "POWER":
  99. v_result = a**b
  100. # since these are unary, we need to make a copy lest we create spooky effects elsewhere.
  101. a = a.copy()
  102. if self.evaluate_input("Operation") == "SCALE":
  103. v_result = a.normalized() * s
  104. if self.evaluate_input("Operation") == "LENGTH":
  105. f_result = a.magnitude
  106. if self.evaluate_input("Operation") == "CROSS":
  107. v_result = a.cross(b)
  108. if self.evaluate_input("Operation") == "DOT":
  109. f_result = a.dot(b)
  110. if self.evaluate_input("Operation") == "NORMALIZE":
  111. v_result = a.normalized()
  112. if self.evaluate_input("Operation") == "LINEAR_INTERP":
  113. v_result = a.lerp(b, s).copy()
  114. self.parameters["Result Float"] = f_result
  115. # if v_result:
  116. self.parameters["Result Vector"] = v_result
  117. self.prepared = True
  118. self.executed = True