merge upstream

This commit is contained in:
2025-06-10 20:28:46 +00:00
16 changed files with 277 additions and 24 deletions

View File

@ -1,26 +1,12 @@
package leenkx.logicnode;
import iron.object.Object;
import iron.math.Vec4;
class GetWorldNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var object: Object = inputs[0].get();
if (object == null) return null;
return switch (property0) {
case "Right": object.transform.world.right();
case "Look": object.transform.world.look();
case "Up": object.transform.world.up();
default: null;
}
return iron.Scene.active.raw.world_ref;
}
}
}

View File

@ -0,0 +1,26 @@
package leenkx.logicnode;
import iron.object.Object;
import iron.math.Vec4;
class GetWorldNode extends LogicNode {
public var property0: String;
public function new(tree: LogicTree) {
super(tree);
}
override function get(from: Int): Dynamic {
var object: Object = inputs[0].get();
if (object == null) return null;
return switch (property0) {
case "Right": object.transform.world.right();
case "Look": object.transform.world.look();
case "Up": object.transform.world.up();
default: null;
}
}
}

View File

@ -0,0 +1,16 @@
package leenkx.logicnode;
class ResolutionGetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
return switch (from) {
case 0: leenkx.renderpath.Postprocess.resolution_uniforms[0];
case 1: leenkx.renderpath.Postprocess.resolution_uniforms[1];
default: 0;
}
}
}

View File

@ -0,0 +1,33 @@
package leenkx.logicnode;
import kha.graphics4.TextureFilter;
class ResolutionSetNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function run(from:Int) {
var size: Int = inputs[1].get();
var filter: Int = inputs[2].get();
#if rp_resolution_filter
if (filter == 0)
iron.object.Uniforms.defaultFilter = TextureFilter.LinearFilter;
else
iron.object.Uniforms.defaultFilter = TextureFilter.PointFilter;
leenkx.renderpath.Postprocess.resolution_uniforms[0] = size;
leenkx.renderpath.Postprocess.resolution_uniforms[1] = filter;
var npath = leenkx.renderpath.RenderPathCreator.get();
var world = iron.Scene.active.raw.world_ref;
npath.loadShader("shader_datas/World_" + world + "/World_" + world);
iron.RenderPath.setActive(npath);
#end
runOutput(0);
}
}

View File

@ -0,0 +1,55 @@
package leenkx.logicnode;
import iron.object.MeshObject;
import iron.data.MaterialData;
class SetMaterialTextureFilterNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
var object: MeshObject = inputs[1].get();
var mat: MaterialData = inputs[2].get();
var slot: Int = inputs[3].get();
var name: String = inputs[4].get();
var filter: Int = inputs[5].get();
if (object == null) return;
if (slot >= object.materials.length) return;
var mo = cast(object, iron.object.MeshObject);
for (i => node in mo.materials[slot].contexts[0].raw.bind_textures)
if (node.name == name){
var moImgt = mo.materials[slot].contexts[0].raw.bind_textures[i];
switch(filter){
case 0: //Linear
moImgt.min_filter = null;
moImgt.mag_filter = null;
moImgt.mipmap_filter = null;
moImgt.generate_mipmaps = null;
case 1: //Closest
moImgt.min_filter = 'point';
moImgt.mag_filter = 'point';
moImgt.mipmap_filter = null;
moImgt.generate_mipmaps = null;
case 2: //Cubic
moImgt.min_filter = null;
moImgt.mag_filter = null;
moImgt.mipmap_filter = 'linear';
moImgt.generate_mipmaps = true;
case 3: //Smart
moImgt.min_filter = 'anisotropic';
moImgt.mag_filter = null;
moImgt.mipmap_filter = 'linear';
moImgt.generate_mipmaps = true;
}
break;
}
runOutput(0);
}
}

View File

@ -0,0 +1,40 @@
package leenkx.logicnode;
class SetWorldNode extends LogicNode {
public function new(tree: LogicTree) {
super(tree);
}
override function run(from: Int) {
var world: String = inputs[1].get();
if (world != null){
//check if world shader data exists
var file: String = 'World_'+world+'_data';
#if lnx_json
file += ".json";
#elseif lnx_compress
file += ".lz4";
#else
file += '.lnx';
#end
var exists: Bool = false;
iron.data.Data.getBlob(file, function(b: kha.Blob) {
if (b != null) exists = true;
});
assert(Error, exists == true, "World must be either associated to a scene or have fake user");
iron.Scene.active.raw.world_ref = world;
var npath = leenkx.renderpath.RenderPathCreator.get();
npath.loadShader("shader_datas/World_" + world + "/World_" + world);
iron.RenderPath.setActive(npath);
}
runOutput(0);
}
}

View File

