add support of virtools mesh lit mode
This commit is contained in:
parent
d128ffcde5
commit
59a1275f68
@ -3,7 +3,7 @@ from bpy_extras.wm_utils.progress_report import ProgressReport
|
||||
import tempfile, os, typing
|
||||
from . import PROP_preferences
|
||||
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh
|
||||
from . import PROP_ballance_element, PROP_virtools_group, PROP_virtools_material, PROP_virtools_texture
|
||||
from . import PROP_ballance_element, PROP_virtools_group, PROP_virtools_material, PROP_virtools_texture, PROP_virtools_mesh
|
||||
from .PyBMap import bmap_wrapper as bmap
|
||||
|
||||
class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtoolsFile):
|
||||
@ -76,25 +76,32 @@ def _import_virtools_textures(
|
||||
print(f'Texture Raw Data Temp: {rawdata_temp}')
|
||||
|
||||
for vttexture in reader.get_textures():
|
||||
# if this image is raw data, save it in external folder before loading
|
||||
# the attribute of raw data saving is the file path is not absolute path
|
||||
texpath_to_load: str = vttexture.get_file_name()
|
||||
if not os.path.isabs(texpath_to_load):
|
||||
texpath_to_load = os.path.join(
|
||||
rawdata_temp,
|
||||
os.path.basename(texpath_to_load)
|
||||
)
|
||||
vttexture.save_image(texpath_to_load)
|
||||
|
||||
# detect whether it is ballance texture and load
|
||||
try_blc_tex: str | None = PROP_virtools_texture.get_ballance_texture_filename(texpath_to_load)
|
||||
tex: bpy.types.Image
|
||||
if try_blc_tex:
|
||||
# load as ballance texture
|
||||
tex = PROP_virtools_texture.load_ballance_texture(try_blc_tex)
|
||||
texpath_to_load: str | None = vttexture.get_file_name()
|
||||
|
||||
# if no assoc file path (what? but it is real happended)
|
||||
# this is invalid image, create a blank image instead
|
||||
if texpath_to_load is None:
|
||||
tex = bpy.data.images.new("", 1, 1)
|
||||
else:
|
||||
# load as other textures
|
||||
tex = PROP_virtools_texture.load_other_texture(texpath_to_load)
|
||||
# if this image is raw data, save it in external folder before loading
|
||||
# the attribute of raw data saving is the file path is not absolute path
|
||||
if not os.path.isabs(texpath_to_load):
|
||||
texpath_to_load = os.path.join(
|
||||
rawdata_temp,
|
||||
os.path.basename(texpath_to_load)
|
||||
)
|
||||
vttexture.save_image(texpath_to_load)
|
||||
|
||||
# detect whether it is ballance texture and load
|
||||
try_blc_tex: str | None = PROP_virtools_texture.get_ballance_texture_filename(texpath_to_load)
|
||||
|
||||
if try_blc_tex:
|
||||
# load as ballance texture
|
||||
tex = PROP_virtools_texture.load_ballance_texture(try_blc_tex)
|
||||
else:
|
||||
# load as other textures
|
||||
tex = PROP_virtools_texture.load_other_texture(texpath_to_load)
|
||||
|
||||
# rename and insert it to map
|
||||
tex.name = UTIL_functions.virtools_name_regulator(vttexture.get_name())
|
||||
@ -248,6 +255,11 @@ def _import_virtools_meshes(
|
||||
|
||||
# end of mesh writer
|
||||
|
||||
# set other mesh settings
|
||||
mesh_settings: PROP_virtools_mesh.RawVirtoolsMesh = PROP_virtools_mesh.RawVirtoolsMesh()
|
||||
mesh_settings.mLitMode = vtmesh.get_lit_mode()
|
||||
PROP_virtools_mesh.set_raw_virtools_mesh(mesh, mesh_settings)
|
||||
|
||||
# add into map and step
|
||||
mesh_cret_map[vtmesh] = mesh
|
||||
progress.step()
|
||||
|
@ -1,5 +1,6 @@
|
||||
import bpy
|
||||
import os, typing, enum, array
|
||||
from . import PROP_virtools_mesh
|
||||
from . import UTIL_functions, UTIL_file_io, UTIL_blender_mesh, UTIL_virtools_types
|
||||
|
||||
#region Raw Elements Operations
|
||||
@ -136,6 +137,8 @@ def _load_element(mesh: bpy.types.Mesh, element_id: int) -> None:
|
||||
v.x = vpos[idx]
|
||||
v.y = vpos[idx + 1]
|
||||
v.z = vpos[idx + 2]
|
||||
# conv co
|
||||
UTIL_virtools_types.vxvector3_conv_co(v)
|
||||
yield v
|
||||
mesh_part.mVertexPosition = vpos_iterator()
|
||||
def vnml_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
@ -145,9 +148,12 @@ def _load_element(mesh: bpy.types.Mesh, element_id: int) -> None:
|
||||
v.x = vnml[idx]
|
||||
v.y = vnml[idx + 1]
|
||||
v.z = vnml[idx + 2]
|
||||
# conv co
|
||||
UTIL_virtools_types.vxvector3_conv_co(v)
|
||||
yield v
|
||||
mesh_part.mVertexNormal = vnml_iterator()
|
||||
def vuv_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector2]:
|
||||
# no uv, no need to conv co
|
||||
v: UTIL_virtools_types.VxVector2 = UTIL_virtools_types.VxVector2()
|
||||
yield v
|
||||
mesh_part.mVertexUV = vuv_iterator()
|
||||
@ -165,6 +171,8 @@ def _load_element(mesh: bpy.types.Mesh, element_id: int) -> None:
|
||||
f.mIndices[1].mNmlIdx = face[idx + 3]
|
||||
f.mIndices[2].mPosIdx = face[idx + 4]
|
||||
f.mIndices[2].mNmlIdx = face[idx + 5]
|
||||
# conv co
|
||||
f.conv_co()
|
||||
yield f
|
||||
mesh_part.mFace = face_iterator()
|
||||
|
||||
@ -173,6 +181,12 @@ def _load_element(mesh: bpy.types.Mesh, element_id: int) -> None:
|
||||
# end of with writer
|
||||
# write mesh data
|
||||
|
||||
# set other mesh settings
|
||||
# generated mesh always use lit mode.
|
||||
mesh_settings: PROP_virtools_mesh.RawVirtoolsMesh = PROP_virtools_mesh.RawVirtoolsMesh()
|
||||
mesh_settings.mLitMode = UTIL_virtools_types.VXMESH_LITMODE.VX_LITMESH
|
||||
PROP_virtools_mesh.set_raw_virtools_mesh(mesh, mesh_settings)
|
||||
|
||||
# end of with fmesh
|
||||
# close file
|
||||
|
||||
|
94
bbp_ng/PROP_virtools_mesh.py
Normal file
94
bbp_ng/PROP_virtools_mesh.py
Normal file
@ -0,0 +1,94 @@
|
||||
import bpy
|
||||
import typing, enum
|
||||
from . import UTIL_functions, UTIL_virtools_types
|
||||
|
||||
# Annotation
|
||||
|
||||
from .UTIL_functions import AnnotationData, BlenderEnumPropEntry_t
|
||||
|
||||
g_Annotation_VXMESH_LITMODE: dict[int, AnnotationData] = {
|
||||
UTIL_virtools_types.VXMESH_LITMODE.VX_PRELITMESH.value: AnnotationData("Prelit", "Lighting use color information store with vertices "),
|
||||
UTIL_virtools_types.VXMESH_LITMODE.VX_LITMESH.value: AnnotationData("Lit", "Lighting is done by renderer using normals and face material information. "),
|
||||
}
|
||||
|
||||
# Raw Data
|
||||
|
||||
class RawVirtoolsMesh():
|
||||
# Instance Member Declarations
|
||||
mLitMode: UTIL_virtools_types.VXMESH_LITMODE
|
||||
# Default Value Declarations
|
||||
cDefaultLitMode: typing.ClassVar[UTIL_virtools_types.VXMESH_LITMODE] = UTIL_virtools_types.VXMESH_LITMODE.VX_LITMESH
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
# assign default value for each component
|
||||
self.mLitMode = kwargs.get('mLitMode', RawVirtoolsMesh.cDefaultLitMode)
|
||||
|
||||
# Blender Property Group
|
||||
|
||||
class BBP_PG_virtools_mesh(bpy.types.PropertyGroup):
|
||||
lit_mode: bpy.props.EnumProperty(
|
||||
name = "Lit Mode",
|
||||
description = "Lighting mode of the mesh.",
|
||||
items = UTIL_functions.generate_vt_enums_for_bl_enumprop(
|
||||
UTIL_virtools_types.VXMESH_LITMODE,
|
||||
g_Annotation_VXMESH_LITMODE
|
||||
),
|
||||
default = RawVirtoolsMesh.cDefaultLitMode.value
|
||||
)
|
||||
|
||||
# Getter Setter
|
||||
|
||||
def get_virtools_mesh(mesh: bpy.types.Mesh) -> BBP_PG_virtools_mesh:
|
||||
return mesh.virtools_mesh
|
||||
|
||||
def get_raw_virtools_mesh(mesh: bpy.types.Mesh) -> RawVirtoolsMesh:
|
||||
props: BBP_PG_virtools_mesh = get_virtools_mesh(mesh)
|
||||
rawdata: RawVirtoolsMesh = RawVirtoolsMesh()
|
||||
|
||||
rawdata.mLitMode = UTIL_virtools_types.VXMESH_LITMODE(int(props.lit_mode))
|
||||
|
||||
return rawdata
|
||||
|
||||
def set_raw_virtools_mesh(mesh: bpy.types.Mesh, rawdata: RawVirtoolsMesh) -> None:
|
||||
props: BBP_PG_virtools_mesh = get_virtools_mesh(mesh)
|
||||
|
||||
props.lit_mode = str(rawdata.mLitMode.value)
|
||||
|
||||
# Display Panel
|
||||
|
||||
class BBP_PT_virtools_mesh(bpy.types.Panel):
|
||||
"""Show Virtools Mesh Properties."""
|
||||
bl_label = "Virtools Mesh"
|
||||
bl_idname = "BBP_PT_virtools_mesh"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "data" # idk why blender use `data` as the mesh tab.
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.mesh is not None
|
||||
|
||||
def draw(self, context):
|
||||
# get layout and target
|
||||
layout = self.layout
|
||||
props: BBP_PG_virtools_mesh = get_virtools_mesh(context.mesh)
|
||||
|
||||
# draw data
|
||||
layout.prop(props, 'lit_mode')
|
||||
|
||||
# Register
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(BBP_PG_virtools_mesh)
|
||||
bpy.utils.register_class(BBP_PT_virtools_mesh)
|
||||
|
||||
# add into mesh metadata
|
||||
bpy.types.Mesh.virtools_mesh = bpy.props.PointerProperty(type = BBP_PG_virtools_mesh)
|
||||
|
||||
def unregister():
|
||||
# remove from metadata
|
||||
del bpy.types.Mesh.virtools_mesh
|
||||
|
||||
bpy.utils.unregister_class(BBP_PT_virtools_mesh)
|
||||
bpy.utils.unregister_class(BBP_PG_virtools_mesh)
|
||||
|
@ -32,6 +32,8 @@ bm_bool_p = ctypes.POINTER(bm_bool)
|
||||
bm_void_p = ctypes.c_void_p
|
||||
bm_void_pp = ctypes.POINTER(ctypes.c_void_p)
|
||||
|
||||
bm_callback = ctypes.CFUNCTYPE(None, bm_CKSTRING)
|
||||
|
||||
class bm_VxVector2(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('x', bm_CKFLOAT),
|
||||
@ -104,19 +106,21 @@ BMDispose = _create_bmap_func('BMDispose', [])
|
||||
# @param file_name[in] Type: LibCmo::CKSTRING.
|
||||
# @param temp_folder[in] Type: LibCmo::CKSTRING.
|
||||
# @param texture_folder[in] Type: LibCmo::CKSTRING.
|
||||
# @param raw_callback[in] Type: BMap::NakedOutputCallback.
|
||||
# @param encoding_count[in] Type: LibCmo::CKDWORD.
|
||||
# @param encodings[in] Type: LibCmo::CKSTRING*.
|
||||
# @param out_file[out] Type: BMap::BMFile*. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMFile_Load = _create_bmap_func('BMFile_Load', [bm_CKSTRING, bm_CKSTRING, bm_CKSTRING, bm_CKDWORD, bm_CKSTRING_p, bm_void_pp])
|
||||
BMFile_Load = _create_bmap_func('BMFile_Load', [bm_CKSTRING, bm_CKSTRING, bm_CKSTRING, bm_callback, bm_CKDWORD, bm_CKSTRING_p, bm_void_pp])
|
||||
## BMFile_Create
|
||||
# @param temp_folder[in] Type: LibCmo::CKSTRING.
|
||||
# @param texture_folder[in] Type: LibCmo::CKSTRING.
|
||||
# @param raw_callback[in] Type: BMap::NakedOutputCallback.
|
||||
# @param encoding_count[in] Type: LibCmo::CKDWORD.
|
||||
# @param encodings[in] Type: LibCmo::CKSTRING*.
|
||||
# @param out_file[out] Type: BMap::BMFile*. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMFile_Create = _create_bmap_func('BMFile_Create', [bm_CKSTRING, bm_CKSTRING, bm_CKDWORD, bm_CKSTRING_p, bm_void_pp])
|
||||
BMFile_Create = _create_bmap_func('BMFile_Create', [bm_CKSTRING, bm_CKSTRING, bm_callback, bm_CKDWORD, bm_CKSTRING_p, bm_void_pp])
|
||||
## BMFile_Save
|
||||
# @param map_file[in] Type: BMap::BMFile*.
|
||||
# @param file_name[in] Type: LibCmo::CKSTRING.
|
||||
@ -635,6 +639,18 @@ BMMaterial_GetZFunc = _create_bmap_func('BMMaterial_GetZFunc', [bm_void_p, bm_CK
|
||||
# @param val[in] Type: LibCmo::VxMath::VXCMPFUNC.
|
||||
# @return True if no error, otherwise False.
|
||||
BMMaterial_SetZFunc = _create_bmap_func('BMMaterial_SetZFunc', [bm_void_p, bm_CKID, bm_enum])
|
||||
## BMMesh_GetLitMode
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_mode[out] Type: LibCmo::VxMath::VXMESH_LITMODE. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMMesh_GetLitMode = _create_bmap_func('BMMesh_GetLitMode', [bm_void_p, bm_CKID, bm_enum_p])
|
||||
## BMMesh_SetLitMode
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param mode[in] Type: LibCmo::VxMath::VXMESH_LITMODE.
|
||||
# @return True if no error, otherwise False.
|
||||
BMMesh_SetLitMode = _create_bmap_func('BMMesh_SetLitMode', [bm_void_p, bm_CKID, bm_enum])
|
||||
## BMMesh_GetVertexCount
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
|
@ -7,6 +7,17 @@ g_InvalidPtr: bmap.bm_void_p = bmap.bm_void_p(0)
|
||||
g_InvalidCKID: int = 0
|
||||
g_BMapEncoding: str = "utf-8"
|
||||
|
||||
def python_callback(strl: bytes):
|
||||
"""
|
||||
The Python type callback for BMFile.
|
||||
Simply add a prefix when output.
|
||||
Need a convertion before passing to BMFile.
|
||||
"""
|
||||
# the passing value is bytes, not bmap.bm_CKSTRING.
|
||||
# i think Python do a auto convertion here.
|
||||
if strl is not None:
|
||||
print(f'[PyBMap] {strl.decode(g_BMapEncoding)}')
|
||||
|
||||
class _AbstractPointer():
|
||||
__mRawPointer: int
|
||||
|
||||
@ -398,6 +409,16 @@ class BMMaterial(BMObject):
|
||||
bmap.BMMaterial_SetZFunc(self._get_pointer(), self._get_ckid(), data)
|
||||
|
||||
class BMMesh(BMObject):
|
||||
|
||||
def get_lit_mode(self) -> virtools_types.VXMESH_LITMODE:
|
||||
mode: bmap.bm_enum = bmap.bm_enum()
|
||||
bmap.BMMesh_GetLitMode(self._get_pointer(), self._get_ckid(), ctypes.byref(mode))
|
||||
return virtools_types.VXMESH_LITMODE(mode.value)
|
||||
|
||||
def set_lit_mode(self, mode: virtools_types.VXMESH_LITMODE) -> None:
|
||||
mode: bmap.bm_enum = bmap.bm_enum(mode.value)
|
||||
bmap.BMMesh_SetLitMode(self._get_pointer(), self._get_ckid(), mode)
|
||||
|
||||
def get_vertex_count(self) -> int:
|
||||
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
|
||||
bmap.BMMesh_GetVertexCount(self._get_pointer(), self._get_ckid(), ctypes.byref(count))
|
||||
@ -569,6 +590,7 @@ class BMFileReader(_AbstractPointer):
|
||||
file_name: bmap.bm_CKSTRING = bmap.bm_CKSTRING(file_name_.encode(g_BMapEncoding))
|
||||
temp_folder: bmap.bm_CKSTRING = bmap.bm_CKSTRING(temp_folder_.encode(g_BMapEncoding))
|
||||
texture_folder: bmap.bm_CKSTRING = bmap.bm_CKSTRING(texture_folder_.encode(g_BMapEncoding))
|
||||
raw_callback: bmap.bm_callback = bmap.bm_callback(python_callback)
|
||||
encoding_count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(len(encodings_))
|
||||
encodings: ctypes.Array = (bmap.bm_CKSTRING * len(encodings_))(
|
||||
*(strl.encode(g_BMapEncoding) for strl in encodings_)
|
||||
@ -576,7 +598,8 @@ class BMFileReader(_AbstractPointer):
|
||||
out_file: bmap.bm_void_p = bmap.bm_void_p()
|
||||
# exec
|
||||
bmap.BMFile_Load(
|
||||
file_name, temp_folder, texture_folder, encoding_count, encodings,
|
||||
file_name, temp_folder, texture_folder, raw_callback,
|
||||
encoding_count, encodings,
|
||||
ctypes.byref(out_file)
|
||||
)
|
||||
# init self
|
||||
@ -666,6 +689,7 @@ class BMFileWriter(_AbstractPointer):
|
||||
# create param
|
||||
temp_folder: bmap.bm_CKSTRING = bmap.bm_CKSTRING(temp_folder_.encode(g_BMapEncoding))
|
||||
texture_folder: bmap.bm_CKSTRING = bmap.bm_CKSTRING(texture_folder_.encode(g_BMapEncoding))
|
||||
raw_callback: bmap.bm_callback = bmap.bm_callback(python_callback)
|
||||
encoding_count: bmap.bm_CKDWORD = bmap.bm_CKDWORD(len(encodings_))
|
||||
encodings: ctypes.Array = (bmap.bm_CKSTRING * len(encodings_))(
|
||||
*(strl.encode(g_BMapEncoding) for strl in encodings_)
|
||||
@ -673,7 +697,8 @@ class BMFileWriter(_AbstractPointer):
|
||||
out_file: bmap.bm_void_p = bmap.bm_void_p()
|
||||
# exec
|
||||
bmap.BMFile_Create(
|
||||
temp_folder, texture_folder, encoding_count, encodings,
|
||||
temp_folder, texture_folder, raw_callback,
|
||||
encoding_count, encodings,
|
||||
ctypes.byref(out_file)
|
||||
)
|
||||
# init self
|
||||
|
@ -304,3 +304,15 @@ class VXCMPFUNC(enum.IntEnum):
|
||||
VXCMP_NOTEQUAL = 6 ##< Accept if value if different than current value.
|
||||
VXCMP_GREATEREQUAL = 7 ##< Accept if value if greater or equal current value.
|
||||
VXCMP_ALWAYS = 8 ##< Always accept the test.
|
||||
|
||||
class VXMESH_LITMODE(enum.IntEnum):
|
||||
"""!
|
||||
{filename:VXMESH_LITMODE}
|
||||
Summary: Mesh lighting options
|
||||
|
||||
Remarks:
|
||||
+ The VXMESH_LITMODE is used by CKMesh::SetLitMode to specify how lighting is done.
|
||||
See Also: CKMaterial,CKMesh
|
||||
"""
|
||||
VX_PRELITMESH = 0 ##< Lighting use color information store with vertices
|
||||
VX_LITMESH = 1 ##< Lighting is done by renderer using normals and face material information.
|
@ -23,7 +23,7 @@ if "bpy" in locals():
|
||||
|
||||
#endregion
|
||||
|
||||
from . import PROP_preferences, PROP_virtools_material, PROP_virtools_texture, PROP_ballance_element, PROP_virtools_group
|
||||
from . import PROP_preferences, PROP_virtools_material, PROP_virtools_texture, PROP_virtools_mesh, PROP_ballance_element, PROP_virtools_group
|
||||
from . import OP_IMPORT_bmfile, OP_EXPORT_bmfile, OP_IMPORT_virtools, OP_EXPORT_virtools
|
||||
from . import OP_UV_flatten_uv, OP_UV_rail_uv
|
||||
|
||||
@ -87,6 +87,7 @@ def register() -> None:
|
||||
PROP_preferences.register()
|
||||
PROP_virtools_material.register()
|
||||
PROP_virtools_texture.register()
|
||||
PROP_virtools_mesh.register()
|
||||
PROP_ballance_element.register()
|
||||
PROP_virtools_group.register()
|
||||
|
||||
@ -129,6 +130,7 @@ def unregister() -> None:
|
||||
|
||||
PROP_virtools_group.unregister()
|
||||
PROP_ballance_element.unregister()
|
||||
PROP_virtools_mesh.unregister()
|
||||
PROP_virtools_texture.unregister()
|
||||
PROP_virtools_material.unregister()
|
||||
PROP_preferences.unregister()
|
||||
|
Loading…
Reference in New Issue
Block a user