feat: add blc params in exporter. fix bme.
- add ballance params section and successive switch in virtools file exporter to allow user manually cancel sector group ensurance which give user a way to export component, not the whole level. - add mirror matrix detection in bme creation. a mirror matrix will reverse triangle indice order. we need reverse it again when facing mirror matrix. this resolves the issue when applying term 3. - use mirror, not rotation to create straight floor in bme which give a better looks in game.
This commit is contained in:
parent
3a1a0fb0f6
commit
07298fd21c
@ -20,19 +20,26 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
|
||||
description = "Decide how texture saved if texture is specified as Use Global as its Save Options.",
|
||||
items = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
|
||||
default = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.to_selection(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_EXTERNAL)
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
use_compress: bpy.props.BoolProperty(
|
||||
name="Use Compress",
|
||||
description = "Whether use ZLib to compress result when saving composition.",
|
||||
default = True,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
compress_level: bpy.props.IntProperty(
|
||||
name = "Compress Level",
|
||||
description = "The ZLib compress level used by Virtools Engine when saving composition.",
|
||||
min = 1, max = 9,
|
||||
default = 5,
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
successive_sector: bpy.props.BoolProperty(
|
||||
name="Successive Sector",
|
||||
description = "Whether order exporter to use document specified sector count to make sure sector is successive.",
|
||||
default = True,
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
@ -59,6 +66,7 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
|
||||
_g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.get_selection(self.texture_save_opt),
|
||||
self.use_compress,
|
||||
self.compress_level,
|
||||
self.successive_sector,
|
||||
objls
|
||||
)
|
||||
|
||||
@ -86,8 +94,11 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
|
||||
|
||||
# show sector info to notice user
|
||||
layout.separator()
|
||||
layout.label(text = 'Ballance Params')
|
||||
box = layout.box()
|
||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||
layout.label(text = f'Map Sectors: {map_info.mSectorCount}')
|
||||
box.prop(self, 'successive_sector')
|
||||
box.label(text = f'Map Sectors: {map_info.mSectorCount}')
|
||||
|
||||
_TObj3dPair = tuple[bpy.types.Object, bmap.BM3dObject]
|
||||
_TMeshPair = tuple[bpy.types.Object, bpy.types.Mesh, bmap.BMMesh]
|
||||
@ -100,6 +111,7 @@ def _export_virtools(
|
||||
texture_save_opt_: UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS,
|
||||
use_compress_: bool,
|
||||
compress_level_: int,
|
||||
successive_sector_: bool,
|
||||
export_objects: tuple[bpy.types.Object, ...]
|
||||
) -> None:
|
||||
|
||||
@ -119,7 +131,7 @@ def _export_virtools(
|
||||
obj3d_crets: tuple[_TObj3dPair, ...] = _prepare_virtools_3dobjects(
|
||||
writer, progress, export_objects)
|
||||
# export group and 3dobject by prepared 3dobject
|
||||
_export_virtools_groups(writer, progress, obj3d_crets)
|
||||
_export_virtools_groups(writer, progress, successive_sector_, obj3d_crets)
|
||||
mesh_crets: tuple[_TMeshPair, ...] = _export_virtools_3dobjects(
|
||||
writer, progress, obj3d_crets)
|
||||
# export mesh
|
||||
@ -168,6 +180,7 @@ def _prepare_virtools_3dobjects(
|
||||
def _export_virtools_groups(
|
||||
writer: bmap.BMFileWriter,
|
||||
progress: ProgressReport,
|
||||
successive_sector: bool,
|
||||
obj3d_crets: tuple[_TObj3dPair, ...]
|
||||
) -> None:
|
||||
# create virtools group
|
||||
@ -175,7 +188,7 @@ def _export_virtools_groups(
|
||||
# start saving
|
||||
progress.enter_substeps(len(obj3d_crets), "Saving Groups")
|
||||
|
||||
# create sector group first
|
||||
# create sector group first if user ordered
|
||||
# This step is designed for ensure that the created sector group is successive.
|
||||
#
|
||||
# Due to the design of Ballance, Ballance rely on checking the existance of Sector_XX to get how many sectors this map have.
|
||||
@ -183,14 +196,16 @@ def _export_virtools_groups(
|
||||
# or be ended at a accident sector.
|
||||
#
|
||||
# So we create all needed sector group in here to make sure exported virtools file can be read by Ballancde correctly.
|
||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||
for i in range(map_info.mSectorCount):
|
||||
gp_name: str = UTIL_naming_convension.build_name_from_sector_index(i + 1)
|
||||
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
|
||||
if vtgroup is None:
|
||||
vtgroup = writer.create_group()
|
||||
vtgroup.set_name(gp_name)
|
||||
group_cret_map[gp_name] = vtgroup
|
||||
if successive_sector:
|
||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo
|
||||
map_info = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||
for i in range(map_info.mSectorCount):
|
||||
gp_name: str = UTIL_naming_convension.build_name_from_sector_index(i + 1)
|
||||
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
|
||||
if vtgroup is None:
|
||||
vtgroup = writer.create_group()
|
||||
vtgroup.set_name(gp_name)
|
||||
group_cret_map[gp_name] = vtgroup
|
||||
|
||||
for obj3d, vtobj3d in obj3d_crets:
|
||||
# open group visitor
|
||||
|
@ -344,6 +344,12 @@ def create_bme_struct(
|
||||
cache_bv = typing.cast(mathutils.Vector, transform @ cache_bv)
|
||||
# get result
|
||||
prebuild_vec_data.append((cache_bv.x, cache_bv.y, cache_bv.z))
|
||||
|
||||
# Check whether given transform is mirror matrix
|
||||
# because mirror matrix will reverse triangle indice order.
|
||||
# If matrix is mirror matrix, we need reverse it again in following procession,
|
||||
# including getting uv, calculating normal and providing face data.
|
||||
mirror_matrix: bool = _is_mirror_matrix(transform)
|
||||
|
||||
# prepare mesh part data
|
||||
mesh_part: UTIL_blender_mesh.MeshWriterIngredient = UTIL_blender_mesh.MeshWriterIngredient()
|
||||
@ -370,7 +376,12 @@ def create_bme_struct(
|
||||
if face_nml_data is None:
|
||||
# nml is null, we need compute by ourselves
|
||||
# get first 3 entries in indices list as the compution ref
|
||||
face_indices_data: list[int] = face_data[TOKEN_FACES_INDICES]
|
||||
# please note that we may need reverse it
|
||||
face_indices_data: list[int]
|
||||
if mirror_matrix:
|
||||
face_indices_data = face_data[TOKEN_FACES_INDICES][::-1]
|
||||
else:
|
||||
face_indices_data = face_data[TOKEN_FACES_INDICES][:]
|
||||
# compute it by getting vertices info from prebuild vertices data
|
||||
# because the normals is computed from transformed vertices
|
||||
# so no need to correct its by normal transform.
|
||||
@ -399,7 +410,9 @@ def create_bme_struct(
|
||||
v: UTIL_virtools_types.VxVector2 = UTIL_virtools_types.VxVector2()
|
||||
for face_idx in valid_face_idx:
|
||||
face_data: dict[str, typing.Any] = proto[TOKEN_FACES][face_idx]
|
||||
for i in range(len(face_data[TOKEN_FACES_INDICES])):
|
||||
# iterate uv list considering mirror matrix
|
||||
indices_count: int = len(face_data[TOKEN_FACES_INDICES])
|
||||
for i in (range(indices_count)[::-1] if mirror_matrix else range(indices_count)):
|
||||
# BME uv do not need any extra process
|
||||
v.x, v.y = _eval_others(face_data[TOKEN_FACES_UVS][i], params)
|
||||
yield v
|
||||
@ -424,8 +437,13 @@ def create_bme_struct(
|
||||
# get face data
|
||||
face_data: dict[str, typing.Any] = proto[TOKEN_FACES][face_idx]
|
||||
|
||||
# get face indices considering the mirror matrix
|
||||
face_indices: list[int]
|
||||
if mirror_matrix:
|
||||
face_indices = face_data[TOKEN_FACES_INDICES][::-1]
|
||||
else:
|
||||
face_indices = face_data[TOKEN_FACES_INDICES][:]
|
||||
# calc indices count
|
||||
face_indices: list[int] = face_data[TOKEN_FACES_INDICES]
|
||||
indices_count: int = len(face_indices)
|
||||
# resize face data to fulfill req
|
||||
while len(f.mIndices) > indices_count:
|
||||
@ -499,5 +517,18 @@ def _compute_normals(
|
||||
corss_mul.normalize()
|
||||
return (corss_mul.x, corss_mul.y, corss_mul.z)
|
||||
|
||||
def _is_mirror_matrix(mat: mathutils.Matrix) -> bool:
|
||||
"""
|
||||
Reflection matrix (aka. mirror matrix) is a special scaling matrix.
|
||||
In this matrix, 1 or 3 scaling factor is minus number.
|
||||
|
||||
Mirror matrix will cause the inverse of triangle indice order.
|
||||
So we need detect it and re-reverse when creating bm struct.
|
||||
This function can detect whether given matrix is mirror matrix.
|
||||
|
||||
Reference: https://zhuanlan.zhihu.com/p/96717729
|
||||
"""
|
||||
return mat.is_negative
|
||||
#return mat.to_3x3().determinant() < 0
|
||||
|
||||
#endregion
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user