1
0
mirror of https://github.com/DarklightGames/io_scene_psk_psa.git synced 2024-11-28 00:20:48 +01:00

Added vertex color space conversion option for sRGBA (this is now the default to match UE4.24)

This commit is contained in:
Colin Basnett 2022-01-27 15:11:32 -08:00
parent 2ba29b04d3
commit a62ee207e1
4 changed files with 76 additions and 19 deletions

View File

@ -72,6 +72,7 @@ def register():
bpy.types.TOPBAR_MT_file_import.append(psk_import_menu_func)
bpy.types.TOPBAR_MT_file_export.append(psa_export_menu_func)
bpy.types.Scene.psa_import = PointerProperty(type=psa_importer.PsaImportPropertyGroup)
bpy.types.Scene.psk_import = PointerProperty(type=psk_importer.PskImportPropertyGroup)
bpy.types.Scene.psa_export = PointerProperty(type=psa_exporter.PsaExportPropertyGroup)
bpy.types.Scene.psk_export = PointerProperty(type=psk_exporter.PskExportPropertyGroup)

View File

@ -1,6 +1,13 @@
from typing import List
def rgb_to_srgb(c):
if c > 0.0031308:
return 1.055 * (pow(c, (1.0 / 2.4))) - 0.055
else:
return 12.92 * c
def populate_bone_group_list(armature_object, bone_group_list):
bone_group_list.clear()

View File

@ -235,7 +235,7 @@ def on_psa_file_path_updated(property, context):
pass
class PsaImportPropertyGroup(bpy.types.PropertyGroup):
class PsaImportPropertyGroup(PropertyGroup):
psa_file_path: StringProperty(default='', update=on_psa_file_path_updated, name='PSA File Path')
psa_bones: CollectionProperty(type=PsaImportPsaBoneItem)
action_list: CollectionProperty(type=PsaImportActionListItem)

View File