@ -780,7 +780,11 @@ class Inc {
public static inline function getDisplayp(): Null<Int> {
#if rp_resolution_filter // Custom resolution set
#if rp_pp
return leenkx.renderpath.Postprocess.resolution_uniforms[0];
#else
return Main.resolutionSize;
#end
#else
return null;
#end

View File

@ -133,6 +133,11 @@ class Postprocess {
[50.0] //2: Volumetric Fog Amount B
];
public static var resolution_uniforms = [
720, //0: Size
0 //1: Filter
];
public static function vec3Link(object: Object, mat: MaterialData, link: String): iron.math.Vec4 {
var v:Vec4 = null;

View File

@ -0,0 +1,23 @@
from lnx.logicnode.lnx_nodes import *
class SetMaterialTextureFilterNode(LnxLogicTreeNode):
"""Sets texture filter interpolation."""
bl_idname = 'LNSetMaterialTextureFilterNode'
bl_label = 'Set Object Material Texture Filter'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxNodeSocketObject', 'Object')
self.add_input('LnxDynamicSocket', 'Material')
self.add_input('LnxIntSocket', 'Slot')
self.add_input('LnxStringSocket', 'Node')
self.add_input('LnxIntSocket', 'Texture Filter')
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.label(text='Tex Filter 0: Linear')
layout.label(text='Tex Filter 1: Closest')
layout.label(text='Tex Filter 2: Cubic')
layout.label(text='Tex Filter 3: Smart')

View File

@ -0,0 +1,12 @@
from lnx.logicnode.lnx_nodes import *
class ResolutionGetNode(LnxLogicTreeNode):
"""Returns the resolution parameters.
"""
bl_idname = 'LNResolutionGetNode'
bl_label = 'Get Resolution Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxIntSocket', 'Size')
self.add_output('LnxIntSocket', 'Filter')

View File

@ -0,0 +1,20 @@
from lnx.logicnode.lnx_nodes import *
class ResolutionSetNode(LnxLogicTreeNode):
"""Set the resolution post-processing settings.
Filter 0: Lineal 1: Closest
"""
bl_idname = 'LNResolutionSetNode'
bl_label = 'Set Resolution Settings'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxIntSocket', 'Size', default_value=720)
self.add_input('LnxIntSocket', 'Filter', default_value=0)
self.add_output('LnxNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.label(text="Type 0: Lineal")
layout.label(text="Type 1: Closest")

View File

@ -1,8 +1,8 @@
from lnx.logicnode.lnx_nodes import *
class GetWorldNode(LnxLogicTreeNode):
class GetWorldOrientationNode(LnxLogicTreeNode):
"""Returns the world orientation of the given object."""
bl_idname = 'LNGetWorldNode'
bl_idname = 'LNGetWorldOrientationNode'
bl_label = 'Get World Orientation'
lnx_section = 'rotation'
lnx_version = 1

View File

@ -0,0 +1,10 @@
from lnx.logicnode.lnx_nodes import *
class GetWorldNode(LnxLogicTreeNode):
"""Gets the World of the active scene."""
bl_idname = 'LNGetWorldNode'
bl_label = 'Get World'
lnx_version = 1
def lnx_init(self, context):
self.add_output('LnxStringSocket', 'World')

View File

@ -0,0 +1,13 @@
from lnx.logicnode.lnx_nodes import *
class SetWorldNode(LnxLogicTreeNode):
"""Sets the World of the active scene."""
bl_idname = 'LNSetWorldNode'
bl_label = 'Set World'
lnx_version = 1
def lnx_init(self, context):
self.add_input('LnxNodeSocketAction', 'In')
self.add_input('LnxStringSocket', 'World')
self.add_output('LnxNodeSocketAction', 'Out')

View File

@ -47,11 +47,20 @@ def build():
with write_probes.setup_envmap_render():
for scene in bpy.data.scenes:
world = scene.world
#for scene in bpy.data.scenes:
for world in bpy.data.worlds:
#world = scene.world
# Only export worlds from enabled scenes and only once per world
if scene.lnx_export and world is not None and world not in worlds:
assigned = False;
for scene in bpy.data.scenes:
if scene.lnx_export and scene.world is not None:
if scene.world.name == world.name:
assigned = True;
break;
#if scene.lnx_export and world is not None and world not in worlds:
# Only export worlds from enabled scenes and with fake users
if (world.use_fake_user and world.name != 'Lnx') or assigned:
worlds.append(world)
world.lnx_envtex_name = ''

View File

@ -452,9 +452,10 @@ class LnxRPListItem(bpy.types.PropertyGroup):
lnx_ssrs: BoolProperty(name="SSRS", description="Screen-space ray-traced shadows", default=False, update=assets.invalidate_shader_cache)
lnx_micro_shadowing: BoolProperty(name="Micro Shadowing", description="Use the shaders' occlusion parameter to compute micro shadowing for the scene's sun lamp. This option is not available for render paths using mobile or solid material models", default=False, update=assets.invalidate_shader_cache)
lnx_texture_filter: EnumProperty(
items=[('Anisotropic', 'Anisotropic', 'Anisotropic'),
('Linear', 'Linear', 'Linear'),
items=[('Linear', 'Linear', 'Linear'),
('Point', 'Closest', 'Point'),
('Cubic', 'Cubic', 'Cubic'),
('Anisotropic', 'Smart', 'Anisotropic'),
('Manual', 'Manual', 'Manual')],
name="Texture Filtering", description="Set Manual to honor interpolation setting on Image Texture node", default='Anisotropic')
lnx_material_model: EnumProperty(