forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
140
leenkx/blender/lnx/logicnode/physics/LN_Add_rigid_body.py
Normal file
140
leenkx/blender/lnx/logicnode/physics/LN_Add_rigid_body.py
Normal file
@ -0,0 +1,140 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class AddRigidBodyNode(LnxLogicTreeNode):
|
||||
"""Adds a rigid body to an object if not already present.
|
||||
|
||||
@option Advanced: Shows optional advanced options for rigid body.
|
||||
|
||||
@option Shape: Shape of the rigid body including Box, Sphere, Capsule, Cone, Cylinder, Convex Hull and Mesh
|
||||
|
||||
@input Object: Object to which rigid body is added.
|
||||
|
||||
@input Mass: Mass of the rigid body. Must be > 0.
|
||||
|
||||
@input Active: Rigid body actively participates in the physics world and will be affected by collisions
|
||||
|
||||
@input Animated: Rigid body follows animation and will affect other active non-animated rigid bodies.
|
||||
|
||||
@input Trigger: Rigid body behaves as a trigger and detects collision. However, rigd body does not contribute to or receive collissions.
|
||||
|
||||
@input Friction: Surface friction of the rigid body. Minimum value = 0, Preferred max value = 1.
|
||||
|
||||
@input Bounciness: How elastic is the surface of the rigid body. Minimum value = 0, Preferred max value = 1.
|
||||
|
||||
@input Continuous Collision Detection (CCD): Detects for collisions in between frames. Use only for very fast moving objects.
|
||||
|
||||
@input Collision Margin: Enable an external margin for collision detection
|
||||
|
||||
@input Margin: Length of the collision margin. Must be > 0.
|
||||
|
||||
@input Linear Damping: Damping for linear translation. Recommended range 0 to 1.
|
||||
|
||||
@input Angular Damping: Damping for angular translation. Recommended range 0 to 1.
|
||||
|
||||
@input Angular Friction: Rolling or angular friction. Recommended range >= 0
|
||||
|
||||
@input Use Deactivation: Deactive this rigid body when below the Linear and Angular velocity threshold. Enable to improve performance.
|
||||
|
||||
@input Linear Velocity Threshold: Velocity below which decativation occurs if enabled.
|
||||
|
||||
@input Angular Velocity Threshold: Velocity below which decativation occurs if enabled.
|
||||
|
||||
@input Collision Group: A set of rigid bodies that can interact with each other
|
||||
|
||||
@input Collision Mask: Bitmask to filter collisions. Collision can occur between two rigid bodies if they have atleast one bit in common.
|
||||
|
||||
@output Rigid body: Object to which rigid body was added.
|
||||
|
||||
@output Out: activated after rigid body is added.
|
||||
"""
|
||||
|
||||
bl_idname = 'LNAddRigidBodyNode'
|
||||
bl_label = 'Add Rigid Body'
|
||||
lnx_version = 2
|
||||
|
||||
NUM_STATIC_INS = 9
|
||||
|
||||
def update_advanced(self, context):
|
||||
"""This is a helper method to allow declaring the `advanced`
|
||||
property before the update_sockets() method. It's not required
|
||||
but then you would need to move the declaration of `advanced`
|
||||
further down."""
|
||||
self.update_sockets(context)
|
||||
|
||||
property1: HaxeBoolProperty(
|
||||
'property1',
|
||||
name="Advanced",
|
||||
description="Show advanced options",
|
||||
default=False,
|
||||
update=update_advanced
|
||||
)
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Box', 'Box', 'Box'),
|
||||
('Sphere', 'Sphere', 'Sphere'),
|
||||
('Capsule', 'Capsule', 'Capsule'),
|
||||
('Cone', 'Cone', 'Cone'),
|
||||
('Cylinder', 'Cylinder', 'Cylinder'),
|
||||
('Convex Hull', 'Convex Hull', 'Convex Hull'),
|
||||
('Mesh', 'Mesh', 'Mesh')],
|
||||
name='Shape', default='Box')
|
||||
|
||||
def lnx_init(self, context):
|
||||
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxFloatSocket', 'Mass', 1.0)
|
||||
self.add_input('LnxBoolSocket', 'Active', True)
|
||||
self.add_input('LnxBoolSocket', 'Animated', False)
|
||||
self.add_input('LnxBoolSocket', 'Trigger', False)
|
||||
self.add_input('LnxFloatSocket', 'Friction', 0.5)
|
||||
self.add_input('LnxFloatSocket', 'Bounciness', 0.0)
|
||||
self.add_input('LnxBoolSocket', 'Continuous Collision Detection', False)
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxNodeSocketObject', 'Rigid body')
|
||||
|
||||
self.update_sockets(context)
|
||||
|
||||
def update_sockets(self, context):
|
||||
# It's bad to remove from a list during iteration so we use
|
||||
# this helper list here
|
||||
remove_list = []
|
||||
|
||||
# Remove dynamically placed input sockets
|
||||
for i in range(AddRigidBodyNode.NUM_STATIC_INS, len(self.inputs)):
|
||||
remove_list.append(self.inputs[i])
|
||||
for i in remove_list:
|
||||
self.inputs.remove(i)
|
||||
|
||||
# Add dynamic input sockets
|
||||
if self.property1:
|
||||
self.add_input('LnxBoolSocket', 'Collision Margin', False)
|
||||
self.add_input('LnxFloatSocket', 'Margin', 0.04)
|
||||
self.add_input('LnxFloatSocket', 'Linear Damping', 0.04)
|
||||
self.add_input('LnxFloatSocket', 'Angular Damping', 0.1)
|
||||
self.add_input('LnxFloatSocket', 'Angular Friction', 0.1)
|
||||
self.add_input('LnxBoolSocket', 'Use Deacivation')
|
||||
self.add_input('LnxFloatSocket', 'Linear Velocity Threshold', 0.4)
|
||||
self.add_input('LnxFloatSocket', 'Angular Velocity Threshold', 0.5)
|
||||
self.add_input('LnxIntSocket', 'Collision Group', 1)
|
||||
self.add_input('LnxIntSocket', 'Collision Mask', 1)
|
||||
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, "property1")
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||
if self.lnx_version not in (0, 1):
|
||||
raise LookupError()
|
||||
|
||||
in_socket_mapping={0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8}
|
||||
if self.property1:
|
||||
in_socket_mapping.update({9:9, 10:10, 11:11, 12:12, 13:14, 14:15, 15:16, 16:17, 17:18})
|
||||
|
||||
return NodeReplacement(
|
||||
'LNAddRigidBodyNode', self.lnx_version, 'LNAddRigidBodyNode', 2,
|
||||
in_socket_mapping=in_socket_mapping,
|
||||
out_socket_mapping={0:0, 1:1},
|
||||
property_mapping={'property0':'property0', 'property1':'property1'})
|
@ -0,0 +1,176 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class AddPhysicsConstraintNode(LnxLogicTreeNode):
|
||||
"""
|
||||
Add a physics constraint to constrain two rigid bodies if not already present.
|
||||
|
||||
@option Fixed: No fredom of movement. Relative positions and rotations of rigid bodies are fixed
|
||||
|
||||
@option Point: Both rigid bodies are constrained at the pivot object.
|
||||
|
||||
@option Hinge: Constrained objects can move only along angular Z axis of the pivot object.
|
||||
|
||||
@option Slider: Constrained objects can move only along linear X axis of the pivot object.
|
||||
|
||||
@option Piston: Constrained objects can move only and rotate along X axis of the pivot object.
|
||||
|
||||
@option GenericSpring: Fully custimizable generic 6 degree of freedom constraint with optional springs. All liner and angular axes can be constrained
|
||||
along with spring options. Use `Physics Constraint Node` to set a combination of constraints and springs.
|
||||
|
||||
@seeNode Physics Constraint
|
||||
|
||||
@input Pivot object: The object to which the physics constraint traint is applied. This object will not be affected by the constraint
|
||||
but is necessary to specify the constraint axes and location. Hence, the pivot object need not be a rigid body. Typically an `Empty`
|
||||
object may be used. Each pivot object can have only one constraint trait applied. Moving/rotating/parenting the pivot object after the constraint
|
||||
is applied has no effect. However, removig the pivot object removes the constraint and `RB 1` and `RB 2` are no longer constrained.
|
||||
|
||||
@input RB 1: The first rigid body to be constrained. Must be a rigid body. This object can be constrained by more than one constraint.
|
||||
|
||||
@input RB 2: The second rigid body to be constrained. Must be a rigid body. This object can be constrained by more than one constraint.
|
||||
|
||||
@input Disable Collisions: Disable collisions between `RB 1` and `RB 2`
|
||||
|
||||
@input Breakable: Constraint can break if stress on the constraint is more than the set threshold. Disable this option to disable breaking.
|
||||
|
||||
@input Breaking threshold: Stress on the constraint above which the constraint breaks. Depends on the mass, velocity of rigid bodies and type of constraint.
|
||||
|
||||
@input Limit Lower: Lower limit of the consraint in that particular axis
|
||||
|
||||
@input Limit Upper: Upper limit of the constraint in that particular axis. (`lower limit` = `upper limit`) --> Fully constrained. (`lower limit` < `upper limit`) --> Partially constrained
|
||||
(`lower limit` > `upper limit`) --> Full freedom.
|
||||
|
||||
@input Angular limits: Limits to constarin rotation. Specified in degrees. Range (-360 to +360)
|
||||
|
||||
@input Add Constarint: Option to add custom constraint to `Generic Spring` type.
|
||||
"""
|
||||
|
||||
|
||||
bl_idname = 'LNAddPhysicsConstraintNode'
|
||||
bl_label = 'Add Physics Constraint'
|
||||
lnx_section = 'add'
|
||||
lnx_version = 1
|
||||
|
||||
@staticmethod
|
||||
def get_enum_id_value(obj, prop_name, value):
|
||||
return obj.bl_rna.properties[prop_name].enum_items[value].identifier
|
||||
|
||||
@staticmethod
|
||||
def get_count_in(type_name):
|
||||
return {
|
||||
'Fixed': 0,
|
||||
'Point': 1,
|
||||
'Hinge': 2,
|
||||
'Slider': 3,
|
||||
'Piston': 4,
|
||||
'Generic Spring': 5
|
||||
}.get(type_name, 0)
|
||||
|
||||
def get_enum(self):
|
||||
return self.get('property0', 0)
|
||||
|
||||
def set_enum(self, value):
|
||||
# Checking the selection of another type
|
||||
select_current = self.get_enum_id_value(self, 'property0', value)
|
||||
select_prev = self.property0
|
||||
|
||||
#Check if a different type is selected
|
||||
if select_prev != select_current:
|
||||
print('New value selected')
|
||||
# Arguements for type Fixed
|
||||
if (self.get_count_in(select_current) == 0):
|
||||
while (len(self.inputs) > 7):
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
|
||||
# Arguements for type Point
|
||||
if (self.get_count_in(select_current) == 1):
|
||||
while (len(self.inputs) > 7):
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
|
||||
#Arguements for type Hinge
|
||||
if (self.get_count_in(select_current) == 2):
|
||||
while (len(self.inputs) > 7):
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
#Z ang limits
|
||||
self.add_input('LnxBoolSocket', 'Z angle')
|
||||
self.add_input('LnxFloatSocket', 'Z ang lower', -45.0)
|
||||
self.add_input('LnxFloatSocket', 'Z ang upper', 45.0)
|
||||
|
||||
#Arguements for type Slider
|
||||
if (self.get_count_in(select_current) == 3):
|
||||
while (len(self.inputs) > 7):
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
#X lin limits
|
||||
self.add_input('LnxBoolSocket', 'X linear')
|
||||
self.add_input('LnxFloatSocket', 'X lin lower')
|
||||
self.add_input('LnxFloatSocket', 'X lin upper')
|
||||
|
||||
#Arguements for type Piston
|
||||
if (self.get_count_in(select_current) == 4):
|
||||
while (len(self.inputs) > 7):
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
#X lin limits
|
||||
self.add_input('LnxBoolSocket', 'X linear')
|
||||
self.add_input('LnxFloatSocket', 'X lin lower')
|
||||
self.add_input('LnxFloatSocket', 'X lin upper')
|
||||
#X ang limits
|
||||
self.add_input('LnxBoolSocket', 'X angle')
|
||||
self.add_input('LnxFloatSocket', 'X ang lower', -45.0)
|
||||
self.add_input('LnxFloatSocket', 'X ang upper', 45.0)
|
||||
|
||||
#Arguements for type GenericSpring
|
||||
if (self.get_count_in(select_current) == 5):
|
||||
while (len(self.inputs) > 7):
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
|
||||
self['property0'] = value
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Fixed', 'Fixed', 'Fixed'),
|
||||
('Point', 'Point', 'Point'),
|
||||
('Hinge', 'Hinge', 'Hinge'),
|
||||
('Slider', 'Slider', 'Slider'),
|
||||
('Piston', 'Piston', 'Piston'),
|
||||
('Generic Spring', 'Generic Spring', 'Generic Spring')],
|
||||
name='Type', default='Fixed', set=set_enum, get=get_enum)
|
||||
|
||||
def __init__(self):
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Pivot Object')
|
||||
self.add_input('LnxNodeSocketObject', 'RB 1')
|
||||
self.add_input('LnxNodeSocketObject', 'RB 2')
|
||||
self.add_input('LnxBoolSocket', 'Disable Collissions')
|
||||
self.add_input('LnxBoolSocket', 'Breakable')
|
||||
self.add_input('LnxFloatSocket', 'Breaking Threshold')
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
#GenericSpring:
|
||||
if (self.get_count_in(self.property0) == 5):
|
||||
grid0 = layout.grid_flow(row_major=True, columns=1, align=True)
|
||||
grid0.label(text="Possible Constraints:")
|
||||
grid0.label(text="Linear [X, Y, Z]")
|
||||
grid0.label(text="Angular [X, Y, Z]")
|
||||
grid0.label(text="Spring Linear [X, Y, Z]")
|
||||
grid0.label(text="Spring Angular [X, Y, Z]")
|
||||
row = layout.row(align=True)
|
||||
column = row.column(align=True)
|
||||
op = column.operator('lnx.node_add_input', text='Add Constraint', icon='PLUS', emboss=True)
|
||||
op.node_index = str(id(self))
|
||||
op.socket_type = 'LnxDynamicSocket'
|
||||
op.name_format = 'Constraint {0}'.format(len(self.inputs) - 6)
|
||||
column1 = row.column(align=True)
|
||||
op = column1.operator('lnx.node_remove_input', text='', icon='X', emboss=True)
|
||||
op.node_index = str(id(self))
|
||||
#Static inputs
|
||||
if len(self.inputs) < 8:
|
||||
column1.enabled = False
|
||||
#Max Possible inputs
|
||||
if len(self.inputs) > 18:
|
||||
column.enabled = False
|
||||
|
25
leenkx/blender/lnx/logicnode/physics/LN_apply_force.py
Normal file
25
leenkx/blender/lnx/logicnode/physics/LN_apply_force.py
Normal file
@ -0,0 +1,25 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ApplyForceNode(LnxLogicTreeNode):
|
||||
"""Applies force in the given rigid body.
|
||||
|
||||
@seeNode Apply Force At Location
|
||||
@seeNode Apply Impulse
|
||||
@seeNode Apply Impulse At Location
|
||||
|
||||
@input Force: the force vector
|
||||
@input On Local Axis: if `true`, interpret the force vector as in
|
||||
object space
|
||||
"""
|
||||
bl_idname = 'LNApplyForceNode'
|
||||
bl_label = 'Apply Force'
|
||||
lnx_section = 'force'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Force')
|
||||
self.add_input('LnxBoolSocket', 'On Local Axis')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
@ -0,0 +1,30 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ApplyForceAtLocationNode(LnxLogicTreeNode):
|
||||
"""Applies force in the given rigid body at the given position.
|
||||
|
||||
@seeNode Apply Force
|
||||
@seeNode Apply Impulse
|
||||
@seeNode Apply Impulse At Location
|
||||
|
||||
@input Force: the force vector
|
||||
@input Force On Local Axis: if `true`, interpret the force vector as in
|
||||
object space
|
||||
@input Location: the location where to apply the force
|
||||
@input Relative Location: if `true`, use the location relative
|
||||
to the objects location, otherwise use world coordinates
|
||||
"""
|
||||
bl_idname = 'LNApplyForceAtLocationNode'
|
||||
bl_label = 'Apply Force At Location'
|
||||
lnx_section = 'force'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Force')
|
||||
self.add_input('LnxBoolSocket', 'Force On Local Axis')
|
||||
self.add_input('LnxVectorSocket', 'Location')
|
||||
self.add_input('LnxBoolSocket', 'Relative Location')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
25
leenkx/blender/lnx/logicnode/physics/LN_apply_impulse.py
Normal file
25
leenkx/blender/lnx/logicnode/physics/LN_apply_impulse.py
Normal file
@ -0,0 +1,25 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ApplyImpulseNode(LnxLogicTreeNode):
|
||||
"""Applies impulse in the given rigid body.
|
||||
|
||||
@seeNode Apply Impulse At Location
|
||||
@seeNode Apply Force
|
||||
@seeNode Apply Force At Location
|
||||
|
||||
@input Impulse: the impulse vector
|
||||
@input On Local Axis: if `true`, interpret the impulse vector as in
|
||||
object space
|
||||
"""
|
||||
bl_idname = 'LNApplyImpulseNode'
|
||||
bl_label = 'Apply Impulse'
|
||||
lnx_section = 'force'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Impulse')
|
||||
self.add_input('LnxBoolSocket', 'On Local Axis')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
@ -0,0 +1,30 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ApplyImpulseAtLocationNode(LnxLogicTreeNode):
|
||||
"""Applies impulse in the given rigid body at the given position.
|
||||
|
||||
@seeNode Apply Impulse
|
||||
@seeNode Apply Force
|
||||
@seeNode Apply Force At Location
|
||||
|
||||
@input Impulse: the impulse vector
|
||||
@input Impulse On Local Axis: if `true`, interpret the impulse vector as in
|
||||
object space
|
||||
@input Location: the location where to apply the impulse
|
||||
@input Relative Location: if `true`, use the location relative
|
||||
to the objects location, otherwise use world coordinates
|
||||
"""
|
||||
bl_idname = 'LNApplyImpulseAtLocationNode'
|
||||
bl_label = 'Apply Impulse At Location'
|
||||
lnx_section = 'force'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Impulse')
|
||||
self.add_input('LnxBoolSocket', 'Impulse On Local Axis')
|
||||
self.add_input('LnxVectorSocket', 'Location')
|
||||
self.add_input('LnxBoolSocket', 'Relative Location')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
16
leenkx/blender/lnx/logicnode/physics/LN_apply_torque.py
Normal file
16
leenkx/blender/lnx/logicnode/physics/LN_apply_torque.py
Normal file
@ -0,0 +1,16 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ApplyTorqueNode(LnxLogicTreeNode):
|
||||
"""Applies torque to the given rigid body."""
|
||||
bl_idname = 'LNApplyTorqueNode'
|
||||
bl_label = 'Apply Torque'
|
||||
lnx_section = 'force'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Torque')
|
||||
self.add_input('LnxBoolSocket', 'On Local Axis')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
@ -0,0 +1,16 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ApplyTorqueImpulseNode(LnxLogicTreeNode):
|
||||
"""Applies torque impulse in the given rigid body."""
|
||||
bl_idname = 'LNApplyTorqueImpulseNode'
|
||||
bl_label = 'Apply Torque Impulse'
|
||||
lnx_section = 'force'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Torque')
|
||||
self.add_input('LnxBoolSocket', 'On Local Axis')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
34
leenkx/blender/lnx/logicnode/physics/LN_convex_cast.py
Normal file
34
leenkx/blender/lnx/logicnode/physics/LN_convex_cast.py
Normal file
@ -0,0 +1,34 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ConvexCastNode(LnxLogicTreeNode):
|
||||
"""Casts a convex rigid body and get the closest hit point. Also called Convex Sweep Test.
|
||||
|
||||
@seeNode Mask
|
||||
|
||||
@input Convex RB: A convex Rigid Body object to be used for the sweep test.
|
||||
@input From: The initial location of the convex object.
|
||||
@input To: The final location of the convex object.
|
||||
@input Rotation: Rotation of the Convex RB during sweep test.
|
||||
@input Mask: A bit mask value to specify which
|
||||
objects are considered
|
||||
|
||||
@output Hit Position: The hit position in world coordinates
|
||||
@output Convex Position: Position of the convex RB at the time of collision.
|
||||
@output Normal: The surface normal of the hit position relative to
|
||||
the world.
|
||||
"""
|
||||
bl_idname = 'LNPhysicsConvexCastNode'
|
||||
bl_label = 'Convex Cast'
|
||||
lnx_section = 'ray'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'Convex RB')
|
||||
self.add_input('LnxVectorSocket', 'From')
|
||||
self.add_input('LnxVectorSocket', 'To')
|
||||
self.add_input('LnxRotationSocket', 'Rotation')
|
||||
self.add_input('LnxIntSocket', 'Mask', default_value=1)
|
||||
|
||||
self.add_output('LnxVectorSocket', 'Hit Position')
|
||||
self.add_output('LnxVectorSocket', 'Convex Position')
|
||||
self.add_output('LnxVectorSocket', 'Normal')
|
38
leenkx/blender/lnx/logicnode/physics/LN_convex_cast_on.py
Normal file
38
leenkx/blender/lnx/logicnode/physics/LN_convex_cast_on.py
Normal file
@ -0,0 +1,38 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ConvexCastOnNode(LnxLogicTreeNode):
|
||||
"""Casts a convex rigid body and get the closest hit point. Also called Convex Sweep Test.
|
||||
|
||||
@seeNode Mask
|
||||
|
||||
@input In: Input trigger
|
||||
@input Convex RB: A convex Rigid Body object to be used for the sweep test.
|
||||
@input From: The initial location of the convex object.
|
||||
@input To: The final location of the convex object.
|
||||
@input Rotation: Rotation of the Convex RB during sweep test.
|
||||
@input Mask: A bit mask value to specify which
|
||||
objects are considered
|
||||
|
||||
@output Out: Output after hit
|
||||
@output Hit Position: The hit position in world coordinates
|
||||
@output Convex Position: Position of the convex RB at the time of collision.
|
||||
@output Normal: The surface normal of the hit position relative to
|
||||
the world.
|
||||
"""
|
||||
bl_idname = 'LNPhysicsConvexCastOnNode'
|
||||
bl_label = 'Convex Cast On'
|
||||
lnx_section = 'ray'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Convex RB')
|
||||
self.add_input('LnxVectorSocket', 'From')
|
||||
self.add_input('LnxVectorSocket', 'To')
|
||||
self.add_input('LnxRotationSocket', 'Rotation')
|
||||
self.add_input('LnxIntSocket', 'Mask', default_value=1)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxVectorSocket', 'Hit Position')
|
||||
self.add_output('LnxVectorSocket', 'Convex Position')
|
||||
self.add_output('LnxVectorSocket', 'Normal')
|
17
leenkx/blender/lnx/logicnode/physics/LN_get_rb_contacts.py
Normal file
17
leenkx/blender/lnx/logicnode/physics/LN_get_rb_contacts.py
Normal file
@ -0,0 +1,17 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetContactsNode(LnxLogicTreeNode):
|
||||
"""Returns an array with all objects that are colliding with the
|
||||
given object.
|
||||
|
||||
@seeNode Get First Contact
|
||||
"""
|
||||
bl_idname = 'LNGetContactsNode'
|
||||
bl_label = 'Get RB Contacts'
|
||||
lnx_section = 'contact'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
|
||||
self.add_output('LnxNodeSocketArray', 'Contacts')
|
26
leenkx/blender/lnx/logicnode/physics/LN_get_rb_data.py
Normal file
26
leenkx/blender/lnx/logicnode/physics/LN_get_rb_data.py
Normal file
@ -0,0 +1,26 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetRigidBodyDataNode(LnxLogicTreeNode):
|
||||
"""Returns the data of the given rigid body."""
|
||||
bl_idname = 'LNGetRigidBodyDataNode'
|
||||
bl_label = 'Get RB Data'
|
||||
lnx_section = 'props'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketObject', 'Object')
|
||||
|
||||
self.outputs.new('LnxBoolSocket', 'Is RB')
|
||||
self.outputs.new('LnxIntSocket', 'Collision Group')
|
||||
self.outputs.new('LnxIntSocket', 'Collision Mask')
|
||||
self.outputs.new('LnxBoolSocket', 'Is Animated')
|
||||
self.outputs.new('LnxBoolSocket', 'Is Static')
|
||||
self.outputs.new('LnxFloatSocket', 'Angular Damping')
|
||||
self.outputs.new('LnxFloatSocket', 'Linear Damping')
|
||||
self.outputs.new('LnxFloatSocket', 'Friction')
|
||||
self.outputs.new('LnxFloatSocket', 'Mass')
|
||||
#self.outputs.new('LnxStringSocket', 'Collision Shape')
|
||||
#self.outputs.new('LnxIntSocket', 'Activation State')
|
||||
#self.outputs.new('LnxBoolSocket', 'Is Gravity Enabled')
|
||||
#self.outputs.new(LnxVectorSocket', Angular Factor')
|
||||
#self.outputs.new('LnxVectorSocket', Linear Factor')
|
@ -0,0 +1,16 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetFirstContactNode(LnxLogicTreeNode):
|
||||
"""Returns the first object that is colliding with the given object.
|
||||
|
||||
@seeNode Get Contacts
|
||||
"""
|
||||
bl_idname = 'LNGetFirstContactNode'
|
||||
bl_label = 'Get RB First Contact'
|
||||
lnx_section = 'contact'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
|
||||
self.add_output('LnxNodeSocketObject', 'First Contact')
|
@ -0,0 +1,13 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetPointVelocityNode(LnxLogicTreeNode):
|
||||
"""Returns the world velocity of the given point along the rigid body."""
|
||||
bl_idname = 'LNGetPointVelocityNode'
|
||||
bl_label = 'Get RB Point Velocity'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Point')
|
||||
|
||||
self.add_output('LnxVectorSocket', 'Velocity')
|
15
leenkx/blender/lnx/logicnode/physics/LN_get_rb_velocity.py
Normal file
15
leenkx/blender/lnx/logicnode/physics/LN_get_rb_velocity.py
Normal file
@ -0,0 +1,15 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetVelocityNode(LnxLogicTreeNode):
|
||||
"""Returns the world velocity of the given rigid body."""
|
||||
bl_idname = 'LNGetVelocityNode'
|
||||
bl_label = 'Get RB Velocity'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxBoolSocket', 'Linear On Local Axis')
|
||||
self.add_input('LnxBoolSocket', 'Angular On Local Axis')
|
||||
|
||||
self.add_output('LnxVectorSocket', 'Linear')
|
||||
self.add_output('LnxVectorSocket', 'Angular')
|
13
leenkx/blender/lnx/logicnode/physics/LN_get_world_gravity.py
Normal file
13
leenkx/blender/lnx/logicnode/physics/LN_get_world_gravity.py
Normal file
@ -0,0 +1,13 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetGravityNode(LnxLogicTreeNode):
|
||||
"""Returns the world gravity.
|
||||
|
||||
@seeNode Set Gravity
|
||||
"""
|
||||
bl_idname = 'LNGetGravityNode'
|
||||
bl_label = 'Get World Gravity'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_output('LnxVectorSocket', 'World Gravity')
|
14
leenkx/blender/lnx/logicnode/physics/LN_has_contact.py
Normal file
14
leenkx/blender/lnx/logicnode/physics/LN_has_contact.py
Normal file
@ -0,0 +1,14 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class HasContactNode(LnxLogicTreeNode):
|
||||
"""Returns whether the given rigid body has contact with another given rigid body."""
|
||||
bl_idname = 'LNHasContactNode'
|
||||
bl_label = 'Has Contact'
|
||||
lnx_section = 'contact'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB 1')
|
||||
self.add_input('LnxNodeSocketObject', 'RB 2')
|
||||
|
||||
self.add_output('LnxBoolSocket', 'Has Contact')
|
14
leenkx/blender/lnx/logicnode/physics/LN_has_contact_array.py
Normal file
14
leenkx/blender/lnx/logicnode/physics/LN_has_contact_array.py
Normal file
@ -0,0 +1,14 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class HasContactArrayNode(LnxLogicTreeNode):
|
||||
"""Returns whether the given rigid body has contact with other given rigid bodies."""
|
||||
bl_idname = 'LNHasContactArrayNode'
|
||||
bl_label = 'Has Contact Array'
|
||||
lnx_section = 'contact'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxNodeSocketArray', 'RBs')
|
||||
|
||||
self.add_output('LnxBoolSocket', 'Has Contact')
|
11
leenkx/blender/lnx/logicnode/physics/LN_is_rb_active.py
Normal file
11
leenkx/blender/lnx/logicnode/physics/LN_is_rb_active.py
Normal file
@ -0,0 +1,11 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class IsRigidBodyActiveNode(LnxLogicTreeNode):
|
||||
"""Returns whether the given rigid body is active or sleeping."""
|
||||
bl_idname = 'LNIsRigidBodyActiveNode'
|
||||
bl_label = 'RB Is Active'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_output('LnxBoolSocket', 'Is Active')
|
33
leenkx/blender/lnx/logicnode/physics/LN_on_contact.py
Normal file
33
leenkx/blender/lnx/logicnode/physics/LN_on_contact.py
Normal file
@ -0,0 +1,33 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class OnContactNode(LnxLogicTreeNode):
|
||||
"""Activates the output when the rigid body make contact with
|
||||
another rigid body.
|
||||
|
||||
@option Begin: the output is activated on the first frame when the
|
||||
two objects have contact
|
||||
@option End: the output is activated on the frame after the last
|
||||
frame when the two objects had contact
|
||||
@option Overlap: the output is activated on each frame the object
|
||||
have contact
|
||||
"""
|
||||
bl_idname = 'LNOnContactNode'
|
||||
bl_label = 'On Contact'
|
||||
lnx_section = 'contact'
|
||||
lnx_version = 1
|
||||
|
||||
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')],
|
||||
name='', default='begin')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB 1')
|
||||
self.add_input('LnxNodeSocketObject', 'RB 2')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
24
leenkx/blender/lnx/logicnode/physics/LN_on_contact_array.py
Normal file
24
leenkx/blender/lnx/logicnode/physics/LN_on_contact_array.py
Normal file
@ -0,0 +1,24 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class OnContactArrayNode(LnxLogicTreeNode):
|
||||
"""Activates the output when the given rigid body make contact with other given rigid bodies."""
|
||||
bl_idname = 'LNOnContactArrayNode'
|
||||
bl_label = 'On Contact Array'
|
||||
lnx_section = 'contact'
|
||||
lnx_version = 1
|
||||
|
||||
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')],
|
||||
name='', default='begin')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxNodeSocketArray', 'RBs')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
27
leenkx/blender/lnx/logicnode/physics/LN_on_volume_trigger.py
Normal file
27
leenkx/blender/lnx/logicnode/physics/LN_on_volume_trigger.py
Normal file
@ -0,0 +1,27 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class OnVolumeTriggerNode(LnxLogicTreeNode):
|
||||
"""Activates the output when the given object enters, overlaps or leaves the bounding box of the given trigger object. (Note: Works even if objects are not Rigid Bodies).
|
||||
|
||||
@input RB: this object is taken as the entering object
|
||||
@input Trigger: this object is used as the volume trigger
|
||||
"""
|
||||
bl_idname = 'LNOnVolumeTriggerNode'
|
||||
bl_label = 'On Volume Trigger'
|
||||
lnx_version = 1
|
||||
|
||||
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')],
|
||||
name='', default='begin')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'Object 1')
|
||||
self.add_input('LnxNodeSocketObject', 'Object 2')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
@ -0,0 +1,74 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class PhysicsConstraintNode(LnxLogicTreeNode):
|
||||
"""
|
||||
Custom physics constraint to add to `Add Physics Constarint` node.
|
||||
|
||||
@option Linear/Angualr: Select if constrint is applied along linear or angular axis.
|
||||
|
||||
@option Axis: Local axis of the pivot object along which the constraint is applied.
|
||||
|
||||
@option Spring: Constraint is a Spring along the selected axis.
|
||||
|
||||
@input Limit Lower: Lower limit of the consraint in that particular axis
|
||||
|
||||
@input Limit Upper: Upper limit of the constraint in that particular axis. (`lower limit` = `upper limit`) --> Fully constrained. (`lower limit` < `upper limit`) --> Partially constrained
|
||||
(`lower limit` > `upper limit`) --> Full freedom.
|
||||
|
||||
@seeNode Add Physics Constraint
|
||||
"""
|
||||
|
||||
bl_idname = 'LNPhysicsConstraintNode'
|
||||
bl_label = 'Physics Constraint'
|
||||
lnx_section = 'add'
|
||||
lnx_version = 1
|
||||
|
||||
def update_spring(self, context):
|
||||
self.update_sockets(context)
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items=[('Linear', 'Linear', 'Linear'),
|
||||
('Angular', 'Angular', 'Angular')],
|
||||
name='Type', default='Linear')
|
||||
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items=[('X', 'X', 'X'),
|
||||
('Y', 'Y', 'Y'),
|
||||
('Z', 'Z', 'Z')],
|
||||
name='Axis', default='X')
|
||||
|
||||
property2: HaxeBoolProperty(
|
||||
'property2',
|
||||
name="Spring",
|
||||
description="Is a spring constraint",
|
||||
default=False,
|
||||
update=update_spring
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxFloatSocket', 'Lower limit')
|
||||
self.add_input('LnxFloatSocket', 'Upper limit')
|
||||
self.add_output('LnxDynamicSocket', 'Constraint')
|
||||
|
||||
def update_sockets(self, context):
|
||||
while len(self.inputs) > 0:
|
||||
self.inputs.remove(self.inputs.values()[-1])
|
||||
|
||||
# Add dynamic input sockets
|
||||
if self.property2:
|
||||
self.add_input('LnxFloatSocket', 'Stiffness', 10.0)
|
||||
self.add_input('LnxFloatSocket', 'Damping', 0.5)
|
||||
else:
|
||||
self.add_input('LnxFloatSocket', 'Lower limit')
|
||||
self.add_input('LnxFloatSocket', 'Upper limit')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
layout.prop(self, 'property2')
|
33
leenkx/blender/lnx/logicnode/physics/LN_pick_rb.py
Normal file
33
leenkx/blender/lnx/logicnode/physics/LN_pick_rb.py
Normal file
@ -0,0 +1,33 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class PickObjectNode(LnxLogicTreeNode):
|
||||
"""Picks the rigid body in the given location using the screen
|
||||
coordinates (2D).
|
||||
|
||||
@seeNode Mask
|
||||
|
||||
@input Screen Coords: the location at which to pick, in screen
|
||||
coordinates
|
||||
@input Mask: a bit mask value to specify which
|
||||
objects are considered
|
||||
|
||||
@output RB: the object that was hit
|
||||
@output Hit: the hit position in world coordinates
|
||||
@output Normal: the hit normal in world coordinates
|
||||
"""
|
||||
bl_idname = 'LNPickObjectNode'
|
||||
bl_label = 'Pick RB'
|
||||
lnx_section = 'ray'
|
||||
lnx_version = 2
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxVectorSocket', 'Screen Coords')
|
||||
self.add_input('LnxIntSocket', 'Mask', default_value=1)
|
||||
|
||||
self.add_output('LnxNodeSocketObject', 'RB')
|
||||
self.add_output('LnxVectorSocket', 'Hit')
|
||||
self.add_output('LnxVectorSocket', 'Normal')
|
||||
|
||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||
return NodeReplacement.Identity(self)
|
32
leenkx/blender/lnx/logicnode/physics/LN_ray_cast.py
Normal file
32
leenkx/blender/lnx/logicnode/physics/LN_ray_cast.py
Normal file
@ -0,0 +1,32 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class RayCastNode(LnxLogicTreeNode):
|
||||
"""Casts a physics ray and returns the first object that is hit by
|
||||
this ray.
|
||||
|
||||
@seeNode Mask
|
||||
|
||||
@input From: the location from where to start the ray, in world
|
||||
coordinates
|
||||
@input To: the target location of the ray, in world coordinates
|
||||
@input Mask: a bit mask value to specify which
|
||||
objects are considered
|
||||
|
||||
@output RB: the object that was hit
|
||||
@output Hit: the hit position in world coordinates
|
||||
@output Normal: the surface normal of the hit position relative to
|
||||
the world
|
||||
"""
|
||||
bl_idname = 'LNCastPhysicsRayNode'
|
||||
bl_label = 'Ray Cast'
|
||||
lnx_section = 'ray'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxVectorSocket', 'From')
|
||||
self.add_input('LnxVectorSocket', 'To')
|
||||
self.add_input('LnxIntSocket', 'Mask', default_value=1)
|
||||
|
||||
self.add_output('LnxNodeSocketObject', 'RB')
|
||||
self.add_output('LnxVectorSocket', 'Hit')
|
||||
self.add_output('LnxVectorSocket', 'Normal')
|
36
leenkx/blender/lnx/logicnode/physics/LN_ray_cast_on.py
Normal file
36
leenkx/blender/lnx/logicnode/physics/LN_ray_cast_on.py
Normal file
@ -0,0 +1,36 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class RayCastOnNode(LnxLogicTreeNode):
|
||||
"""Casts a physics ray and returns the first object that is hit by
|
||||
this ray.
|
||||
|
||||
@seeNode Mask
|
||||
|
||||
@input In: Input trigger
|
||||
@input From: the location from where to start the ray, in world
|
||||
coordinates
|
||||
@input To: the target location of the ray, in world coordinates
|
||||
@input Mask: a bit mask value to specify which
|
||||
objects are considered
|
||||
|
||||
@output Out: Output after hit
|
||||
@output RB: the object that was hit
|
||||
@output Hit: the hit position in world coordinates
|
||||
@output Normal: the surface normal of the hit position relative to
|
||||
the world
|
||||
"""
|
||||
bl_idname = 'LNCastPhysicsRayOnNode'
|
||||
bl_label = 'Ray Cast On'
|
||||
lnx_section = 'ray'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxVectorSocket', 'From')
|
||||
self.add_input('LnxVectorSocket', 'To')
|
||||
self.add_input('LnxIntSocket', 'Mask', default_value=1)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxNodeSocketObject', 'RB')
|
||||
self.add_output('LnxVectorSocket', 'Hit')
|
||||
self.add_output('LnxVectorSocket', 'Normal')
|
13
leenkx/blender/lnx/logicnode/physics/LN_remove_rb.py
Normal file
13
leenkx/blender/lnx/logicnode/physics/LN_remove_rb.py
Normal file
@ -0,0 +1,13 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class RemovePhysicsNode (LnxLogicTreeNode):
|
||||
"""Removes the rigid body from the given object."""
|
||||
bl_idname = 'LNRemovePhysicsNode'
|
||||
bl_label = 'Remove RB'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketAction', 'In')
|
||||
self.inputs.new('LnxNodeSocketObject', 'RB')
|
||||
|
||||
self.outputs.new('LnxNodeSocketAction', 'Out')
|
@ -0,0 +1,26 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetActivationStateNode(LnxLogicTreeNode):
|
||||
"""Sets the rigid body simulation state of the given object."""
|
||||
bl_idname = 'LNSetActivationStateNode'
|
||||
bl_label = 'Set RB Activation State'
|
||||
bl_icon = 'NONE'
|
||||
lnx_version = 1
|
||||
|
||||
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'),
|
||||
('always inactive', 'Always Inactive', 'The rigid body simulation is never activated'),
|
||||
],
|
||||
name='', default='inactive')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketAction', 'In')
|
||||
self.inputs.new('LnxNodeSocketObject', 'RB')
|
||||
|
||||
self.outputs.new('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
15
leenkx/blender/lnx/logicnode/physics/LN_set_rb_friction.py
Normal file
15
leenkx/blender/lnx/logicnode/physics/LN_set_rb_friction.py
Normal file
@ -0,0 +1,15 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetFrictionNode (LnxLogicTreeNode):
|
||||
"""Sets the friction of the given rigid body."""
|
||||
bl_idname = 'LNSetFrictionNode'
|
||||
bl_label = 'Set RB Friction'
|
||||
bl_icon = 'NONE'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketAction', 'In')
|
||||
self.inputs.new('LnxNodeSocketObject', 'RB')
|
||||
self.inputs.new('LnxFloatSocket', 'Friction')
|
||||
|
||||
self.outputs.new('LnxNodeSocketAction', 'Out')
|
@ -0,0 +1,14 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetGravityEnabledNode(LnxLogicTreeNode):
|
||||
"""Sets whether the gravity is enabled for the given rigid body."""
|
||||
bl_idname = 'LNSetGravityEnabledNode'
|
||||
bl_label = 'Set RB Gravity Enabled'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxBoolSocket', 'Enabled')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
17
leenkx/blender/lnx/logicnode/physics/LN_set_rb_velocity.py
Normal file
17
leenkx/blender/lnx/logicnode/physics/LN_set_rb_velocity.py
Normal file
@ -0,0 +1,17 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetVelocityNode(LnxLogicTreeNode):
|
||||
"""Sets the velocity of the given rigid body."""
|
||||
bl_idname = 'LNSetVelocityNode'
|
||||
bl_label = 'Set RB Velocity'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'RB')
|
||||
self.add_input('LnxVectorSocket', 'Linear')
|
||||
self.add_input('LnxVectorSocket', 'Linear Factor', default_value=[1.0, 1.0, 1.0])
|
||||
self.add_input('LnxVectorSocket', 'Angular')
|
||||
self.add_input('LnxVectorSocket', 'Angular Factor', default_value=[1.0, 1.0, 1.0])
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
16
leenkx/blender/lnx/logicnode/physics/LN_set_world_gravity.py
Normal file
16
leenkx/blender/lnx/logicnode/physics/LN_set_world_gravity.py
Normal file
@ -0,0 +1,16 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetGravityNode(LnxLogicTreeNode):
|
||||
"""Sets the world gravity.
|
||||
|
||||
@seeNode Get World Gravity
|
||||
"""
|
||||
bl_idname = 'LNSetGravityNode'
|
||||
bl_label = 'Set World Gravity'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxVectorSocket', 'Gravity')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
29
leenkx/blender/lnx/logicnode/physics/LN_volume_trigger.py
Normal file
29
leenkx/blender/lnx/logicnode/physics/LN_volume_trigger.py
Normal file
@ -0,0 +1,29 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class VolumeTriggerNode(LnxLogicTreeNode):
|
||||
"""Returns `true` if the given rigid body enters, overlaps or leaves the
|
||||
given volume trigger.
|
||||
|
||||
@input RB: this object is taken as the entering object
|
||||
@input Trigger: this object is used as the volume trigger
|
||||
"""
|
||||
bl_idname = 'LNVolumeTriggerNode'
|
||||
bl_label = 'Volume Trigger'
|
||||
lnx_section = 'misc'
|
||||
lnx_version = 1
|
||||
|
||||
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')],
|
||||
name='', default='begin')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketObject', 'Object 1')
|
||||
self.add_input('LnxNodeSocketObject', 'Object 2')
|
||||
|
||||
self.add_output('LnxBoolSocket', 'Bool')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
6
leenkx/blender/lnx/logicnode/physics/__init__.py
Normal file
6
leenkx/blender/lnx/logicnode/physics/__init__.py
Normal file
@ -0,0 +1,6 @@
|
||||
from lnx.logicnode.lnx_nodes import add_node_section
|
||||
|
||||
add_node_section(name='default', category='Physics')
|
||||
add_node_section(name='force', category='Physics')
|
||||
add_node_section(name='contact', category='Physics')
|
||||
add_node_section(name='ray', category='Physics')
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user