fix: fix light direction issue when importing and exporting virtools file.

This commit is contained in:
yyc12345 2025-01-03 23:42:44 +08:00
parent 3372c7a4b7
commit 94d5c934c6
3 changed files with 41 additions and 7 deletions

View File

@ -1,4 +1,4 @@
import bpy import bpy, mathutils
from bpy_extras.wm_utils.progress_report import ProgressReport from bpy_extras.wm_utils.progress_report import ProgressReport
import tempfile, os, typing import tempfile, os, typing
from . import PROP_preferences, UTIL_ioport_shared from . import PROP_preferences, UTIL_ioport_shared
@ -228,9 +228,9 @@ def _export_virtools_light(
# setup 3d entity parts # setup 3d entity parts
# set world matrix # set world matrix
# TODO: fix light direction matrix issue.
vtmat: UTIL_virtools_types.VxMatrix = UTIL_virtools_types.VxMatrix() vtmat: UTIL_virtools_types.VxMatrix = UTIL_virtools_types.VxMatrix()
UTIL_virtools_types.vxmatrix_from_blender(vtmat, obj3d.matrix_world) bldmat: mathutils.Matrix = UTIL_virtools_types.bldmatrix_restore_light_obj(obj3d.matrix_world)
UTIL_virtools_types.vxmatrix_from_blender(vtmat, bldmat)
UTIL_virtools_types.vxmatrix_conv_co(vtmat) UTIL_virtools_types.vxmatrix_conv_co(vtmat)
vtlight.set_world_matrix(vtmat) vtlight.set_world_matrix(vtmat)
# set visibility # set visibility

View File

@ -1,4 +1,4 @@
import bpy import bpy, mathutils
from bpy_extras.wm_utils.progress_report import ProgressReport from bpy_extras.wm_utils.progress_report import ProgressReport
import tempfile, os, typing import tempfile, os, typing
from . import PROP_preferences, UTIL_ioport_shared from . import PROP_preferences, UTIL_ioport_shared
@ -381,10 +381,10 @@ def _import_virtools_lights(
# add into scene # add into scene
UTIL_functions.add_into_scene(light_3dobj) UTIL_functions.add_into_scene(light_3dobj)
# set world matrix # set world matrix
# TODO: fix light direction
vtmat: UTIL_virtools_types.VxMatrix = vtlight.get_world_matrix() vtmat: UTIL_virtools_types.VxMatrix = vtlight.get_world_matrix()
UTIL_virtools_types.vxmatrix_conv_co(vtmat) UTIL_virtools_types.vxmatrix_conv_co(vtmat)
light_3dobj.matrix_world = UTIL_virtools_types.vxmatrix_to_blender(vtmat) bldmat: mathutils.Matrix = UTIL_virtools_types.vxmatrix_to_blender(vtmat)
light_3dobj.matrix_world = UTIL_virtools_types.bldmatrix_patch_light_obj(bldmat)
# set visibility # set visibility
light_3dobj.hide_set(not vtlight.get_visibility()) light_3dobj.hide_set(not vtlight.get_visibility())

View File

@ -1,5 +1,5 @@
import mathutils import mathutils
import typing, sys import typing, math
from . import UTIL_functions from . import UTIL_functions
# extract all declarations in PyBMap # extract all declarations in PyBMap
@ -45,6 +45,7 @@ def vxmatrix_conv_co(self: VxMatrix) -> None:
def vxmatrix_from_blender(self: VxMatrix, data_: mathutils.Matrix) -> None: def vxmatrix_from_blender(self: VxMatrix, data_: mathutils.Matrix) -> None:
""" """
Set matrix by blender matrix. Set matrix by blender matrix.
Please note there is no corrdinate system convertion between
""" """
# transposed first # transposed first
data: mathutils.Matrix = data_.transposed() data: mathutils.Matrix = data_.transposed()
@ -74,6 +75,39 @@ def vxmatrix_to_blender(self: VxMatrix) -> mathutils.Matrix:
data.transpose() data.transpose()
return data return data
## Hints about Light Matrix
# There is a slight difference between Virtools and Blender.
# In blender, the default direction of all directional light (spot and sun) are Down (-Z).
# Hoewver, in Virtools, the default direction of all directional light (spot and directional) are Forward (+Z).
#
# As brief view, in Blender coordinate system, you can see that we got Blender default light direction
# from Virtools default light direction by rotating it around X-axis with -90 degree
# (the positive rotation direction is decided by right hand priniciple).
#
# So, if the object we importing is a light, we need add a special transform matrix ahead of world matrix
# to correct the light default direction first.
# When exporting, just do a reverse operation.
def bldmatrix_patch_light_obj(data: mathutils.Matrix) -> mathutils.Matrix:
"""
Add patch for light world matrix to correct its direction.
This function is usually used when importing light.
"""
# we multiple a matrix which represent a 90 degree roration in X-axis.
# right multiple means that it will apply to light first, before apply the matrix gotten from virtools.
return data @ mathutils.Matrix.Rotation(math.radians(90), 4, 'X')
def bldmatrix_restore_light_obj(data: mathutils.Matrix) -> mathutils.Matrix:
"""
The reverse operation of bldmatrix_patch_light_mat().
This function is usually used when exporting light.
"""
# as the reverse operation, we need right mutiple a reversed matrix of the matrix
# which represent a 90 degree roration in X-axis to remove the matrix we added in patch step.
# however, the reverse matrix of 90 degree X-axis rotation is just NEGATUIVE 90 degree X-axis rotation.
# so we simply right multiple it.
return data @ mathutils.Matrix.Rotation(math.radians(-90), 4, 'X')
#endregion #endregion
#region Blender EnumProperty Creation #region Blender EnumProperty Creation