@@ -50,7 +50,7 @@ def exp_color(value, exp_list, name=""):
5050
5151def exp_scalar (value , exp_list ):
5252 n = Node ("Scalar" , {
53- "Name" : "" ,
53+ # "Name": "",
5454 "constant" : "%f" % value
5555 })
5656 return exp_list .push (n )
@@ -89,7 +89,7 @@ def exp_texcoord_node(socket, exp_list):
8989def exp_tex_noise (socket , exp_list ):
9090
9191 # default if socket.name == "Fac"
92- function_path = "/DatasmithBlenderContent/MaterialFunctions/Noise "
92+ function_path = "/DatasmithBlenderContent/MaterialFunctions/TexNoise "
9393 out_socket = 0
9494 if socket .name == "Color" :
9595 out_socket = 1
@@ -101,6 +101,25 @@ def exp_tex_noise(socket, exp_list):
101101 n .push (Node ("1" , exp_2 ))
102102 return { "expression" : exp_list .push (n ), "OutputIndex" :out_socket }
103103
104+
105+ def exp_tex_checker (socket , exp_list ):
106+ if socket .node in cached_nodes :
107+ exp = { "expression" : cached_nodes [socket .node ] }
108+ else :
109+ exp = exp_function_call (
110+ "/DatasmithBlenderContent/MaterialFunctions/TexChecker" ,
111+ exp_list = exp_list ,
112+ inputs = socket .node .inputs ,
113+ force_default = True ,
114+ )
115+ cached_nodes [socket .node ] = exp ["expression" ]
116+
117+ # could be faster by comparing to constants instead?
118+ exp ["OutputIndex" ] = socket .node .outputs .find (socket .name )
119+
120+ return exp
121+
122+
104123def exp_uvmap (node , exp_list ):
105124 channel_name = node .uv_map
106125 owner = datasmith_context ["material_owner" ]
@@ -468,6 +487,7 @@ def exp_mixrgb(node, exp_list):
468487 "MAPPING_TEX3D" : "/DatasmithBlenderContent/MaterialFunctions/MappingTexture3D" ,
469488 "MAPPING_NORMAL" : "/DatasmithBlenderContent/MaterialFunctions/MappingNormal" ,
470489 "NORMAL_FROM_HEIGHT" : "/Engine/Functions/Engine_MaterialFunctions03/Procedurals/NormalFromHeightmap" ,
490+ "WORLD_POSITION" : "/DatasmithBlenderContent/MaterialFunctions/BlenderWorldPosition" ,
471491}
472492
473493
@@ -562,7 +582,7 @@ def exp_normal_map(socket, exp_list):
562582def exp_new_geometry (socket , exp_list ):
563583 socket_name = socket .name
564584 if socket_name == "Position" :
565- blend = Node ("WorldPosition" )
585+ blend = Node ("FunctionCall" , { "Function" : op_custom_functions [ "WORLD_POSITION" ]} )
566586 n = exp_list .push (blend )
567587 return { "expression" : n }
568588 if socket_name == "Normal" :
@@ -593,7 +613,7 @@ def exp_new_geometry(socket, exp_list):
593613def exp_texture_coordinates (socket , exp_list ):
594614 socket_name = socket .name
595615 if socket_name == "Position" :
596- blend = Node ("WorldPosition" )
616+ blend = Node ("FunctionCall" , { "Function" : op_custom_functions [ "WORLD_POSITION" ]} )
597617 n = exp_list .push (blend )
598618 return { "expression" : n }
599619 if socket_name == "Normal" :
@@ -825,14 +845,18 @@ def exp_group(socket, exp_list):
825845 node = socket .node
826846 global group_context
827847 global reverse_expressions
848+ global cached_nodes
828849 new_context = {}
850+ new_cached_nodes = {}
829851 for input in node .inputs :
830852 new_context [input .name ] = get_expression (input , exp_list )
831853
832854 previous_reverse = reverse_expressions
833855 reverse_expressions = {}
834856 previous_context = group_context
857+ previous_cached_nodes = cached_nodes
835858 group_context = new_context
859+ cached_nodes = new_cached_nodes
836860
837861 # now traverse the inner graph
838862 output_name = socket .name
@@ -852,6 +876,7 @@ def exp_group(socket, exp_list):
852876 inner_exp = get_expression (inner_socket , exp_list )
853877
854878 group_context = previous_context
879+ cached_nodes = previous_cached_nodes
855880 reverse_expressions = previous_reverse
856881 return inner_exp
857882
@@ -944,7 +969,7 @@ def get_expression(field, exp_list, force_default=False):
944969 socket = field .links [0 ].from_socket
945970 reverse_expressions [socket ] = return_exp
946971
947- log .debug (expression_log_prefix + "end field:" + field_path )
972+ log .debug ("%send field:%s = %s" % ( expression_log_prefix , field_path , return_exp ) )
948973
949974 return return_exp
950975
@@ -981,6 +1006,7 @@ def get_expression_inner(field, exp_list):
9811006 "BaseColor" : get_expression (node .inputs ['Base Color' ], exp_list ),
9821007 "Metallic" : get_expression (node .inputs ['Metallic' ], exp_list ),
9831008 "Roughness" : get_expression (node .inputs ['Roughness' ], exp_list ),
1009+ "Specular" : get_expression (node .inputs ['Specular' ], exp_list ),
9841010 }
9851011
9861012 # only add opacity if transmission != 0
@@ -1044,6 +1070,7 @@ def get_expression_inner(field, exp_list):
10441070 log .warn ("BSDF_GLASS incomplete implementation" )
10451071 bsdf = {
10461072 "BaseColor" : get_expression (node .inputs ['Color' ], exp_list ),
1073+ "Metallic" : { "expression" : exp_scalar (1 , exp_list ) },
10471074 "Roughness" : get_expression (node .inputs ['Roughness' ], exp_list ),
10481075 "Refraction" : get_expression (node .inputs ['IOR' ], exp_list ),
10491076 "Opacity" : {"expression" : exp_scalar (0.5 , exp_list )},
@@ -1189,7 +1216,8 @@ def get_expression_inner(field, exp_list):
11891216
11901217 # Add > Texture
11911218 # if node.type == 'TEX_BRICK':
1192- # if node.type == 'TEX_CHECKER':
1219+ if node .type == 'TEX_CHECKER' :
1220+ return exp_tex_checker (socket , exp_list )
11931221 # if node.type == 'TEX_ENVIRONMENT':
11941222 # if node.type == 'TEX_GRADIENT':
11951223 # if node.type == 'TEX_IES':
@@ -1201,12 +1229,15 @@ def get_expression_inner(field, exp_list):
12011229 cached_node = reverse_expressions [node ]
12021230
12031231 if not cached_node :
1232+ image = node .image
1233+ if not image :
1234+ return { "expression" : exp_scalar (0 , exp_list ) }
1235+
12041236
12051237 tex_coord = get_expression (node .inputs ['Vector' ], exp_list )
12061238
12071239
12081240 name = ""
1209- image = node .image
12101241 if image :
12111242 name = sanitize_name (image .name ) # name_full?
12121243
@@ -1469,9 +1500,19 @@ def fill_umesh(umesh, bl_mesh):
14691500
14701501 uvs = []
14711502 num_uvs = min (8 , len (m .uv_layers ))
1503+ active_uv = 0
14721504 for idx in range (num_uvs ):
1505+ if m .uv_layers [idx ].active_render :
1506+ active_uv = idx
1507+ for idx in range (num_uvs ):
1508+ uv_idx = idx # swap active_render UV with channel 0
1509+ if uv_idx == 0 :
1510+ uv_idx = active_uv
1511+ elif uv_idx == active_uv :
1512+ uv_idx = 0
1513+
14731514 uv_channel = np .empty (num_loops * 2 , np .float32 )
1474- uv_data = m .uv_layers [idx ].data
1515+ uv_data = m .uv_layers [uv_idx ].data
14751516 uv_data .foreach_get ("uv" , uv_channel )
14761517 uv_channel = uv_channel .reshape ((num_loops , 2 ))
14771518 uv_channel [:,1 ] = 1 - uv_channel [:,1 ]
@@ -1824,8 +1865,7 @@ def collect_object_transform(bl_obj, instance_matrix=None):
18241865 elif bl_obj .type == 'LIGHT_PROBE' :
18251866 bl_probe = bl_obj .data
18261867 if bl_probe .type == 'PLANAR' :
1827- size = bl_probe .influence_distance * 2.5 # 100 / 40 as the UE4 mirror size is 40m wide
1828- obj_mat = obj_mat @ Matrix .Scale (size , 4 )
1868+ obj_mat = obj_mat @ Matrix .Scale (0.05 , 4 )
18291869 elif bl_probe .type == 'CUBEMAP' :
18301870 if bl_probe .influence_type == 'BOX' :
18311871 size = bl_probe .influence_distance * 100
0 commit comments