From 302e0e48634a326333cdca06c417544006e418e7 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Wed, 7 Apr 2021 19:12:08 +0200 Subject: [PATCH] feat(import_bsi): Implement TEXCOORD import This imports UV maps. Signed-off-by: Lucas Schwiderski --- addons/bitsquid/import_bsi.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/addons/bitsquid/import_bsi.py b/addons/bitsquid/import_bsi.py index d55a230..050e457 100644 --- a/addons/bitsquid/import_bsi.py +++ b/addons/bitsquid/import_bsi.py @@ -19,7 +19,9 @@ import zlib import json import bpy import math + from mathutils import Vector, Matrix +from bpy_extras.io_utils import unpack_list def parse_sjson(file_path, skip_editor_data=True): @@ -187,6 +189,8 @@ def create_object(self, context, name, node_data, geometries): # A list of vectors, where each vector contains three indices into `vertices`. # Those three indices define the vertices that make up the face. faces = [] + uv_name = "UVMap" + uvs = [] tri_count = int(geometries["indices"]["size"]) / 3 @@ -194,9 +198,9 @@ def create_object(self, context, name, node_data, geometries): data_stream = geometries["streams"][i] stride = data_stream["stride"] / 4 - for channel in data_stream['channels']: + for channel in data_stream["channels"]: stream_data = data_stream["data"] - if channel['name'] == 'POSITION': + if channel["name"] == 'POSITION': # NOTE: Do we need to handle `stride != 3`? # Since the value seems to be fixed per stream, a higher # stride would only be possible for objects that can be built @@ -222,6 +226,16 @@ def create_object(self, context, name, node_data, geometries): index_stream[j + 1], index_stream[j + 2], ))) + elif channel["name"] == 'NORMAL': + # Blender is able to create normals from the face definition + # (i.e. the order in which the faces vertices were defined) + # and that seems to be good enough + self.report({'INFO'}, "Ignoring custom normals") + elif channel["name"] == 'TEXCOORD': + uv_name = "UVMap{}".format(channel["index"] + 1) + uv_data = data_stream["data"] + uv_defs = [uv_data[j:j+2] for j in range(0, len(uv_data), 2)] + uvs = [uv_defs[index_stream[j]] for j in range(0, len(index_stream))] else: # TODO: Implement other channel types self.report( @@ -232,6 +246,11 @@ def create_object(self, context, name, node_data, geometries): mesh = bpy.data.meshes.new(name) mesh.from_pydata(vertices, [], faces) + if len(uvs) > 0: + print("{} has UVs".format(name)) + uv_layer = mesh.uv_layers.new(name=uv_name) + uv_layer.data.foreach_set("uv", unpack_list(uvs)) + return mesh @@ -243,7 +262,7 @@ def matrix_from_list(list): it appears as though matrices stored in `.bsi` should be row ordered, but they are, in fact, column ordered. """ - stride = math.sqrt(len(list)) + stride = int(math.sqrt(len(list))) rows = [] for i in range(stride): row = (list[i], list[i+stride], list[i+(stride*2)], list[i+(stride*3)])