@ -1,23 +1,35 @@
import os
import bpy
import bmesh
import numpy as np
from math import inf
from typing import Optional
from .data import Psk
from ..helpers import rgb_to_srgb
from mathutils import Quaternion, Vector, Matrix
from .reader import PskReader
from bpy.props import StringProperty
from bpy.types import Operator
from bpy.props import StringProperty, EnumProperty, BoolProperty
from bpy.types import Operator, PropertyGroup
from bpy_extras.io_utils import ImportHelper
class PskImportOptions(object):
def __init__(self):
self.name = ''
self.should_import_vertex_colors = True
self.vertex_color_space = 'sRGB'
self.should_import_vertex_normals = True
self.should_import_extra_uvs = True
class PskImporter(object):
def __init__(self):
pass
def import_psk(self, psk: Psk, name: str, context):
def import_psk(self, psk: Psk, context, options: PskImportOptions):
# ARMATURE
armature_data = bpy.data.armatures.new(name)
armature_object = bpy.data.objects.new(name, armature_data)
armature_data = bpy.data.armatures.new(options.name)
armature_object = bpy.data.objects.new(options.name, armature_data)
armature_object.show_in_front = True
context.scene.collection.objects.link(armature_object)
@ -95,8 +107,8 @@ class PskImporter(object):
edit_bone['post_quat'] = import_bone.local_rotation.conjugated()
# MESH
mesh_data = bpy.data.meshes.new(name)
mesh_object = bpy.data.objects.new(name, mesh_data)
mesh_data = bpy.data.meshes.new(options.name)
mesh_object = bpy.data.objects.new(options.name, mesh_data)
# MATERIALS
for material in psk.materials:
@ -138,7 +150,7 @@ class PskImporter(object):
data_index += 1
# EXTRA UVS
if psk.has_extra_uvs:
if psk.has_extra_uvs and options.should_import_extra_uvs:
extra_uv_channel_count = int(len(psk.extra_uvs) / len(psk.wedges))
wedge_index_offset = 0
for extra_uv_index in range(extra_uv_channel_count):
@ -154,21 +166,28 @@ class PskImporter(object):
wedge_index_offset += len(psk.wedges)
# VERTEX COLORS
if psk.has_vertex_colors:
if psk.has_vertex_colors and options.should_import_vertex_colors:
size = (len(psk.points), 4)
vertex_colors = np.full(size, inf)
vertex_color_data = mesh_data.vertex_colors.new(name='VERTEXCOLOR')
vertex_colors = [None] * len(psk.points)
ambiguous_vertex_color_point_indices = []
for wedge_index, wedge in enumerate(psk.wedges):
point_index = wedge.point_index
psk_vertex_color = psk.vertex_colors[wedge_index]
if vertex_colors[point_index] is not None and vertex_colors[point_index] != psk_vertex_color:
psk_vertex_color = psk.vertex_colors[wedge_index].normalized()
if vertex_colors[point_index, 0] != inf and tuple(vertex_colors[point_index]) != psk_vertex_color:
ambiguous_vertex_color_point_indices.append(point_index)
vertex_colors[point_index] = psk_vertex_color
else:
vertex_colors[point_index] = psk_vertex_color
if options.vertex_color_space == 'SRGBA':
for i in range(vertex_colors.shape[0]):
vertex_colors[i, :3] = tuple(map(lambda x: rgb_to_srgb(x), vertex_colors[i, :3]))
for loop_index, loop in enumerate(mesh_data.loops):
vertex_color = vertex_colors[loop.vertex_index]
if vertex_color is not None:
vertex_color_data.data[loop_index].color = vertex_color.normalized()
vertex_color_data.data[loop_index].color = vertex_color
else:
vertex_color_data.data[loop_index].color = 1.0, 1.0, 1.0, 1.0
@ -176,7 +195,7 @@ class PskImporter(object):
print(f'WARNING: {len(ambiguous_vertex_color_point_indices)} vertex(es) with ambiguous vertex colors.')
# VERTEX NORMALS
if psk.has_vertex_normals:
if psk.has_vertex_normals and options.should_import_vertex_normals:
mesh_data.polygons.foreach_set("use_smooth", [True] * len(mesh_data.polygons))
normals = []
for vertex_normal in psk.vertex_normals:
@ -208,6 +227,21 @@ class PskImporter(object):
pass
class PskImportPropertyGroup(PropertyGroup):
should_import_vertex_colors: BoolProperty(default=True, name='Vertex Colors')
vertex_color_space: EnumProperty(
name='Vertex Color Space',
description='',
default='SRGBA',
items=(
('LINEAR', 'Linear', ''),
('SRGBA', 'sRGBA', ''),
)
)
should_import_vertex_normals: BoolProperty(default=True, name='Vertex Normals')
should_import_extra_uvs: BoolProperty(default=True, name='Extra UVs')
class PskImportOperator(Operator, ImportHelper):
bl_idname = 'import.psk'
bl_label = 'Export'
@ -221,13 +255,28 @@ class PskImportOperator(Operator, ImportHelper):
default='')
def execute(self, context):
pg = context.scene.psk_import
reader = PskReader()
psk = reader.read(self.filepath)
name = os.path.splitext(os.path.basename(self.filepath))[0]
PskImporter().import_psk(psk, name, context)
options = PskImportOptions()
options.name = os.path.splitext(os.path.basename(self.filepath))[0]
options.vertex_color_space = pg.vertex_color_space
PskImporter().import_psk(psk, context, options)
return {'FINISHED'}
def draw(self, context):
pg = context.scene.psk_import
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
layout.prop(pg, 'should_import_vertex_normals')
layout.prop(pg, 'should_import_extra_uvs')
layout.prop(pg, 'should_import_vertex_colors')
if pg.should_import_vertex_colors:
layout.prop(pg, 'vertex_color_space')
__classes__ = [
PskImportOperator
PskImportOperator,
PskImportPropertyGroup,
]