From 84dd5b76f107429be2d0571ce5c14ff892e9f662 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sat, 23 Jul 2022 17:22:44 +0800 Subject: [PATCH] add feature, optimize function argv passing. - add support of 4 alpha fields intorduced in BM spec recently. - optimize material creation functions argv passing strategy. - change related func calls of (2). - optimize material parameter pick code to reduce useless check. --- ballance_blender_plugin/BMFILE_export.py | 102 +++++++++--------- ballance_blender_plugin/BMFILE_import.py | 9 +- ballance_blender_plugin/OBJS_add_floors.py | 5 +- .../PROPS_virtools_material.py | 6 +- ballance_blender_plugin/UTILS_functions.py | 18 ++-- .../UTILS_virtools_prop.py | 48 +++++++-- 6 files changed, 112 insertions(+), 76 deletions(-) diff --git a/ballance_blender_plugin/BMFILE_export.py b/ballance_blender_plugin/BMFILE_export.py index 03bd376..fb85134 100644 --- a/ballance_blender_plugin/BMFILE_export.py +++ b/ballance_blender_plugin/BMFILE_export.py @@ -241,72 +241,66 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar UTILS_file_io.write_uint64(finfo, fmaterial.tell()) # try get original written data - (material_colAmbient, material_colDiffuse, material_colSpecular, - material_colEmissive, material_specularPower) = UTILS_virtools_prop.get_virtools_material_data(material) + (material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, + material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided, + material_texture) = UTILS_virtools_prop.get_virtools_material_data(material) - # get basic color - mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material) - if mat_wrap: - # we trying get texture data from Principled BSDF - # because bpy.types.Material.virtools_material now can provide - # Virtools material data stablely, so i annotate following code - # only keep texture data - ''' - use_mirror = mat_wrap.metallic != 0.0 - if use_mirror: - material_colAmbient = _set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic)) - else: - material_colAmbient = _set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0)) - material_colDiffuse = _set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2])) - material_colSpecular = _set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)) - material_colEmissive = _set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3]) - material_specularPower = _set_value_when_none(material_specularPower, 0.0) - ''' - - # confirm texture - tex_wrap = getattr(mat_wrap, "base_color_texture", None) - if tex_wrap: - image = tex_wrap.image - if image: - # add into texture list - if image not in textureSet: - textureSet.add(image) - textureList.append(image) - textureIndex = textureCount - textureCount += 1 - else: - textureIndex = textureList.index(image) - - material_useTexture = True - material_textureIndex = textureIndex + # only try get from Principled BSDF when we couldn't get from virtools_material props + if material_texture is None: + # get node + mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material) + # check existence of Principled BSDF + if mat_wrap: + # we trying get texture data from Principled BSDF + # because bpy.types.Material.virtools_material now can provide + # Virtools material data stablely, so i annotate following code + # only keep texture data + ''' + use_mirror = mat_wrap.metallic != 0.0 + if use_mirror: + material_colAmbient = _set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic)) else: - # no texture - material_useTexture = False - material_textureIndex = 0 - else: - # no texture - material_useTexture = False - material_textureIndex = 0 + material_colAmbient = _set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0)) + material_colDiffuse = _set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2])) + material_colSpecular = _set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)) + material_colEmissive = _set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3]) + material_specularPower = _set_value_when_none(material_specularPower, 0.0) + ''' - else: - # no Principled BSDF. write garbage - # same reason for disabling following code - ''' - material_colAmbient = _set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8)) - material_colDiffuse = _set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8)) - material_colSpecular = _set_value_when_none(material_colSpecular, (0.8, 0.8, 0.8)) - material_colEmissive = _set_value_when_none(material_colEmissive, (0.8, 0.8, 0.8)) - material_specularPower = _set_value_when_none(material_specularPower, 0.0) - ''' + # confirm texture + tex_wrap = getattr(mat_wrap, "base_color_texture", None) + if tex_wrap: + image = tex_wrap.image + if image: + material_texture = image + + # check texture index + if material_texture is None: material_useTexture = False material_textureIndex = 0 + else: + # add into texture list + if material_texture not in textureSet: + textureSet.add(material_texture) + textureList.append(material_texture) + textureIndex = textureCount + textureCount += 1 + else: + textureIndex = textureList.index(material_texture) + + material_useTexture = True + material_textureIndex = textureIndex UTILS_file_io.write_color(fmaterial, material_colAmbient) UTILS_file_io.write_color(fmaterial, material_colDiffuse) UTILS_file_io.write_color(fmaterial, material_colSpecular) UTILS_file_io.write_color(fmaterial, material_colEmissive) UTILS_file_io.write_float(fmaterial, material_specularPower) + UTILS_file_io.write_bool(fmaterial, material_alphaTest) + UTILS_file_io.write_bool(fmaterial, material_alphaBlend) + UTILS_file_io.write_bool(fmaterial, material_zBuffer) + UTILS_file_io.write_bool(fmaterial, material_twoSided) UTILS_file_io.write_bool(fmaterial, material_useTexture) UTILS_file_io.write_uint32(fmaterial, material_textureIndex) diff --git a/ballance_blender_plugin/BMFILE_import.py b/ballance_blender_plugin/BMFILE_import.py index 4a7ca75..69b66f6 100644 --- a/ballance_blender_plugin/BMFILE_import.py +++ b/ballance_blender_plugin/BMFILE_import.py @@ -157,6 +157,10 @@ def import_bm(context, bmx_filepath, prefs_fncg, prefs_externalTexture, prefs_te material_colSpecular = UTILS_file_io.read_3vector(fmaterial) material_colEmissive = UTILS_file_io.read_3vector(fmaterial) material_specularPower = UTILS_file_io.read_float(fmaterial) + material_alphaTest = UTILS_file_io.read_bool(fmaterial) + material_alphaBlend = UTILS_file_io.read_bool(fmaterial) + material_zBuffer = UTILS_file_io.read_bool(fmaterial) + material_twoSided = UTILS_file_io.read_bool(fmaterial) material_useTexture = UTILS_file_io.read_bool(fmaterial) material_texture = UTILS_file_io.read_uint32(fmaterial) @@ -169,9 +173,10 @@ def import_bm(context, bmx_filepath, prefs_fncg, prefs_externalTexture, prefs_te # try create material nodes UTILS_functions.create_blender_material(material_target, - material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, - material_specularPower, + (material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, + material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided, textureList[material_texture].blender_data if material_useTexture else None) + ) # mesh.bm # WARNING: this code is shared with add_floor diff --git a/ballance_blender_plugin/OBJS_add_floors.py b/ballance_blender_plugin/OBJS_add_floors.py index 7e7ec77..7b3e308 100644 --- a/ballance_blender_plugin/OBJS_add_floors.py +++ b/ballance_blender_plugin/OBJS_add_floors.py @@ -214,11 +214,14 @@ def _create_or_get_material(material_name, prefs_externalTexture): if material_name in try_item['member']: # got it # set material data + # all floor do not have any transparency props, so we provide 4 False value. UTILS_functions.create_blender_material(mtl, - try_item['data']['ambient'], try_item['data']['diffuse'], + (try_item['data']['ambient'], try_item['data']['diffuse'], try_item['data']['specular'], try_item['data']['emissive'], try_item['data']['power'], + False, False, False, False, texture) + ) break # return mtl diff --git a/ballance_blender_plugin/PROPS_virtools_material.py b/ballance_blender_plugin/PROPS_virtools_material.py index 9977d56..84d148d 100644 --- a/ballance_blender_plugin/PROPS_virtools_material.py +++ b/ballance_blender_plugin/PROPS_virtools_material.py @@ -14,7 +14,7 @@ class BALLANCE_OT_apply_virtools_material(bpy.types.Operator): def execute(self, context): mtl = context.material mtl_data = UTILS_virtools_prop.get_virtools_material_data(mtl) - UTILS_functions.create_material_nodes(mtl, *mtl_data) + UTILS_functions.create_material_nodes(mtl, mtl_data) return {'FINISHED'} @@ -41,6 +41,10 @@ class BALLANCE_PT_virtools_material(bpy.types.Panel): layout.prop(target, 'specular') layout.prop(target, 'emissive') layout.prop(target, 'specular_power') + layout.prop(target, 'alpha_test') + layout.prop(target, 'alpha_blend') + layout.prop(target, 'z_buffer') + layout.prop(target, 'two_sided') layout.operator("ballance.apply_virtools_material", icon="NODETREE") diff --git a/ballance_blender_plugin/UTILS_functions.py b/ballance_blender_plugin/UTILS_functions.py index cde045d..4c277f7 100644 --- a/ballance_blender_plugin/UTILS_functions.py +++ b/ballance_blender_plugin/UTILS_functions.py @@ -42,21 +42,19 @@ def get_component_id(name): # ================================= # create material -def create_blender_material(input_mtl, ambient, diffuse, specular, emissive, - specular_power, texture): +def create_blender_material(input_mtl, packed_data): # adding material nodes - create_material_nodes(input_mtl, - ambient, diffuse, specular, emissive, specular_power, texture - ) + create_material_nodes(input_mtl, packed_data) # write custom property - UTILS_virtools_prop.set_virtools_material_data(input_mtl, - ambient, diffuse, specular, emissive, specular_power, texture - ) + UTILS_virtools_prop.set_virtools_material_data(input_mtl, packed_data) -def create_material_nodes(input_mtl, ambient, diffuse, specular, emissive, - specular_power, texture): +def create_material_nodes(input_mtl, packed_data): + + (ambient, diffuse, specular, emissive, specular_power, + alpha_test, alpha_blend, z_buffer, two_sided, + texture) = packed_data # enable nodes mode input_mtl.use_nodes=True diff --git a/ballance_blender_plugin/UTILS_virtools_prop.py b/ballance_blender_plugin/UTILS_virtools_prop.py index 816ee1f..3406a98 100644 --- a/ballance_blender_plugin/UTILS_virtools_prop.py +++ b/ballance_blender_plugin/UTILS_virtools_prop.py @@ -33,6 +33,29 @@ class BALLANCE_PG_virtools_material(bpy.types.PropertyGroup): default=0.0, ) + alpha_test: bpy.props.BoolProperty( + name="Alpha Test", + description="Alpha Func: VXCMP_GREATER. Alpha Ref: 1.", + default=False, + ) + + alpha_blend: bpy.props.BoolProperty( + name="Alpha Blend", + description="Source Blend: VXBLEND_SRCALPHA. Dest Blend: VXBLEND_INVSRCALPHA.", + default=False, + ) + + z_buffer: bpy.props.BoolProperty( + name="Z Buffer", + description="ZFunc: VXCMP_LESSEQUAL.", + default=False, + ) + + two_sided: bpy.props.BoolProperty( + name="Two Sided", + default=False, + ) + texture: bpy.props.PointerProperty( type=bpy.types.Image, name="Texture", @@ -50,16 +73,25 @@ def get_virtools_material(mtl): def get_virtools_material_data(mtl): data = get_virtools_material(mtl) - return (data.ambient, data.diffuse, data.specular, data.emissive, data.specular_power, data.texture) + return ( + data.ambient, + data.diffuse, + data.specular, + data.emissive, + data.specular_power, + data.alpha_test, + data.alpha_blend, + data.z_buffer, + data.two_sided, + data.texture + ) -def set_virtools_material_data(mtl, ambient, diffuse, specular, emissive, specular_power, texture): +def set_virtools_material_data(mtl, packed_data): data = get_virtools_material(mtl) - data.ambient = ambient - data.diffuse = diffuse - data.specular = specular - data.emissive = emissive - data.specular_power = specular_power - data.texture = texture + # packed_data have the same order with the return value of `get_virtools_material_data` + (data.ambient, data.diffuse, data.specular, data.emissive, data.specular_power, + data.alpha_test, data.alpha_blend, data.z_buffer, data.two_sided, + data.texture) = packed_data def get_active_virtools_group(obj): return obj.active_virtools_group