BallanceBlenderHelper/bbp_ng/PROP_virtools_material.py

760 lines
36 KiB
Python
Raw Normal View History

2023-10-11 10:55:45 +08:00
import bpy
2023-10-12 22:15:21 +08:00
import typing, enum
2023-10-11 22:24:22 +08:00
from . import UTIL_virtools_types, UTIL_functions
2023-11-11 13:32:58 +08:00
from . import PROP_virtools_texture
2023-10-11 10:55:45 +08:00
2023-10-12 22:15:21 +08:00
#region Enums Annotations
2023-11-11 13:32:58 +08:00
from .UTIL_functions import AnnotationData, BlenderEnumPropEntry_t, generate_vt_enums_for_bl_enumprop
2023-10-12 22:15:21 +08:00
g_Annotation_VXTEXTURE_BLENDMODE: dict[int, AnnotationData] = {
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_DECAL.value: AnnotationData("Decal", "Texture replace any material information "),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_MODULATE.value: AnnotationData("Modulate", "Texture and material are combine. Alpha information of the texture replace material alpha component. "),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_DECALALPHA.value: AnnotationData("Decal Alpha", "Alpha information in the texture specify how material and texture are combined. Alpha information of the texture replace material alpha component. "),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_MODULATEALPHA.value: AnnotationData("Modulate Alpha", "Alpha information in the texture specify how material and texture are combined "),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_DECALMASK.value: AnnotationData("Decal Mask", ""),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_MODULATEMASK.value: AnnotationData("Modulate Mask", ""),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_COPY.value: AnnotationData("Copy", "Equivalent to DECAL "),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_ADD.value: AnnotationData("Add", ""),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_DOTPRODUCT3.value: AnnotationData("Dot Product 3", "Perform a Dot Product 3 between texture (normal map) and a referential vector given in VXRENDERSTATE_TEXTUREFACTOR. "),
UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_MAX.value: AnnotationData("Max", ""),
}
g_Annotation_VXTEXTURE_FILTERMODE: dict[int, AnnotationData] = {
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_NEAREST.value: AnnotationData("Nearest", "No Filter "),
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_LINEAR.value: AnnotationData("Linear", "Bilinear Interpolation "),
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_MIPNEAREST.value: AnnotationData("Mip Nearest", "Mip mapping "),
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_MIPLINEAR.value: AnnotationData("Mip Linear", "Mip Mapping with Bilinear interpolation "),
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_LINEARMIPNEAREST.value: AnnotationData("Linear Mip Nearest", "Mip Mapping with Bilinear interpolation between mipmap levels. "),
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_LINEARMIPLINEAR.value: AnnotationData("Linear Mip Linear", "Trilinear Filtering "),
UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_ANISOTROPIC.value: AnnotationData("Anisotropic", "Anisotropic filtering "),
}
g_Annotation_VXBLEND_MODE: dict[int, AnnotationData] = {
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_ZERO.value: AnnotationData("Zero", "Blend factor is (0, 0, 0, 0). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_ONE.value: AnnotationData("One", "Blend factor is (1, 1, 1, 1). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_SRCCOLOR.value: AnnotationData("Src Color", "Blend factor is (Rs, Gs, Bs, As). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_INVSRCCOLOR.value: AnnotationData("Inv Src Color", "Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_SRCALPHA.value: AnnotationData("Src Alpha", "Blend factor is (As, As, As, As). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_INVSRCALPHA.value: AnnotationData("Inv Src Alpha", "Blend factor is (1-As, 1-As, 1-As, 1-As). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_DESTALPHA.value: AnnotationData("Dest Alpha", "Blend factor is (Ad, Ad, Ad, Ad). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_INVDESTALPHA.value: AnnotationData("Inv Dest Alpha", "Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_DESTCOLOR.value: AnnotationData("Dest Color", "Blend factor is (Rd, Gd, Bd, Ad). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_INVDESTCOLOR.value: AnnotationData("Inv Dest Color", "Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad). "),
UTIL_virtools_types.VXBLEND_MODE.VXBLEND_SRCALPHASAT.value: AnnotationData("Src Alpha Sat", "Blend factor is (f, f, f, 1); f = min(As, 1-Ad). "),
#UTIL_virtools_types.VXBLEND_MODE.VXBLEND_BOTHSRCALPHA.value: AnnotationData("Both Src Alpha", "Source blend factor is (As, As, As, As) and destination blend factor is (1-As, 1-As, 1-As, 1-As) "),
#UTIL_virtools_types.VXBLEND_MODE.VXBLEND_BOTHINVSRCALPHA.value: AnnotationData("Both Inv Src Alpha", "Source blend factor is (1-As, 1-As, 1-As, 1-As) and destination blend factor is (As, As, As, As) "),
}
g_Annotation_VXTEXTURE_ADDRESSMODE: dict[int, AnnotationData] = {
UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSWRAP.value: AnnotationData("Wrap", "Default mesh wrap mode is used (see CKMesh::SetWrapMode) "),
UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSMIRROR.value: AnnotationData("Mirror", "Texture coordinates outside the range [0..1] are flipped evenly. "),
UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSCLAMP.value: AnnotationData("Clamp", "Texture coordinates greater than 1.0 are set to 1.0, and values less than 0.0 are set to 0.0. "),
UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSBORDER.value: AnnotationData("Border", "When texture coordinates are greater than 1.0 or less than 0.0 texture is set to a color defined in CKMaterial::SetTextureBorderColor. "),
UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSMIRRORONCE.value: AnnotationData("Mirror Once", " "),
}
g_Annotation_VXFILL_MODE: dict[int, AnnotationData] = {
UTIL_virtools_types.VXFILL_MODE.VXFILL_POINT.value: AnnotationData("Point", "Vertices rendering "),
UTIL_virtools_types.VXFILL_MODE.VXFILL_WIREFRAME.value: AnnotationData("Wireframe", "Edges rendering "),
UTIL_virtools_types.VXFILL_MODE.VXFILL_SOLID.value: AnnotationData("Solid", "Face rendering "),
}
g_Annotation_VXSHADE_MODE: dict[int, AnnotationData] = {
UTIL_virtools_types.VXSHADE_MODE.VXSHADE_FLAT.value: AnnotationData("Flat", "Flat Shading "),
UTIL_virtools_types.VXSHADE_MODE.VXSHADE_GOURAUD.value: AnnotationData("Gouraud", "Gouraud Shading "),
UTIL_virtools_types.VXSHADE_MODE.VXSHADE_PHONG.value: AnnotationData("Phong", "Phong Shading (Not yet supported by most implementation) "),
}
g_Annotation_VXCMPFUNC: dict[int, AnnotationData] = {
UTIL_virtools_types.VXCMPFUNC.VXCMP_NEVER.value: AnnotationData("Never", "Always fail the test. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_LESS.value: AnnotationData("Less", "Accept if value if less than current value. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_EQUAL.value: AnnotationData("Equal", "Accept if value if equal than current value. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_LESSEQUAL.value: AnnotationData("Less Equal", "Accept if value if less or equal than current value. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_GREATER.value: AnnotationData("Greater", "Accept if value if greater than current value. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_NOTEQUAL.value: AnnotationData("Not Equal", "Accept if value if different than current value. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_GREATEREQUAL.value: AnnotationData("Greater Equal", "Accept if value if greater or equal current value. "),
UTIL_virtools_types.VXCMPFUNC.VXCMP_ALWAYS.value: AnnotationData("Always", "Always accept the test. "),
}
#endregion
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
class RawVirtoolsMaterial():
# Instance Member Declarations
mDiffuse: UTIL_virtools_types.VxColor
mAmbient: UTIL_virtools_types.VxColor
mSpecular: UTIL_virtools_types.VxColor
mEmissive: UTIL_virtools_types.VxColor
mSpecularPower: float
2023-10-12 22:15:21 +08:00
mTexture: bpy.types.Image | None
2023-10-11 22:24:22 +08:00
mTextureBorderColor: UTIL_virtools_types.VxColor
mTextureBlendMode: UTIL_virtools_types.VXTEXTURE_BLENDMODE
mTextureMinMode: UTIL_virtools_types.VXTEXTURE_FILTERMODE
mTextureMagMode: UTIL_virtools_types.VXTEXTURE_FILTERMODE
mTextureAddressMode: UTIL_virtools_types.VXTEXTURE_ADDRESSMODE
mSourceBlend: UTIL_virtools_types.VXBLEND_MODE
mDestBlend: UTIL_virtools_types.VXBLEND_MODE
mFillMode: UTIL_virtools_types.VXFILL_MODE
mShadeMode: UTIL_virtools_types.VXSHADE_MODE
mEnableAlphaTest: bool
mEnableAlphaBlend: bool
mEnablePerspectiveCorrection: bool
mEnableZWrite: bool
mEnableTwoSided: bool
mAlphaRef: int
mAlphaFunc: UTIL_virtools_types.VXCMPFUNC
mZFunc: UTIL_virtools_types.VXCMPFUNC
# Default Value Declarations
cDefaultDiffuse: typing.ClassVar[UTIL_virtools_types.VxColor] = UTIL_virtools_types.VxColor(0.7, 0.7, 0.7, 1.0)
cDefaultAmbient: typing.ClassVar[UTIL_virtools_types.VxColor] = UTIL_virtools_types.VxColor(0.3, 0.3, 0.3, 1.0)
cDefaultSpecular: typing.ClassVar[UTIL_virtools_types.VxColor] = UTIL_virtools_types.VxColor(0.5, 0.5, 0.5, 1.0)
cDefaultEmissive: typing.ClassVar[UTIL_virtools_types.VxColor] = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0, 1.0)
cDefaultSpecularPower: typing.ClassVar[float] = 0.0
2023-10-12 22:15:21 +08:00
cDefaultTexture: typing.ClassVar[bpy.types.Image | None] = None
2023-10-11 22:24:22 +08:00
cDefaultTextureBorderColor: typing.ClassVar[UTIL_virtools_types.VxColor] = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0, 0.0)
cDefaultTextureBlendMode: typing.ClassVar[UTIL_virtools_types.VXTEXTURE_BLENDMODE]= UTIL_virtools_types.VXTEXTURE_BLENDMODE.VXTEXTUREBLEND_MODULATEALPHA
cDefaultTextureMinMode: typing.ClassVar[UTIL_virtools_types.VXTEXTURE_FILTERMODE] = UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_LINEAR
cDefaultTextureMagMode: typing.ClassVar[UTIL_virtools_types.VXTEXTURE_FILTERMODE] = UTIL_virtools_types.VXTEXTURE_FILTERMODE.VXTEXTUREFILTER_LINEAR
cDefaultTextureAddressMode: typing.ClassVar[UTIL_virtools_types.VXTEXTURE_ADDRESSMODE] = UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSWRAP
cDefaultSourceBlend: typing.ClassVar[UTIL_virtools_types.VXBLEND_MODE] = UTIL_virtools_types.VXBLEND_MODE.VXBLEND_ONE
cDefaultDestBlend: typing.ClassVar[UTIL_virtools_types.VXBLEND_MODE] = UTIL_virtools_types.VXBLEND_MODE.VXBLEND_ZERO
cDefaultFillMode: typing.ClassVar[UTIL_virtools_types.VXFILL_MODE] = UTIL_virtools_types.VXFILL_MODE.VXFILL_SOLID
cDefaultShadeMode: typing.ClassVar[UTIL_virtools_types.VXSHADE_MODE] = UTIL_virtools_types.VXSHADE_MODE.VXSHADE_GOURAUD
cDefaultEnableAlphaTest: typing.ClassVar[bool] = False
cDefaultEnableAlphaBlend: typing.ClassVar[bool] = False
cDefaultEnablePerspectiveCorrection: typing.ClassVar[bool] = True
cDefaultEnableZWrite: typing.ClassVar[bool] = True
cDefaultEnableTwoSided: typing.ClassVar[bool] = False
cDefaultAlphaRef: typing.ClassVar[int] = 0
cDefaultAlphaFunc: typing.ClassVar[UTIL_virtools_types.VXCMPFUNC] = UTIL_virtools_types.VXCMPFUNC.VXCMP_ALWAYS
cDefaultZFunc: typing.ClassVar[UTIL_virtools_types.VXCMPFUNC] = UTIL_virtools_types.VXCMPFUNC.VXCMP_LESSEQUAL
2023-10-12 22:15:21 +08:00
def __init__(self, **kwargs):
2023-10-11 22:24:22 +08:00
# assign default value for each component
2023-10-12 22:15:21 +08:00
self.mDiffuse = kwargs.get('mDiffuse', RawVirtoolsMaterial.cDefaultDiffuse).clone()
self.mAmbient = kwargs.get('mAmbient', RawVirtoolsMaterial.cDefaultAmbient).clone()
self.mSpecular = kwargs.get('mSpecular', RawVirtoolsMaterial.cDefaultSpecular).clone()
self.mSpecularPower = kwargs.get('mSpecularPower', RawVirtoolsMaterial.cDefaultSpecularPower)
self.mEmissive = kwargs.get('mEmissive', RawVirtoolsMaterial.cDefaultEmissive).clone()
self.mEnableTwoSided = kwargs.get('mEnableTwoSided', RawVirtoolsMaterial.cDefaultEnableTwoSided)
self.mTexture = kwargs.get('mTexture', RawVirtoolsMaterial.cDefaultTexture)
self.mTextureMinMode = kwargs.get('mTextureMinMode', RawVirtoolsMaterial.cDefaultTextureMinMode)
self.mTextureMagMode = kwargs.get('mTextureMagMode', RawVirtoolsMaterial.cDefaultTextureMagMode)
self.mSourceBlend = kwargs.get('mSourceBlend', RawVirtoolsMaterial.cDefaultSourceBlend)
self.mDestBlend = kwargs.get('mDestBlend', RawVirtoolsMaterial.cDefaultDestBlend)
self.mEnableAlphaBlend = kwargs.get('mEnableAlphaBlend', RawVirtoolsMaterial.cDefaultEnableAlphaBlend)
self.mShadeMode = kwargs.get('mShadeMode', RawVirtoolsMaterial.cDefaultShadeMode)
self.mFillMode = kwargs.get('mFillMode', RawVirtoolsMaterial.cDefaultFillMode)
self.mEnableAlphaTest = kwargs.get('mEnableAlphaTest', RawVirtoolsMaterial.cDefaultEnableAlphaTest)
self.mEnableZWrite = kwargs.get('mEnableZWrite', RawVirtoolsMaterial.cDefaultEnableZWrite)
2023-10-11 22:24:22 +08:00
2023-10-12 22:15:21 +08:00
self.mEnablePerspectiveCorrection = kwargs.get('mEnablePerspectiveCorrection', RawVirtoolsMaterial.cDefaultEnablePerspectiveCorrection)
self.mTextureBlendMode = kwargs.get('mTextureBlendMode', RawVirtoolsMaterial.cDefaultTextureBlendMode)
self.mTextureAddressMode = kwargs.get('mTextureAddressMode', RawVirtoolsMaterial.cDefaultTextureAddressMode)
self.mZFunc = kwargs.get('mZFunc', RawVirtoolsMaterial.cDefaultZFunc)
self.mAlphaFunc = kwargs.get('mAlphaFunc', RawVirtoolsMaterial.cDefaultAlphaFunc)
self.mTextureBorderColor = kwargs.get('mTextureBorderColor', RawVirtoolsMaterial.cDefaultTextureBorderColor).clone()
self.mAlphaRef = kwargs.get('mAlphaRef', RawVirtoolsMaterial.cDefaultAlphaRef)
2023-10-11 22:24:22 +08:00
def regulate(self):
# regulate colors
self.mDiffuse.regulate()
self.mAmbient.regulate()
self.mSpecular.regulate()
self.mEmissive.regulate()
self.mTextureBorderColor.regulate()
# only diffuse and texture border color can have alpha component
self.mAmbient.a = 1.0
self.mSpecular.a = 1.0
self.mEmissive.a = 1.0
# alpha ref limit
self.mAlphaRef = UTIL_functions.clamp_int(self.mAlphaRef, 0, 255)
# specular power
self.mSpecularPower = UTIL_functions.clamp_float(self.mSpecularPower, 0.0, 100.0)
2023-10-11 10:55:45 +08:00
class BBP_PG_virtools_material(bpy.types.PropertyGroup):
ambient: bpy.props.FloatVectorProperty(
name = "Ambient",
2023-10-11 22:24:22 +08:00
description = "Ambient color of the material",
2023-10-11 10:55:45 +08:00
subtype = 'COLOR',
min = 0.0,
max = 1.0,
size = 3,
2023-11-09 17:20:57 +08:00
default = RawVirtoolsMaterial.cDefaultAmbient.to_const_rgb()
2023-10-11 10:55:45 +08:00
)
diffuse: bpy.props.FloatVectorProperty(
name = "Diffuse",
2023-10-11 22:24:22 +08:00
description = "Diffuse color of the material",
2023-10-11 10:55:45 +08:00
subtype = 'COLOR_GAMMA',
min = 0.0,
max = 1.0,
size = 4,
2023-11-09 17:20:57 +08:00
default = RawVirtoolsMaterial.cDefaultDiffuse.to_const_rgba()
2023-10-11 10:55:45 +08:00
)
specular: bpy.props.FloatVectorProperty(
name = "Specular",
2023-10-11 22:24:22 +08:00
description = "Specular color of the material",
2023-10-11 10:55:45 +08:00
subtype = 'COLOR',
min = 0.0,
max = 1.0,
size = 3,
2023-11-09 17:20:57 +08:00
default = RawVirtoolsMaterial.cDefaultSpecular.to_const_rgb()
2023-10-11 10:55:45 +08:00
)
emissive: bpy.props.FloatVectorProperty(
name = "Emissive",
2023-10-11 22:24:22 +08:00
description = "Emissive color of the material",
2023-10-11 10:55:45 +08:00
subtype = 'COLOR',
min = 0.0,
max = 1.0,
size = 3,
2023-11-09 17:20:57 +08:00
default = RawVirtoolsMaterial.cDefaultEmissive.to_const_rgb()
2023-10-11 10:55:45 +08:00
)
specular_power: bpy.props.FloatProperty(
2023-10-11 22:24:22 +08:00
name = "Power",
description = "Specular highlight power",
2023-10-11 10:55:45 +08:00
min = 0.0,
max = 100.0,
2023-10-11 22:24:22 +08:00
default = RawVirtoolsMaterial.cDefaultSpecularPower
2023-10-11 10:55:45 +08:00
)
texture: bpy.props.PointerProperty(
type = bpy.types.Image,
2023-10-11 22:24:22 +08:00
name = "Texture",
description = "Texture of the material"
2023-10-11 10:55:45 +08:00
)
texture_border_color: bpy.props.FloatVectorProperty(
2023-10-11 22:24:22 +08:00
name = "Border Color",
description = "The border color is used when the texture address mode is VXTEXTURE_ADDRESSBORDER.",
subtype = 'COLOR_GAMMA',
2023-10-11 10:55:45 +08:00
min = 0.0,
max = 1.0,
2023-10-11 22:24:22 +08:00
size = 4,
2023-11-09 17:20:57 +08:00
default = RawVirtoolsMaterial.cDefaultTextureBorderColor.to_const_rgba()
2023-10-11 10:55:45 +08:00
)
texture_blend_mode: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Texture Blend",
description = "Texture blend mode",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXTEXTURE_BLENDMODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXTEXTURE_BLENDMODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultTextureBlendMode.value
2023-10-11 10:55:45 +08:00
)
texture_min_mode: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Filter Min",
description = "Texture filter mode when the texture is minified",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXTEXTURE_FILTERMODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXTEXTURE_FILTERMODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultTextureMinMode.value
2023-10-11 10:55:45 +08:00
)
texture_mag_mode: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Filter Mag",
description = "Texture filter mode when the texture is magnified",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXTEXTURE_FILTERMODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXTEXTURE_FILTERMODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultTextureMagMode.value
2023-10-11 10:55:45 +08:00
)
texture_address_mode: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Address Mode",
description = "The address mode controls how the texture coordinates outside the range 0..1",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXTEXTURE_ADDRESSMODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXTEXTURE_ADDRESSMODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultTextureAddressMode.value
2023-10-11 10:55:45 +08:00
)
source_blend: bpy.props.EnumProperty(
name = "Source Blend",
2023-10-11 22:24:22 +08:00
description = "Source blend factor",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXBLEND_MODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXBLEND_MODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultSourceBlend.value
2023-10-11 10:55:45 +08:00
)
dest_blend: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Destination Blend",
description = "Destination blend factor",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXBLEND_MODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXBLEND_MODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultDestBlend.value
2023-10-11 10:55:45 +08:00
)
fill_mode: bpy.props.EnumProperty(
name = "Fill Mode",
2023-10-11 22:24:22 +08:00
description = "Fill mode",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXFILL_MODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXFILL_MODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultFillMode.value
2023-10-11 10:55:45 +08:00
)
shade_mode: bpy.props.EnumProperty(
name = "Shade Mode",
2023-10-11 22:24:22 +08:00
description = "Shade mode",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXSHADE_MODE,
2023-10-12 22:15:21 +08:00
g_Annotation_VXSHADE_MODE
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultShadeMode.value
2023-10-11 10:55:45 +08:00
)
enable_alpha_test: bpy.props.BoolProperty(
2023-10-11 22:24:22 +08:00
name = "Alpha Test",
description = "Whether the alpha test is enabled",
default = RawVirtoolsMaterial.cDefaultEnableAlphaTest
2023-10-11 10:55:45 +08:00
)
enable_alpha_blend: bpy.props.BoolProperty(
2023-10-11 22:24:22 +08:00
name = "Blend",
description = "Whether alpha blending is enabled or not.",
default = RawVirtoolsMaterial.cDefaultEnableAlphaBlend
2023-10-11 10:55:45 +08:00
)
enable_perspective_correction: bpy.props.BoolProperty(
2023-10-11 22:24:22 +08:00
name = "Perspective Correction",
description = "Whether texture perspective correction is enabled",
default = RawVirtoolsMaterial.cDefaultEnablePerspectiveCorrection
2023-10-11 10:55:45 +08:00
)
2023-10-11 22:24:22 +08:00
enable_z_write: bpy.props.BoolProperty(
name = "Z-Buffer Write",
description = "Whether writing in ZBuffer is enabled.",
default = RawVirtoolsMaterial.cDefaultEnableZWrite
2023-10-11 10:55:45 +08:00
)
enable_two_sided: bpy.props.BoolProperty(
2023-10-11 22:24:22 +08:00
name = "Both Sided",
description = "Whether the material is both sided or not",
default = RawVirtoolsMaterial.cDefaultEnableTwoSided
2023-10-11 10:55:45 +08:00
)
alpha_ref: bpy.props.IntProperty(
2023-10-11 22:24:22 +08:00
name = "Alpha Ref Value",
description = "Alpha referential value",
2023-10-11 10:55:45 +08:00
min = 0,
max = 255,
2023-10-11 22:24:22 +08:00
default = RawVirtoolsMaterial.cDefaultAlphaRef
2023-10-11 10:55:45 +08:00
)
2023-10-11 22:24:22 +08:00
2023-10-11 10:55:45 +08:00
alpha_func: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Alpha Test Function",
description = "Alpha comparision function",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXCMPFUNC,
2023-10-12 22:15:21 +08:00
g_Annotation_VXCMPFUNC
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultAlphaFunc.value
2023-10-11 10:55:45 +08:00
)
2023-10-11 22:24:22 +08:00
2023-10-11 10:55:45 +08:00
z_func: bpy.props.EnumProperty(
2023-10-11 22:24:22 +08:00
name = "Z Compare Function",
description = "Z Comparison function",
2023-11-11 13:32:58 +08:00
items = generate_vt_enums_for_bl_enumprop(
2023-10-11 10:55:45 +08:00
UTIL_virtools_types.VXCMPFUNC,
2023-10-12 22:15:21 +08:00
g_Annotation_VXCMPFUNC
2023-10-11 22:24:22 +08:00
),
default = RawVirtoolsMaterial.cDefaultZFunc.value
2023-10-11 10:55:45 +08:00
)
2023-10-12 22:15:21 +08:00
#region Getter Setter
2023-10-11 22:24:22 +08:00
def get_virtools_material(mtl: bpy.types.Material) -> BBP_PG_virtools_material:
return mtl.virtools_material
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
def get_raw_virtools_material(mtl: bpy.types.Material) -> RawVirtoolsMaterial:
props: BBP_PG_virtools_material = get_virtools_material(mtl)
rawdata: RawVirtoolsMaterial = RawVirtoolsMaterial()
2023-10-11 10:55:45 +08:00
2023-11-10 12:26:04 +08:00
rawdata.mDiffuse.from_const_rgba(props.diffuse)
rawdata.mAmbient.from_const_rgb(props.ambient)
rawdata.mSpecular.from_const_rgb(props.specular)
rawdata.mEmissive.from_const_rgb(props.emissive)
2023-10-11 22:24:22 +08:00
rawdata.mSpecularPower = props.specular_power
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
rawdata.mTexture = props.texture
2023-11-10 12:26:04 +08:00
rawdata.mTextureBorderColor.from_const_rgba(props.texture_border_color)
2023-10-11 10:55:45 +08:00
2023-10-12 22:15:21 +08:00
rawdata.mTextureBlendMode = UTIL_virtools_types.VXTEXTURE_BLENDMODE(int(props.texture_blend_mode))
rawdata.mTextureMinMode = UTIL_virtools_types.VXTEXTURE_FILTERMODE(int(props.texture_min_mode))
rawdata.mTextureMagMode = UTIL_virtools_types.VXTEXTURE_FILTERMODE(int(props.texture_mag_mode))
rawdata.mTextureAddressMode = UTIL_virtools_types.VXTEXTURE_ADDRESSMODE(int(props.texture_address_mode))
2023-10-11 10:55:45 +08:00
2023-10-12 22:15:21 +08:00
rawdata.mSourceBlend = UTIL_virtools_types.VXBLEND_MODE(int(props.source_blend))
rawdata.mDestBlend = UTIL_virtools_types.VXBLEND_MODE(int(props.dest_blend))
rawdata.mFillMode = UTIL_virtools_types.VXFILL_MODE(int(props.fill_mode))
rawdata.mShadeMode = UTIL_virtools_types.VXSHADE_MODE(int(props.shade_mode))
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
rawdata.mEnableAlphaTest = props.enable_alpha_test
rawdata.mEnableAlphaBlend = props.enable_alpha_blend
rawdata.mEnablePerspectiveCorrection = props.enable_perspective_correction
rawdata.mEnableZWrite = props.enable_z_write
rawdata.mEnableTwoSided = props.enable_two_sided
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
rawdata.mAlphaRef = props.alpha_ref
2023-10-12 22:15:21 +08:00
rawdata.mAlphaFunc = UTIL_virtools_types.VXCMPFUNC(int(props.alpha_func))
rawdata.mZFunc = UTIL_virtools_types.VXCMPFUNC(int(props.z_func))
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
rawdata.regulate()
return rawdata
def set_raw_virtools_material(mtl: bpy.types.Material, rawdata: RawVirtoolsMaterial) -> None:
props: BBP_PG_virtools_material = get_virtools_material(mtl)
2023-11-09 17:20:57 +08:00
props.diffuse = rawdata.mDiffuse.to_const_rgba()
props.ambient = rawdata.mAmbient.to_const_rgb()
props.specular = rawdata.mSpecular.to_const_rgb()
props.emissive = rawdata.mEmissive.to_const_rgb()
2023-10-11 22:24:22 +08:00
props.specular_power = rawdata.mSpecularPower
props.texture = rawdata.mTexture
2023-11-09 17:20:57 +08:00
props.texture_border_color = rawdata.mTextureBorderColor.to_const_rgba()
2023-10-11 22:24:22 +08:00
2023-10-12 22:15:21 +08:00
props.texture_blend_mode = str(rawdata.mTextureBlendMode.value)
props.texture_min_mode = str(rawdata.mTextureMinMode.value)
props.texture_mag_mode = str(rawdata.mTextureMagMode.value)
props.texture_address_mode = str(rawdata.mTextureAddressMode.value)
2023-10-11 22:24:22 +08:00
2023-10-12 22:15:21 +08:00
props.source_blend = str(rawdata.mSourceBlend.value)
props.dest_blend = str(rawdata.mDestBlend.value)
props.fill_mode = str(rawdata.mFillMode.value)
props.shade_mode = str(rawdata.mShadeMode.value)
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
props.enable_alpha_test = rawdata.mEnableAlphaTest
props.enable_alpha_blend = rawdata.mEnableAlphaBlend
props.enable_perspective_correction = rawdata.mEnablePerspectiveCorrection
props.enable_z_write = rawdata.mEnableZWrite
props.enable_two_sided = rawdata.mEnableTwoSided
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
props.alpha_ref = rawdata.mAlphaRef
2023-10-12 22:15:21 +08:00
props.alpha_func = str(rawdata.mAlphaFunc.value)
props.z_func = str(rawdata.mZFunc.value)
def apply_to_blender_material(mtl: bpy.types.Material):
# get raw material data
rawdata: RawVirtoolsMaterial = get_raw_virtools_material(mtl)
# enable nodes mode
mtl.use_nodes = True
# delete all existed nodes
for node in mtl.node_tree.nodes:
mtl.node_tree.nodes.remove(node)
# create ballance-style blender material
# for sockets name, see `bpy_extras.node_shader_utils` for more infos
2023-10-12 22:15:21 +08:00
bnode: bpy.types.ShaderNodeBsdfPrincipled = mtl.node_tree.nodes.new(type = "ShaderNodeBsdfPrincipled")
mnode: bpy.types.ShaderNodeOutputMaterial = mtl.node_tree.nodes.new(type = "ShaderNodeOutputMaterial")
mtl.node_tree.links.new(bnode.outputs["BSDF"], mnode.inputs["Surface"])
2023-10-12 22:15:21 +08:00
# set basic colors
metallic_value = sum(rawdata.mAmbient.to_const_rgb()) / 3
mtl.metallic = metallic_value
bnode.inputs["Metallic"].default_value = metallic_value
diffuse_value = rawdata.mDiffuse.to_const_rgba()
mtl.diffuse_color = diffuse_value
bnode.inputs["Base Color"].default_value = diffuse_value
2023-11-09 17:20:57 +08:00
mtl.specular_color = rawdata.mSpecular.to_const_rgb()
2023-11-14 21:37:29 +08:00
# too shiny, disabled.
# bnode.inputs["Emission"].default_value = rawdata.mEmissive.to_const_rgba()
2023-10-12 22:15:21 +08:00
mtl.specular_intensity = rawdata.mSpecularPower
bnode.inputs["Specular"].default_value = UTIL_functions.clamp_float(
rawdata.mSpecularPower, 0.0, 1.0
)
2023-10-12 22:15:21 +08:00
# set some alpha data
mtl.use_backface_culling = not rawdata.mEnableTwoSided
mtl.blend_method = 'BLEND' if rawdata.mEnableAlphaBlend else 'OPAQUE'
# set texture
if rawdata.mTexture is not None:
# basic texture setter
inode: bpy.types.ShaderNodeTexImage = mtl.node_tree.nodes.new(type = "ShaderNodeTexImage")
inode.image = rawdata.mTexture
mtl.node_tree.links.new(inode.outputs["Color"], bnode.inputs["Base Color"])
2023-10-12 22:15:21 +08:00
# todo: sync texture mapping config here
# link alpha if necessary
if rawdata.mEnableAlphaBlend:
mtl.node_tree.links.new(inode.outputs["Alpha"], bnode.inputs["Alpha"])
2023-10-12 22:15:21 +08:00
#endregion
#region Preset Paramters
class MaterialPresetType(enum.IntEnum):
FloorSide = enum.auto()
FloorTop = enum.auto()
TrafoPaper = enum.auto()
TraforWoodStone = enum.auto()
Rail = enum.auto()
WoodPath = enum.auto()
WoodChip = enum.auto()
class MaterialPresetData():
mDisplayName: str
mData: RawVirtoolsMaterial
def __init__(self, display_name: str, data: RawVirtoolsMaterial):
self.mDisplayName = display_name
self.mData = data
g_MaterialPresets: dict[int, MaterialPresetData] = {
MaterialPresetType.FloorSide.value: MaterialPresetData(
"Floor Side",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0),
mDiffuse = UTIL_virtools_types.VxColor(122 / 255.0, 122 / 255.0, 122 / 255.0),
mSpecular = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0),
mEmissive = UTIL_virtools_types.VxColor(104 / 255.0, 104 / 255.0, 104 / 255.0),
mSpecularPower = 0.0
)
),
MaterialPresetType.FloorTop.value: MaterialPresetData(
"Floor Top",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0),
mDiffuse = UTIL_virtools_types.VxColor(1.0, 1.0, 1.0),
mSpecular = UTIL_virtools_types.VxColor(80 / 255.0, 80 / 255.0, 80 / 255.0),
mEmissive = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0),
mSpecularPower = 100.0
)
),
MaterialPresetType.TrafoPaper.value: MaterialPresetData(
"Transform Paper",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(25 / 255.0, 25 / 255.0, 25 / 255.0),
mDiffuse = UTIL_virtools_types.VxColor(1.0, 1.0, 1.0),
mSpecular = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0),
mEmissive = UTIL_virtools_types.VxColor(100 / 255.0, 100 / 255.0, 100 / 255.0),
mSpecularPower = 0.0
)
),
MaterialPresetType.TraforWoodStone.value: MaterialPresetData(
"Transform Stone & Wood",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(25 / 255.0, 25 / 255.0, 25 / 255.0),
mDiffuse = UTIL_virtools_types.VxColor(1.0, 1.0, 1.0),
mSpecular = UTIL_virtools_types.VxColor(229 / 255.0, 229 / 255.0, 229 / 255.0),
mEmissive = UTIL_virtools_types.VxColor(60 / 255.0, 60 / 255.0, 60 / 255.0),
mSpecularPower = 0.0
)
),
MaterialPresetType.Rail.value: MaterialPresetData(
"Rail",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(0.0, 0.0, 0.0),
mDiffuse = UTIL_virtools_types.VxColor(100 / 255.0, 118 / 255.0, 133 / 255.0),
mSpecular = UTIL_virtools_types.VxColor(210 / 255.0, 210 / 255.0, 210 / 255.0),
mEmissive = UTIL_virtools_types.VxColor(124 / 255.0, 134 / 255.0, 150 / 255.0),
mSpecularPower = 10.0
)
),
MaterialPresetType.WoodPath.value: MaterialPresetData(
"Wood Path",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(2 / 255.0, 2 / 255.0, 2 / 255.0),
mDiffuse = UTIL_virtools_types.VxColor(1.0, 1.0, 1.0),
mSpecular = UTIL_virtools_types.VxColor(59 / 255.0, 59 / 255.0, 59 / 255.0),
mEmissive = UTIL_virtools_types.VxColor(30 / 255.0, 30 / 255.0, 30 / 255.0),
mSpecularPower = 25.0
)
),
MaterialPresetType.WoodChip.value: MaterialPresetData(
"Wood Chip",
RawVirtoolsMaterial(
mAmbient = UTIL_virtools_types.VxColor(25 / 255.0, 25 / 255.0, 25 / 255.0),
mDiffuse = UTIL_virtools_types.VxColor(1.0, 1.0, 1.0),
mSpecular = UTIL_virtools_types.VxColor(100 / 255.0, 100 / 255.0, 100 / 255.0),
mEmissive = UTIL_virtools_types.VxColor(50 / 255.0, 50 / 255.0, 50 / 255.0),
mSpecularPower = 50.0
)
),
}
2023-10-15 21:13:56 +08:00
def preset_virtools_material(mtl: bpy.types.Material, preset_type: MaterialPresetType) -> None:
preset_data: MaterialPresetData = g_MaterialPresets[preset_type.value]
set_raw_virtools_material(mtl, preset_data.mData)
2023-10-27 11:51:12 +08:00
def _generate_mtl_presets_for_bl_enumprop() -> tuple[BlenderEnumPropEntry_t, ...]:
2023-10-12 22:15:21 +08:00
# define 2 assist functions
def get_display_name(v: int):
entry: MaterialPresetData | None = g_MaterialPresets.get(v, None)
if entry: return entry.mDisplayName
else: return ""
# token, display name, descriptions, icon, index
return tuple(
(str(member.value), get_display_name(member.value), "", "", member.value) for member in MaterialPresetType
)
#endregion
#region Operators
class BBP_OT_apply_virtools_material(bpy.types.Operator):
"""Apply Virtools Material to Blender Material."""
bl_idname = "bbp.apply_virtools_material"
bl_label = "Apply to Blender Material"
bl_options = {'UNDO'}
@classmethod
def poll(cls, context):
return context.material is not None
def execute(self, context):
mtl: bpy.types.Material = context.material
apply_to_blender_material(mtl)
return {'FINISHED'}
class BBP_OT_preset_virtools_material(bpy.types.Operator):
"""Preset Virtools Material with Original Ballance Data."""
bl_idname = "bbp.preset_virtools_material"
bl_label = "Preset Virtools Material"
bl_options = {'UNDO'}
preset_type: bpy.props.EnumProperty(
name = "Preset",
description = "The preset which you want to apply.",
2023-10-27 11:51:12 +08:00
items = _generate_mtl_presets_for_bl_enumprop(),
2023-10-12 22:15:21 +08:00
)
@classmethod
def poll(cls, context):
return context.material is not None
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
self.layout.prop(self, "preset_type")
def execute(self, context):
2023-10-15 21:13:56 +08:00
# get essential value
mtl: bpy.types.Material = context.material
2023-10-12 22:15:21 +08:00
expected_preset: MaterialPresetType = MaterialPresetType(int(self.preset_type))
# apply preset to material
2023-10-15 21:13:56 +08:00
preset_virtools_material(mtl, expected_preset)
2023-10-12 22:15:21 +08:00
return {'FINISHED'}
#endregion
2023-10-11 22:24:22 +08:00
class BBP_PT_virtools_material(bpy.types.Panel):
"""Show Virtools Material Properties."""
bl_label = "Virtools Material"
bl_idname = "BBP_PT_virtools_material"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
@classmethod
def poll(cls, context):
return context.material is not None
2023-10-11 10:55:45 +08:00
2023-10-11 22:24:22 +08:00
def draw(self, context):
# get layout and target
layout = self.layout
props: BBP_PG_virtools_material = get_virtools_material(context.material)
2023-10-12 22:15:21 +08:00
# draw operator
layout.operator(BBP_OT_preset_virtools_material.bl_idname, icon="PRESET")
layout.operator(BBP_OT_apply_virtools_material.bl_idname, icon="NODETREE")
# draw data
layout.label(text="Color Parameters")
2023-10-11 22:24:22 +08:00
layout.prop(props, 'ambient')
layout.prop(props, 'diffuse')
layout.prop(props, 'specular')
layout.prop(props, 'emissive')
layout.prop(props, 'specular_power')
layout.separator()
layout.label(text="Mode Parameters")
layout.prop(props, 'enable_two_sided')
layout.prop(props, 'fill_mode')
layout.prop(props, 'shade_mode')
layout.separator()
layout.label(text="Texture Parameters")
layout.prop(props, 'texture', emboss = True)
2023-11-11 13:32:58 +08:00
if props.texture is not None:
# have texture, show texture settings and enclosed by a border.
boxlayout = layout.box()
boxlayout.label(text="Virtools Texture Settings")
PROP_virtools_texture.draw_virtools_texture(props.texture, boxlayout)
2023-11-11 13:32:58 +08:00
2023-10-11 22:24:22 +08:00
layout.prop(props, 'texture_blend_mode')
layout.prop(props, 'texture_min_mode')
layout.prop(props, 'texture_mag_mode')
layout.prop(props, 'texture_address_mode')
layout.prop(props, 'enable_perspective_correction')
if (int(props.texture_address_mode) == UTIL_virtools_types.VXTEXTURE_ADDRESSMODE.VXTEXTURE_ADDRESSBORDER.value):
layout.prop(props, 'texture_border_color')
layout.separator()
layout.label(text="Alpha Test Parameters")
layout.prop(props, 'enable_alpha_test')
if props.enable_alpha_test:
layout.prop(props, 'alpha_func')
layout.prop(props, 'alpha_ref')
layout.separator()
layout.label(text="Alpha Blend Parameters")
layout.prop(props, 'enable_alpha_blend')
if props.enable_alpha_blend:
layout.prop(props, 'source_blend')
layout.prop(props, 'dest_blend')
2023-10-12 22:15:21 +08:00
2023-10-11 22:24:22 +08:00
layout.separator()
layout.label(text="Z Write Parameters")
layout.prop(props, 'enable_z_write')
if props.enable_z_write:
layout.prop(props, 'z_func')
2023-10-12 22:15:21 +08:00
def register():
2023-10-27 11:51:12 +08:00
bpy.utils.register_class(BBP_PG_virtools_material)
bpy.utils.register_class(BBP_OT_apply_virtools_material)
bpy.utils.register_class(BBP_OT_preset_virtools_material)
bpy.utils.register_class(BBP_PT_virtools_material)
# add into material metadata
2023-10-11 22:24:22 +08:00
bpy.types.Material.virtools_material = bpy.props.PointerProperty(type = BBP_PG_virtools_material)
def unregister():
# del from material metadata
2023-10-11 22:24:22 +08:00
del bpy.types.Material.virtools_material
2023-10-27 11:51:12 +08:00
bpy.utils.unregister_class(BBP_PT_virtools_material)
bpy.utils.unregister_class(BBP_OT_preset_virtools_material)
bpy.utils.unregister_class(BBP_OT_apply_virtools_material)
bpy.utils.unregister_class(BBP_PG_virtools_material)