forked from LeenkxTeam/LNXSDK
merge upstream
This commit is contained in:
@ -191,7 +191,7 @@ def apply_materials(load_atlas=0):
|
||||
|
||||
mainNode = outputNode.inputs[0].links[0].from_node.inputs[0].links[0].from_node
|
||||
|
||||
if (mainNode.type == "ShaderNodeMixRGB"):
|
||||
if (mainNode.type == "ShaderNodeMix"):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Mix RGB shader found")
|
||||
|
||||
@ -199,9 +199,11 @@ def apply_materials(load_atlas=0):
|
||||
|
||||
#Add all nodes first
|
||||
#Add lightmap multipliction texture
|
||||
mixNode = node_tree.nodes.new(type="ShaderNodeMixRGB")
|
||||
mixNode = node_tree.nodes.new(type="ShaderNodeMix")
|
||||
mixNode.name = "Lightmap_Multiplication"
|
||||
mixNode.location = -800, 300
|
||||
mixNode.data_type = 'RGBA'
|
||||
mixNode.inputs[0].default_value = 1
|
||||
if scene.TLM_EngineProperties.tlm_lighting_mode == "indirect" or scene.TLM_EngineProperties.tlm_lighting_mode == "indirectAO":
|
||||
mixNode.blend_type = 'MULTIPLY'
|
||||
else:
|
||||
@ -312,8 +314,8 @@ def apply_materials(load_atlas=0):
|
||||
else:
|
||||
mat.node_tree.links.new(lightmapNode.outputs[1], DecodeNode.inputs[1]) #Connect lightmap node to decodenode
|
||||
|
||||
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[1]) #Connect decode node to mixnode
|
||||
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[1]) #Connect exposure node to mixnode
|
||||
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[6]) #Connect decode node to mixnode
|
||||
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[6]) #Connect exposure node to mixnode
|
||||
|
||||
else:
|
||||
|
||||
@ -323,10 +325,10 @@ def apply_materials(load_atlas=0):
|
||||
else:
|
||||
mat.node_tree.links.new(lightmapNode.outputs[1], DecodeNode.inputs[1]) #Connect lightmap node to decodenode
|
||||
|
||||
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[1]) #Connect lightmap node to mixnode
|
||||
mat.node_tree.links.new(DecodeNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
|
||||
|
||||
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[2]) #Connect basecolor to pbr node
|
||||
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[0]) #Connect mixnode to pbr node
|
||||
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[7]) #Connect basecolor to pbr node
|
||||
mat.node_tree.links.new(mixNode.outputs[2], mainNode.inputs[0]) #Connect mixnode to pbr node
|
||||
|
||||
if not scene.TLM_EngineProperties.tlm_target == "vertex":
|
||||
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
|
||||
@ -338,11 +340,11 @@ def apply_materials(load_atlas=0):
|
||||
|
||||
if(scene.TLM_EngineProperties.tlm_exposure_multiplier > 0):
|
||||
mat.node_tree.links.new(lightmapNode.outputs[0], ExposureNode.inputs[0]) #Connect lightmap node to mixnode
|
||||
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[1]) #Connect lightmap node to mixnode
|
||||
mat.node_tree.links.new(ExposureNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
|
||||
else:
|
||||
mat.node_tree.links.new(lightmapNode.outputs[0], mixNode.inputs[1]) #Connect lightmap node to mixnode
|
||||
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[2]) #Connect basecolor to pbr node
|
||||
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[0]) #Connect mixnode to pbr node
|
||||
mat.node_tree.links.new(lightmapNode.outputs[0], mixNode.inputs[6]) #Connect lightmap node to mixnode
|
||||
mat.node_tree.links.new(baseColorNode.outputs[0], mixNode.inputs[7]) #Connect basecolor to pbr node
|
||||
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[2]) #Connect mixnode to pbr node
|
||||
if not scene.TLM_EngineProperties.tlm_target == "vertex":
|
||||
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
|
||||
|
||||
@ -491,8 +493,9 @@ def applyAOPass():
|
||||
AOMap.image = AOImage
|
||||
AOMap.location = -800, 0
|
||||
|
||||
AOMult = nodes.new(type="ShaderNodeMixRGB")
|
||||
AOMult = nodes.new(type="ShaderNodeMix")
|
||||
AOMult.name = "TLM_AOMult"
|
||||
AOMult.data_type = 'RGBA'
|
||||
AOMult.blend_type = 'MULTIPLY'
|
||||
AOMult.inputs[0].default_value = 1.0
|
||||
AOMult.location = -300, 300
|
||||
|
@ -518,7 +518,7 @@ def configure_meshes(self):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("The material group is not supported!")
|
||||
|
||||
if (mainNode.type == "ShaderNodeMixRGB"):
|
||||
if (mainNode.type == "ShaderNodeMix"):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Mix shader found")
|
||||
|
||||
@ -811,7 +811,7 @@ def set_settings():
|
||||
|
||||
print(bpy.app.version)
|
||||
|
||||
if bpy.app.version[0] == 3:
|
||||
if bpy.app.version[0] == 3 or byp.app.version[0] == 4:
|
||||
if cycles.device == "GPU":
|
||||
scene.cycles.tile_size = 256
|
||||
else:
|
||||
|
@ -28,7 +28,11 @@ class ViewportDraw:
|
||||
w = 400
|
||||
h = 200
|
||||
|
||||
self.shader = gpu.shader.from_builtin('2D_IMAGE')
|
||||
if bpy.app.version[0] == 3:
|
||||
self.shader = gpu.shader.from_builtin('2D_IMAGE')
|
||||
else:
|
||||
self.shader = gpu.shader.from_builtin('IMAGE')
|
||||
|
||||
self.batch = batch_for_shader(
|
||||
self.shader, 'TRI_FAN',
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ class Shader_Node_Types:
|
||||
normal = "ShaderNodeNormalMap"
|
||||
ao = "ShaderNodeAmbientOcclusion"
|
||||
uv = "ShaderNodeUVMap"
|
||||
mix = "ShaderNodeMixRGB"
|
||||
mix = "ShaderNodeMix"
|
||||
|
||||
def select_object(self,obj):
|
||||
C = bpy.context
|
||||
|
@ -47,7 +47,8 @@ def init_categories():
|
||||
lnx_nodes.add_category('Navmesh', icon='UV_VERTEXSEL', section="motion")
|
||||
lnx_nodes.add_category('Transform', icon='TRANSFORM_ORIGINS', section="motion")
|
||||
lnx_nodes.add_category('Physics', icon='PHYSICS', section="motion")
|
||||
|
||||
lnx_nodes.add_category('Particle', icon='PARTICLE_DATA', section="motion")
|
||||
|
||||
lnx_nodes.add_category('Array', icon='MOD_ARRAY', section="values")
|
||||
lnx_nodes.add_category('Map', icon='SHORTDISPLAY', section="values")
|
||||
lnx_nodes.add_category('Database', icon='MESH_CYLINDER', section="values")
|
||||
|
@ -11,14 +11,15 @@ class DrawCameraTextureNode(LnxLogicTreeNode):
|
||||
@input Object: Object of which to choose the material in the `Material Slot` input.
|
||||
@input Material Slot: Index of the material slot of which the diffuse
|
||||
texture is replaced with the camera's render target.
|
||||
|
||||
@input Node: Node name of the Image Texture Node.
|
||||
|
||||
@output On Start: Activated after the `Start` input has been activated.
|
||||
@output On Stop: Activated after the `Stop` input has been activated.
|
||||
"""
|
||||
bl_idname = 'LNDrawCameraTextureNode'
|
||||
bl_label = 'Draw Camera to Texture'
|
||||
lnx_section = 'draw'
|
||||
lnx_version = 1
|
||||
lnx_version = 2
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'Start')
|
||||
@ -26,6 +27,13 @@ class DrawCameraTextureNode(LnxLogicTreeNode):
|
||||
self.add_input('LnxNodeSocketObject', 'Camera')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Material Slot')
|
||||
|
||||
self.add_input('LnxStringSocket', 'Node')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'On Start')
|
||||
self.add_output('LnxNodeSocketAction', 'On Stop')
|
||||
|
||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||
if self.lnx_version not in (0, 1):
|
||||
raise LookupError()
|
||||
|
||||
return NodeReplacement.Identity(self)
|
44
leenkx/blender/lnx/logicnode/draw/LN_draw_sub_image.py
Normal file
44
leenkx/blender/lnx/logicnode/draw/LN_draw_sub_image.py
Normal file
@ -0,0 +1,44 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class DrawSubImageNode(LnxLogicTreeNode):
|
||||
"""Draws an image.
|
||||
@input Draw: Activate to draw the image on this frame. The input must
|
||||
be (indirectly) called from an `On Render2D` node.
|
||||
@input Image: The filename of the image.
|
||||
@input Color: The color that the image's pixels are multiplied with.
|
||||
@input Left/Center/Right: Horizontal anchor point of the image.
|
||||
0 = Left, 1 = Center, 2 = Right
|
||||
@input Top/Middle/Bottom: Vertical anchor point of the image.
|
||||
0 = Top, 1 = Middle, 2 = Bottom
|
||||
@input X/Y: Position of the anchor point in pixels.
|
||||
@input Width/Height: Size of the sub image in pixels.
|
||||
@input sX/Y: Position of the sub anchor point in pixels.
|
||||
@input sWidth/Height: Size of the image in pixels.
|
||||
@input Angle: Rotation angle in radians. Image will be rotated cloclwiswe
|
||||
at the anchor point.
|
||||
@output Out: Activated after the image has been drawn.
|
||||
@see [`kha.graphics2.Graphics.drawImage()`](http://kha.tech/api/kha/graphics2/Graphics.html#drawImage).
|
||||
"""
|
||||
bl_idname = 'LNDrawSubImageNode'
|
||||
bl_label = 'Draw Sub Image'
|
||||
lnx_section = 'draw'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'Draw')
|
||||
self.add_input('LnxStringSocket', 'Image File')
|
||||
self.add_input('LnxColorSocket', 'Color', default_value=[1.0, 1.0, 1.0, 1.0])
|
||||
self.add_input('LnxIntSocket', '0/1/2 = Left/Center/Right', default_value=0)
|
||||
self.add_input('LnxIntSocket', '0/1/2 = Top/Middle/Bottom', default_value=0)
|
||||
self.add_input('LnxFloatSocket', 'X')
|
||||
self.add_input('LnxFloatSocket', 'Y')
|
||||
self.add_input('LnxFloatSocket', 'Width')
|
||||
self.add_input('LnxFloatSocket', 'Height')
|
||||
self.add_input('LnxFloatSocket', 'sX')
|
||||
self.add_input('LnxFloatSocket', 'sY')
|
||||
self.add_input('LnxFloatSocket', 'sWidth')
|
||||
self.add_input('LnxFloatSocket', 'sHeight')
|
||||
self.add_input('LnxFloatSocket', 'Angle')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
@ -5,8 +5,6 @@ class WriteFileNode(LnxLogicTreeNode):
|
||||
"""Writes the given string content to the given file. If the file
|
||||
already exists, the existing content of the file is overwritten.
|
||||
|
||||
> **This node is currently only implemented on Krom**
|
||||
|
||||
@input File: the name of the file, relative to `Krom.getFilesLocation()`
|
||||
@input Content: the content to write to the file.
|
||||
|
||||
|
34
leenkx/blender/lnx/logicnode/native/LN_write_image.py
Normal file
34
leenkx/blender/lnx/logicnode/native/LN_write_image.py
Normal file
@ -0,0 +1,34 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class WriteImageNode(LnxLogicTreeNode):
|
||||
"""Writes the given image to the given file. If the image
|
||||
already exists, the existing content of the image is overwritten.
|
||||
Aspect ratio must match display resolution ratio.
|
||||
@input Image File: the name of the image, relative to `Krom.getFilesLocation()`
|
||||
@input Camera: the render target image of the camera to write to the image file.
|
||||
@input Width: width of the image file.
|
||||
@input Height: heigth of the image file.
|
||||
@input sX: sub position of first x pixel of the sub image (0 for start).
|
||||
@input sY: sub position of first y pixel of the sub image (0 for start).
|
||||
@input sWidth: width of the sub image.
|
||||
@input sHeight: height of the sub image.
|
||||
@seeNode Read File
|
||||
"""
|
||||
bl_idname = 'LNWriteImageNode'
|
||||
bl_label = 'Write Image'
|
||||
lnx_section = 'file'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxStringSocket', 'Image File')
|
||||
self.add_input('LnxNodeSocketObject', 'Camera')
|
||||
self.add_input('LnxIntSocket', 'Width')
|
||||
self.add_input('LnxIntSocket', 'Height')
|
||||
self.add_input('LnxIntSocket', 'sX')
|
||||
self.add_input('LnxIntSocket', 'sY')
|
||||
self.add_input('LnxIntSocket', 'sWidth')
|
||||
self.add_input('LnxIntSocket', 'sHeight')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
@ -5,8 +5,6 @@ class WriteJsonNode(LnxLogicTreeNode):
|
||||
"""Writes the given content to the given JSON file. If the file
|
||||
already exists, the existing content of the file is overwritten.
|
||||
|
||||
> **This node is currently only implemented on Krom**
|
||||
|
||||
@input File: the name of the file, relative to `Krom.getFilesLocation()`,
|
||||
including the file extension.
|
||||
@input Dynamic: the content to write to the file. Can be any type that can
|
||||
|
@ -0,0 +1,41 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class AddParticleToObjectNode(LnxLogicTreeNode):
|
||||
"""Sets the speed of the given particle source."""
|
||||
bl_idname = 'LNAddParticleToObjectNode'
|
||||
bl_label = 'Add Particle To Object'
|
||||
lnx_version = 1
|
||||
|
||||
def remove_extra_inputs(self, context):
|
||||
while len(self.inputs) > 1:
|
||||
self.inputs.remove(self.inputs[-1])
|
||||
if self.property0 == 'Scene':
|
||||
self.add_input('LnxStringSocket', 'Scene From Name')
|
||||
self.add_input('LnxStringSocket', 'Object From Name')
|
||||
else:
|
||||
self.add_input('LnxNodeSocketObject', 'Object From')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxNodeSocketObject', 'Object To')
|
||||
self.add_input('LnxBoolSocket', 'Render Emitter', default_value = True)
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Scene Active', 'Scene Active', 'Scene Active'),
|
||||
('Scene', 'Scene', 'Scene')],
|
||||
name='', default='Scene Active', update=remove_extra_inputs)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object From')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxNodeSocketObject', 'Object To')
|
||||
self.add_input('LnxBoolSocket', 'Render Emitter', default_value = True)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
14
leenkx/blender/lnx/logicnode/particle/LN_get_particle.py
Normal file
14
leenkx/blender/lnx/logicnode/particle/LN_get_particle.py
Normal file
@ -0,0 +1,14 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetParticleNode(LnxLogicTreeNode):
|
||||
"""Returns the Particle Systems of an object."""
|
||||
bl_idname = 'LNGetParticleNode'
|
||||
bl_label = 'Get Particle'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketObject', 'Object')
|
||||
|
||||
self.outputs.new('LnxNodeSocketArray', 'Names')
|
||||
self.outputs.new('LnxIntSocket', 'Length')
|
||||
self.outputs.new('LnxBoolSocket', 'Render Emitter')
|
@ -0,0 +1,31 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class GetParticleDataNode(LnxLogicTreeNode):
|
||||
"""Returns the data of the given Particle System."""
|
||||
bl_idname = 'LNGetParticleDataNode'
|
||||
bl_label = 'Get Particle Data'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.inputs.new('LnxNodeSocketObject', 'Object')
|
||||
self.inputs.new('LnxIntSocket', 'Slot')
|
||||
|
||||
self.outputs.new('LnxStringSocket', 'Name')
|
||||
self.outputs.new('LnxFloatSocket', 'Particle Size')
|
||||
self.outputs.new('LnxIntSocket', 'Frame Start')
|
||||
self.outputs.new('LnxIntSocket', 'Frame End')
|
||||
self.outputs.new('LnxIntSocket', 'Lifetime')
|
||||
self.outputs.new('LnxFloatSocket', 'Lifetime Random')
|
||||
self.outputs.new('LnxIntSocket', 'Emit From')
|
||||
|
||||
self.outputs.new('LnxVectorSocket', 'Velocity')
|
||||
self.outputs.new('LnxFloatSocket', 'Velocity Random')
|
||||
self.outputs.new('LnxVectorSocket', 'Gravity')
|
||||
self.outputs.new('LnxFloatSocket', 'Weight Gravity')
|
||||
|
||||
self.outputs.new('LnxFloatSocket', 'Speed')
|
||||
|
||||
self.outputs.new('LnxFloatSocket', 'Time')
|
||||
self.outputs.new('LnxFloatSocket', 'Lap')
|
||||
self.outputs.new('LnxFloatSocket', 'Lap Time')
|
||||
self.outputs.new('LnxIntSocket', 'Count')
|
@ -0,0 +1,33 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class RemoveParticleFromObjectNode(LnxLogicTreeNode):
|
||||
"""Remove Particle From Object."""
|
||||
bl_idname = 'LNRemoveParticleFromObjectNode'
|
||||
bl_label = 'Remove Particle From Object'
|
||||
lnx_version = 1
|
||||
|
||||
def remove_extra_inputs(self, context):
|
||||
while len(self.inputs) > 2:
|
||||
self.inputs.remove(self.inputs[-1])
|
||||
if self.property0 == 'Slot':
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
if self.property0 == 'Name':
|
||||
self.add_input('LnxStringSocket', 'Name')
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Slot', 'Slot', 'Slot'),
|
||||
('Name', 'Name', 'Name'),
|
||||
('All', 'All', 'All')],
|
||||
name='', default='Slot', update=remove_extra_inputs)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
@ -0,0 +1,58 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetParticleDataNode(LnxLogicTreeNode):
|
||||
"""Sets the parameters of the given particle system."""
|
||||
bl_idname = 'LNSetParticleDataNode'
|
||||
bl_label = 'Set Particle Data'
|
||||
lnx_version = 1
|
||||
|
||||
def remove_extra_inputs(self, context):
|
||||
while len(self.inputs) > 3:
|
||||
self.inputs.remove(self.inputs[-1])
|
||||
if self.property0 == 'Particle Size':
|
||||
self.add_input('LnxFloatSocket', 'Particle Size')
|
||||
if self.property0 == 'Frame End':
|
||||
self.add_input('LnxIntSocket', 'Frame End')
|
||||
if self.property0 == 'Frame Start':
|
||||
self.add_input('LnxIntSocket', 'Frame Start')
|
||||
if self.property0 == 'Lifetime':
|
||||
self.add_input('LnxIntSocket', 'Lifetime')
|
||||
if self.property0 == 'Lifetime Random':
|
||||
self.add_input('LnxFloatSocket', 'Lifetime Random')
|
||||
if self.property0 == 'Emit From':
|
||||
self.add_input('LnxIntSocket', 'Emit From')
|
||||
if self.property0 == 'Velocity':
|
||||
self.add_input('LnxVectorSocket', 'Velocity')
|
||||
if self.property0 == 'Velocity Random':
|
||||
self.add_input('LnxFloatSocket', 'Velocity Random')
|
||||
if self.property0 == 'Weight Gravity':
|
||||
self.add_input('LnxFloatSocket', 'Weight Gravity')
|
||||
if self.property0 == 'Speed':
|
||||
self.add_input('LnxFloatSocket', 'Speed')
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('Particle Size', 'Particle Size', 'for the system'),
|
||||
('Frame Start', 'Frame Start', 'for the system'),
|
||||
('Frame End', 'Frame End', 'for the system'),
|
||||
('Lifetime', 'Lifetime', 'for the instance'),
|
||||
('Lifetime Random', 'Lifetime Random', 'for the system'),
|
||||
('Emit From', 'Emit From', 'for the system (Vertices:0 Faces:1 Volume: 2)'),
|
||||
('Velocity', 'Velocity', 'for the instance'),
|
||||
('Velocity Random', 'Velocity Random', 'for the system'),
|
||||
('Weight Gravity', 'Weight Gravity', 'for the instance'),
|
||||
('Speed', 'Speed', 'for the instance')],
|
||||
name='', default='Speed', update=remove_extra_inputs)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
@ -1,14 +1,22 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetParticleSpeedNode(LnxLogicTreeNode):
|
||||
"""Sets the speed of the given particle source."""
|
||||
bl_idname = 'LNSetParticleSpeedNode'
|
||||
bl_label = 'Set Particle Speed'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class SetParticleSpeedNode(LnxLogicTreeNode):
|
||||
"""Sets the speed of the given particle source."""
|
||||
bl_idname = 'LNSetParticleSpeedNode'
|
||||
bl_label = 'Set Particle Speed'
|
||||
lnx_version = 2
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxNodeSocketObject', 'Object')
|
||||
self.add_input('LnxIntSocket', 'Slot')
|
||||
self.add_input('LnxFloatSocket', 'Speed', default_value=1.0)
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
|
||||
def get_replacement_node(self, node_tree: bpy.types.NodeTree):
|
||||
if self.lnx_version not in (0, 1):
|
||||
raise LookupError()
|
||||
|
||||
return NodeReplacement.Identity(self)
|
3
leenkx/blender/lnx/logicnode/particle/__init__.py
Normal file
3
leenkx/blender/lnx/logicnode/particle/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from lnx.logicnode.lnx_nodes import add_node_section
|
||||
|
||||
add_node_section(name='default', category='Particle')
|
@ -234,7 +234,7 @@ def build():
|
||||
wrd.compo_defs += '_CGrain'
|
||||
if rpdat.lnx_sharpen:
|
||||
wrd.compo_defs += '_CSharpen'
|
||||
if bpy.data.scenes[0].view_settings.exposure != 0.0:
|
||||
if bpy.utils.get_active_scene().view_settings.exposure != 0.0:
|
||||
wrd.compo_defs += '_CExposure'
|
||||
if rpdat.lnx_fog:
|
||||
wrd.compo_defs += '_CFog'
|
||||
|
@ -298,6 +298,125 @@ float tex_brick_f(vec3 p) {
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
#https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_tex_brick.glsl
|
||||
str_tex_brick_blender = """
|
||||
float integer_noise(int n)
|
||||
{
|
||||
/* Integer bit-shifts for these calculations can cause precision problems on macOS.
|
||||
* Using uint resolves these issues. */
|
||||
uint nn;
|
||||
nn = (uint(n) + 1013u) & 0x7fffffffu;
|
||||
nn = (nn >> 13u) ^ nn;
|
||||
nn = (uint(nn * (nn * nn * 60493u + 19990303u)) + 1376312589u) & 0x7fffffffu;
|
||||
return 0.5f * (float(nn) / 1073741824.0f);
|
||||
}
|
||||
vec2 calc_brick_texture(vec3 p,
|
||||
float mortar_size,
|
||||
float mortar_smooth,
|
||||
float bias,
|
||||
float brick_width,
|
||||
float row_height,
|
||||
float offset_amount,
|
||||
int offset_frequency,
|
||||
float squash_amount,
|
||||
int squash_frequency)
|
||||
{
|
||||
int bricknum, rownum;
|
||||
float offset = 0.0f;
|
||||
float x, y;
|
||||
rownum = int(floor(p.y / row_height));
|
||||
if (offset_frequency != 0 && squash_frequency != 0) {
|
||||
brick_width *= (rownum % squash_frequency != 0) ? 1.0f : squash_amount; /* squash */
|
||||
offset = (rownum % offset_frequency != 0) ? 0.0f : (brick_width * offset_amount); /* offset */
|
||||
}
|
||||
bricknum = int(floor((p.x + offset) / brick_width));
|
||||
x = (p.x + offset) - brick_width * bricknum;
|
||||
y = p.y - row_height * rownum;
|
||||
float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f);
|
||||
float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
|
||||
if (min_dist >= mortar_size) {
|
||||
return vec2(tint, 0.0f);
|
||||
}
|
||||
else if (mortar_smooth == 0.0f) {
|
||||
return vec2(tint, 1.0f);
|
||||
}
|
||||
else {
|
||||
min_dist = 1.0f - min_dist / mortar_size;
|
||||
return vec2(tint, smoothstep(0.0f, mortar_smooth, min_dist));
|
||||
}
|
||||
}
|
||||
vec3 tex_brick_blender(vec3 co,
|
||||
vec3 color1,
|
||||
vec3 color2,
|
||||
vec3 mortar,
|
||||
float scale,
|
||||
float mortar_size,
|
||||
float mortar_smooth,
|
||||
float bias,
|
||||
float brick_width,
|
||||
float row_height,
|
||||
float offset_amount,
|
||||
float offset_frequency,
|
||||
float squash_amount,
|
||||
float squash_frequency)
|
||||
{
|
||||
vec2 f2 = calc_brick_texture(co * scale,
|
||||
mortar_size,
|
||||
mortar_smooth,
|
||||
bias,
|
||||
brick_width,
|
||||
row_height,
|
||||
offset_amount,
|
||||
int(offset_frequency),
|
||||
squash_amount,
|
||||
int(squash_frequency));
|
||||
float tint = f2.x;
|
||||
float f = f2.y;
|
||||
if (f != 1.0f) {
|
||||
float facm = 1.0f - tint;
|
||||
color1 = facm * color1 + tint * color2;
|
||||
}
|
||||
return mix(color1, mortar, f);
|
||||
}
|
||||
float tex_brick_blender_f(vec3 co,
|
||||
vec3 color1,
|
||||
vec3 color2,
|
||||
vec3 mortar,
|
||||
float scale,
|
||||
float mortar_size,
|
||||
float mortar_smooth,
|
||||
float bias,
|
||||
float brick_width,
|
||||
float row_height,
|
||||
float offset_amount,
|
||||
float offset_frequency,
|
||||
float squash_amount,
|
||||
float squash_frequency)
|
||||
{
|
||||
vec2 f2 = calc_brick_texture(co * scale,
|
||||
mortar_size,
|
||||
mortar_smooth,
|
||||
bias,
|
||||
brick_width,
|
||||
row_height,
|
||||
offset_amount,
|
||||
int(offset_frequency),
|
||||
squash_amount,
|
||||
int(squash_frequency));
|
||||
float tint = f2.x;
|
||||
float f = f2.y;
|
||||
if (f != 1.0f) {
|
||||
float facm = 1.0f - tint;
|
||||
color1 = facm * color1 + tint * color2;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
str_tex_wave = """
|
||||
float tex_wave_f(const vec3 p, const int type, const int profile, const float dist, const float detail, const float detail_scale) {
|
||||
float n;
|
||||
|
@ -29,24 +29,35 @@ else:
|
||||
|
||||
|
||||
def parse_tex_brick(node: bpy.types.ShaderNodeTexBrick, out_socket: bpy.types.NodeSocket, state: ParserState) -> Union[floatstr, vec3str]:
|
||||
state.curshader.add_function(c_functions.str_tex_brick)
|
||||
state.curshader.add_function(c_functions.str_tex_brick_blender)
|
||||
|
||||
if node.inputs[0].is_linked:
|
||||
co = c.parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
|
||||
offset_amount = node.offset
|
||||
offset_frequency = node.offset_frequency
|
||||
squash_amount = node.squash
|
||||
squash_frequency = node.squash_frequency
|
||||
|
||||
col1 = c.parse_vector_input(node.inputs[1])
|
||||
col2 = c.parse_vector_input(node.inputs[2])
|
||||
col3 = c.parse_vector_input(node.inputs[3])
|
||||
scale = c.parse_value_input(node.inputs[4])
|
||||
mortar_size = c.parse_value_input(node.inputs[5])
|
||||
mortar_smooth = c.parse_value_input(node.inputs[6])
|
||||
bias = c.parse_value_input(node.inputs[7])
|
||||
brick_width = c.parse_value_input(node.inputs[8])
|
||||
row_height = c.parse_value_input(node.inputs[9])
|
||||
#res = f'tex_brick({co} * {scale}, {col1}, {col2}, {col3})'
|
||||
|
||||
# Color
|
||||
if out_socket == node.outputs[0]:
|
||||
col1 = c.parse_vector_input(node.inputs[1])
|
||||
col2 = c.parse_vector_input(node.inputs[2])
|
||||
col3 = c.parse_vector_input(node.inputs[3])
|
||||
scale = c.parse_value_input(node.inputs[4])
|
||||
res = f'tex_brick({co} * {scale}, {col1}, {col2}, {col3})'
|
||||
res = f'tex_brick_blender({co}, {col1}, {col2}, {col3}, {scale}, {mortar_size}, {mortar_smooth}, {bias}, {brick_width}, {row_height}, {offset_amount}, {offset_frequency}, {squash_amount}, {squash_frequency})'
|
||||
# Fac
|
||||
else:
|
||||
scale = c.parse_value_input(node.inputs[4])
|
||||
res = 'tex_brick_f({0} * {1})'.format(co, scale)
|
||||
res = f'tex_brick_blender_f({co}, {col1}, {col2}, {col3}, {scale}, {mortar_size}, {mortar_smooth}, {bias}, {brick_width}, {row_height}, {offset_amount}, {offset_frequency}, {squash_amount}, {squash_frequency})'
|
||||
|
||||
return res
|
||||
|
||||
|
@ -77,7 +77,7 @@ class LNX_MT_NodeAddOverride(bpy.types.Menu):
|
||||
layout.separator()
|
||||
layout.menu(f'LNX_MT_{INTERNAL_GROUPS_MENU_ID}_menu', text=internal_groups_menu_class.bl_label, icon='OUTLINER_OB_GROUP_INSTANCE')
|
||||
|
||||
elif context.space_data.tree_type == 'ShaderNodeTree':
|
||||
elif context.space_data.tree_type == 'ShaderNodeTree' and bpy.app.version > (4, 0, 0):
|
||||
# TO DO - Recursively gather nodes and draw them to menu
|
||||
|
||||
LNX_MT_NodeAddOverride.overridden_draw(self, context)
|
||||
|
@ -769,9 +769,9 @@ const vec3 compoLetterboxColor = vec3(""" + str(round(rpdat.lnx_letterbox_color[
|
||||
"""const float compoSharpenStrength = """ + str(round(rpdat.lnx_sharpen_strength * 100) / 100) + """;
|
||||
""")
|
||||
|
||||
if bpy.data.scenes[0].view_settings.exposure != 0.0:
|
||||
if bpy.utils.get_active_scene().view_settings.exposure != 0.0:
|
||||
f.write(
|
||||
"""const float compoExposureStrength = """ + str(round(bpy.data.scenes[0].view_settings.exposure * 100) / 100) + """;
|
||||
"""const float compoExposureStrength = """ + str(round(bpy.utils.get_active_scene().view_settings.exposure * 100) / 100) + """;
|
||||
""")
|
||||
|
||||
if rpdat.lnx_fog:
|
||||
|
Reference in New Issue
Block a user