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

Improved PSK vertex color importing to be per-corner instead of per-vertex

Previously, the importer was storing the vertex colors in the point
domain. However, the PSK itself stores colors per "wedge", which maps
to corners, resulting in the "ambiguous vertex colors" warning if two
corners mapped to the same vertex but had different colors.

The new method is now more correct and doesn't discard data.
This commit is contained in:
Colin Basnett 2024-01-22 14:56:51 -08:00
parent 3d3bbb9296
commit b2f5985681

View File

@ -1,4 +1,3 @@
from math import inf
from typing import Optional, List
import bmesh
@ -17,7 +16,7 @@ class PskImportOptions:
self.should_import_mesh = True
self.should_reuse_materials = True
self.should_import_vertex_colors = True
self.vertex_color_space = 'sRGB'
self.vertex_color_space = 'SRGB'
self.should_import_vertex_normals = True
self.should_import_extra_uvs = True
self.should_import_skeleton = True
@ -144,6 +143,7 @@ def import_psk(psk: Psk, context, options: PskImportOptions) -> PskImportResult:
bm.verts.ensure_lookup_table()
# FACES
invalid_face_indices = set()
for face_index, face in enumerate(psk.faces):
point_indices = map(lambda i: psk.wedges[i].point_index, reversed(face.wedge_indices))
@ -192,33 +192,28 @@ def import_psk(psk: Psk, context, options: PskImportOptions) -> PskImportResult:
# 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')
ambiguous_vertex_color_point_indices = []
# Convert vertex colors to sRGB if necessary.
psk_vertex_colors = np.zeros((len(psk.vertex_colors), 4))
for i in range(len(psk.vertex_colors)):
psk_vertex_colors[i,:] = psk.vertex_colors[i].normalized()
match options.vertex_color_space:
case 'SRGBA':
for i in range(psk_vertex_colors.shape[0]):
psk_vertex_colors[i, :3] = tuple(map(lambda x: rgb_to_srgb(x), psk_vertex_colors[i, :3]))
case _:
pass
for wedge_index, wedge in enumerate(psk.wedges):
point_index = wedge.point_index
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)
else:
vertex_colors[point_index] = psk_vertex_color
# Map the PSK vertex colors to the face corners.
face_corner_colors = np.full((len(psk.faces * 3), 4), 1.0)
face_corner_color_index = 0
for face_index, face in enumerate(psk.faces):
for wedge_index in reversed(face.wedge_indices):
face_corner_colors[face_corner_color_index] = psk_vertex_colors[wedge_index]
face_corner_color_index += 1
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
else:
vertex_color_data.data[loop_index].color = 1.0, 1.0, 1.0, 1.0
if len(ambiguous_vertex_color_point_indices) > 0:
result.warnings.append(
f'{len(ambiguous_vertex_color_point_indices)} vertex(es) with ambiguous vertex colors.')
# Create the vertex color attribute.
face_corner_color_attribute = mesh_data.attributes.new(name='VERTEXCOLOR', type='FLOAT_COLOR', domain='CORNER')
face_corner_color_attribute.data.foreach_set('color', face_corner_colors.flatten())
# VERTEX NORMALS
if psk.has_vertex_normals and options.should_import_vertex_normals: