193 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			193 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								from bpy.props import *
							 | 
						||
| 
								 | 
							
								from bpy.types import Node
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from lnx.material.lnx_nodes.lnx_nodes import add_node
							 | 
						||
| 
								 | 
							
								from lnx.material.shader import Shader
							 | 
						||
| 
								 | 
							
								from lnx.material.cycles import *
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if lnx.is_reload(__name__):
							 | 
						||
| 
								 | 
							
								    import lnx
							 | 
						||
| 
								 | 
							
								    lnx.material.lnx_nodes.lnx_nodes = lnx.reload_module(lnx.material.lnx_nodes.lnx_nodes)
							 | 
						||
| 
								 | 
							
								    from lnx.material.lnx_nodes.lnx_nodes import add_node
							 | 
						||
| 
								 | 
							
								    lnx.material.shader = lnx.reload_module(lnx.material.shader)
							 | 
						||
| 
								 | 
							
								    from lnx.material.shader import Shader
							 | 
						||
| 
								 | 
							
								    lnx.material.cycles = lnx.reload_module(lnx.material.cycles)
							 | 
						||
| 
								 | 
							
								    from lnx.material.cycles import *
							 | 
						||
| 
								 | 
							
								else:
							 | 
						||
| 
								 | 
							
								    lnx.enable_reload(__name__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class CustomParticleNode(Node):
							 | 
						||
| 
								 | 
							
								    """Input data for paricles."""
							 | 
						||
| 
								 | 
							
								    bl_idname = 'LnxCustomParticleNode'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Custom Particle'
							 | 
						||
| 
								 | 
							
								    bl_icon = 'NONE'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    posX: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable translation along x",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    posY: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable translation along y",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    posZ: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable translation along z",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rotX: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable rotation along x",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rotY: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable rotation along y",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rotZ: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable rotation along z",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sclX: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable scaling along x",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sclY: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable scaling along y",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sclZ: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="",
							 | 
						||
| 
								 | 
							
								        description="enable scaling along z",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    billBoard: BoolProperty(
							 | 
						||
| 
								 | 
							
								        name="Bill Board",
							 | 
						||
| 
								 | 
							
								        description="Enable Bill Board",
							 | 
						||
| 
								 | 
							
								        default=False,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def init(self, context):
							 | 
						||
| 
								 | 
							
								        self.inputs.new('NodeSocketVector', 'Position')
							 | 
						||
| 
								 | 
							
								        self.inputs.new('NodeSocketVector', 'Rotation')
							 | 
						||
| 
								 | 
							
								        self.inputs.new('NodeSocketVector', 'Scale')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def draw_buttons(self, context, layout):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        grid0 = layout.grid_flow(row_major=True, columns=4, align=False)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        grid0.label(text="")
							 | 
						||
| 
								 | 
							
								        grid0.label(text=" X")
							 | 
						||
| 
								 | 
							
								        grid0.label(text=" Y")
							 | 
						||
| 
								 | 
							
								        grid0.label(text=" Z")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        grid0.label(text="Pos")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "posX")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "posY")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "posZ")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        grid0.label(text="Rot")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "rotX")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "rotY")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "rotZ")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        grid0.label(text="Scl")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "sclX")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "sclY")
							 | 
						||
| 
								 | 
							
								        grid0.prop(self, "sclZ")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        layout.prop(self, "billBoard")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def parse(self, vertshdr: Shader, part_con) -> None:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.sclX or self.sclY or self.sclZ:
							 | 
						||
| 
								 | 
							
								            scl = parse_vector_input(self.inputs[2])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.sclX:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'spos.x *= {scl}.x;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.sclY:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'spos.y *= {scl}.y;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.sclX:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'spos.z *= {scl}.z;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.billBoard:
							 | 
						||
| 
								 | 
							
								            vertshdr.add_uniform('mat4 WV', '_worldViewMatrix')
							 | 
						||
| 
								 | 
							
								            vertshdr.write('spos = mat4(transpose(mat3(WV))) * spos;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.rotX or self.rotY or self.rotZ:
							 | 
						||
| 
								 | 
							
								            rot = parse_vector_input(self.inputs[1])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.rotX and not self.rotY and not self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(1.0, 0.0, 0.0,')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                       0.0, cos({rot}.x), sin({rot}.x),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                       0.0, -sin({rot}.x), cos({rot}.x));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if not self.rotX and self.rotY and not self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(cos({rot}.y), 0.0, -sin({rot}.y),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                       0.0, 1.0, 0.0,')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                       sin({rot}.y), 0.0, cos({rot}.y));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if not self.rotX and not self.rotY and self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(cos({rot}.z), sin({rot}.z), 0.0,')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                       -sin({rot}.z), cos({rot}.z), 0.0,')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                       0.0, 0.0, 1.0);')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.rotX and self.rotY and not self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(cos({rot}.y), 0.0, -sin({rot}.y),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         sin({rot}.y) * sin({rot}.x), cos({rot}.x), cos({rot}.y) * sin({rot}.x),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         sin({rot}.y) * cos({rot}.x), -sin({rot}.x), cos({rot}.y) * cos({rot}.x));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.rotX and not self.rotY and self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(cos({rot}.z), sin({rot}.z), 0.0,')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         -sin({rot}.z) * cos({rot}.x), cos({rot}.z) * cos({rot}.x), sin({rot}.x),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         sin({rot}.z) * sin({rot}.x), -cos({rot}.z) * sin({rot}.x), cos({rot}.x));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if not self.rotX and self.rotY and self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(cos({rot}.z) * cos({rot}.y), sin({rot}.z) * cos({rot}.y), -sin({rot}.y),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         -sin({rot}.z) , cos({rot}.z), 0.0,')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         cos({rot}.z) * sin({rot}.y), sin({rot}.z) * sin({rot}.y), cos({rot}.y));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.rotX and self.rotY and self.rotZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'mat3 part_rot_mat = mat3(cos({rot}.z) * cos({rot}.y), sin({rot}.z) * cos({rot}.y), -sin({rot}.y),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         -sin({rot}.z) * cos({rot}.x) + cos({rot}.z) * sin({rot}.y) * sin({rot}.x), cos({rot}.z) * cos({rot}.x) + sin({rot}.z) * sin({rot}.y) * sin({rot}.x), cos({rot}.y) * sin({rot}.x),')
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'                         sin({rot}.z) * sin({rot}.x) + cos({rot}.z) * sin({rot}.y) * cos({rot}.x), -cos({rot}.z) * sin({rot}.x) + sin({rot}.z) * sin({rot}.y) * cos({rot}.x), cos({rot}.y) * cos({rot}.x));')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vertshdr.write('spos.xyz = part_rot_mat * spos.xyz;')
							 | 
						||
| 
								 | 
							
								            if (part_con.data['name'] == 'mesh' or part_con.data['name'] == 'translucent' or part_con.data['name'] == 'refraction'):
							 | 
						||
| 
								 | 
							
								                vertshdr.write('wnormal = transpose(inverse(part_rot_mat)) * wnormal;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.posX or self.posY or self.posZ:
							 | 
						||
| 
								 | 
							
								            pos = parse_vector_input(self.inputs[0])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.posX:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'spos.x += {pos}.x;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.posY:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'spos.y += {pos}.y;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.posZ:
							 | 
						||
| 
								 | 
							
								                vertshdr.write(f'spos.z += {pos}.z;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        vertshdr.write('wposition = vec4(W * spos).xyz;')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_node(CustomParticleNode, category='Leenkx')
							 |