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.
This commit is contained in:
yyc12345 2022-07-23 17:22:44 +08:00
parent 2950857e3d
commit 84dd5b76f1
6 changed files with 112 additions and 76 deletions

View File

@ -241,72 +241,66 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
UTILS_file_io.write_uint64(finfo, fmaterial.tell()) UTILS_file_io.write_uint64(finfo, fmaterial.tell())
# try get original written data # try get original written data
(material_colAmbient, material_colDiffuse, material_colSpecular, (material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower,
material_colEmissive, material_specularPower) = UTILS_virtools_prop.get_virtools_material_data(material) material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided,
material_texture) = UTILS_virtools_prop.get_virtools_material_data(material)
# get basic color # only try get from Principled BSDF when we couldn't get from virtools_material props
mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material) if material_texture is None:
if mat_wrap: # get node
# we trying get texture data from Principled BSDF mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material)
# because bpy.types.Material.virtools_material now can provide # check existence of Principled BSDF
# Virtools material data stablely, so i annotate following code if mat_wrap:
# only keep texture data # we trying get texture data from Principled BSDF
''' # because bpy.types.Material.virtools_material now can provide
use_mirror = mat_wrap.metallic != 0.0 # Virtools material data stablely, so i annotate following code
if use_mirror: # only keep texture data
material_colAmbient = _set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic)) '''
else: use_mirror = mat_wrap.metallic != 0.0
material_colAmbient = _set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0)) if use_mirror:
material_colDiffuse = _set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2])) material_colAmbient = _set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
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
else: else:
# no texture material_colAmbient = _set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0))
material_useTexture = False material_colDiffuse = _set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2]))
material_textureIndex = 0 material_colSpecular = _set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular))
else: material_colEmissive = _set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3])
# no texture material_specularPower = _set_value_when_none(material_specularPower, 0.0)
material_useTexture = False '''
material_textureIndex = 0
else: # confirm texture
# no Principled BSDF. write garbage tex_wrap = getattr(mat_wrap, "base_color_texture", None)
# same reason for disabling following code if tex_wrap:
''' image = tex_wrap.image
material_colAmbient = _set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8)) if image:
material_colDiffuse = _set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8)) material_texture = image
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)
'''
# check texture index
if material_texture is None:
material_useTexture = False material_useTexture = False
material_textureIndex = 0 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_colAmbient)
UTILS_file_io.write_color(fmaterial, material_colDiffuse) UTILS_file_io.write_color(fmaterial, material_colDiffuse)
UTILS_file_io.write_color(fmaterial, material_colSpecular) UTILS_file_io.write_color(fmaterial, material_colSpecular)
UTILS_file_io.write_color(fmaterial, material_colEmissive) UTILS_file_io.write_color(fmaterial, material_colEmissive)
UTILS_file_io.write_float(fmaterial, material_specularPower) 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_bool(fmaterial, material_useTexture)
UTILS_file_io.write_uint32(fmaterial, material_textureIndex) UTILS_file_io.write_uint32(fmaterial, material_textureIndex)

View File

@ -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_colSpecular = UTILS_file_io.read_3vector(fmaterial)
material_colEmissive = UTILS_file_io.read_3vector(fmaterial) material_colEmissive = UTILS_file_io.read_3vector(fmaterial)
material_specularPower = UTILS_file_io.read_float(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_useTexture = UTILS_file_io.read_bool(fmaterial)
material_texture = UTILS_file_io.read_uint32(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 # try create material nodes
UTILS_functions.create_blender_material(material_target, UTILS_functions.create_blender_material(material_target,
material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, (material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower,
material_specularPower, material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided,
textureList[material_texture].blender_data if material_useTexture else None) textureList[material_texture].blender_data if material_useTexture else None)
)
# mesh.bm # mesh.bm
# WARNING: this code is shared with add_floor # WARNING: this code is shared with add_floor

View File

@ -214,11 +214,14 @@ def _create_or_get_material(material_name, prefs_externalTexture):
if material_name in try_item['member']: if material_name in try_item['member']:
# got it # got it
# set material data # set material data
# all floor do not have any transparency props, so we provide 4 False value.
UTILS_functions.create_blender_material(mtl, 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']['specular'], try_item['data']['emissive'],
try_item['data']['power'], try_item['data']['power'],
False, False, False, False,
texture) texture)
)
break break
# return mtl # return mtl

View File

@ -14,7 +14,7 @@ class BALLANCE_OT_apply_virtools_material(bpy.types.Operator):
def execute(self, context): def execute(self, context):
mtl = context.material mtl = context.material
mtl_data = UTILS_virtools_prop.get_virtools_material_data(mtl) 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'} return {'FINISHED'}
@ -41,6 +41,10 @@ class BALLANCE_PT_virtools_material(bpy.types.Panel):
layout.prop(target, 'specular') layout.prop(target, 'specular')
layout.prop(target, 'emissive') layout.prop(target, 'emissive')
layout.prop(target, 'specular_power') 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") layout.operator("ballance.apply_virtools_material", icon="NODETREE")

View File

@ -42,21 +42,19 @@ def get_component_id(name):
# ================================= # =================================
# create material # create material
def create_blender_material(input_mtl, ambient, diffuse, specular, emissive, def create_blender_material(input_mtl, packed_data):
specular_power, texture):
# adding material nodes # adding material nodes
create_material_nodes(input_mtl, create_material_nodes(input_mtl, packed_data)
ambient, diffuse, specular, emissive, specular_power, texture
)
# write custom property # write custom property
UTILS_virtools_prop.set_virtools_material_data(input_mtl, UTILS_virtools_prop.set_virtools_material_data(input_mtl, packed_data)
ambient, diffuse, specular, emissive, specular_power, texture
)
def create_material_nodes(input_mtl, ambient, diffuse, specular, emissive, def create_material_nodes(input_mtl, packed_data):
specular_power, texture):
(ambient, diffuse, specular, emissive, specular_power,
alpha_test, alpha_blend, z_buffer, two_sided,
texture) = packed_data
# enable nodes mode # enable nodes mode
input_mtl.use_nodes=True input_mtl.use_nodes=True

View File

@ -33,6 +33,29 @@ class BALLANCE_PG_virtools_material(bpy.types.PropertyGroup):
default=0.0, 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( texture: bpy.props.PointerProperty(
type=bpy.types.Image, type=bpy.types.Image,
name="Texture", name="Texture",
@ -50,16 +73,25 @@ def get_virtools_material(mtl):
def get_virtools_material_data(mtl): def get_virtools_material_data(mtl):
data = get_virtools_material(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 = get_virtools_material(mtl)
data.ambient = ambient # packed_data have the same order with the return value of `get_virtools_material_data`
data.diffuse = diffuse (data.ambient, data.diffuse, data.specular, data.emissive, data.specular_power,
data.specular = specular data.alpha_test, data.alpha_blend, data.z_buffer, data.two_sided,
data.emissive = emissive data.texture) = packed_data
data.specular_power = specular_power
data.texture = texture
def get_active_virtools_group(obj): def get_active_virtools_group(obj):
return obj.active_virtools_group return obj.active_virtools_group