1
Fork 0

feat(import_bsi): Implement TEXCOORD import

This imports UV maps.

Signed-off-by: Lucas Schwiderski <lucas@lschwiderski.de>
This commit is contained in:
Lucas Schwiderski 2021-04-07 19:12:08 +02:00
parent 0c7613f735
commit 302e0e4863
Signed by: lucas
GPG key ID: AA12679AAA6DF4D8

View file

@ -19,7 +19,9 @@ import zlib
import json import json
import bpy import bpy
import math import math
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from bpy_extras.io_utils import unpack_list
def parse_sjson(file_path, skip_editor_data=True): 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`. # A list of vectors, where each vector contains three indices into `vertices`.
# Those three indices define the vertices that make up the face. # Those three indices define the vertices that make up the face.
faces = [] faces = []
uv_name = "UVMap"
uvs = []
tri_count = int(geometries["indices"]["size"]) / 3 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] data_stream = geometries["streams"][i]
stride = data_stream["stride"] / 4 stride = data_stream["stride"] / 4
for channel in data_stream['channels']: for channel in data_stream["channels"]:
stream_data = data_stream["data"] stream_data = data_stream["data"]
if channel['name'] == 'POSITION': if channel["name"] == 'POSITION':
# NOTE: Do we need to handle `stride != 3`? # NOTE: Do we need to handle `stride != 3`?
# Since the value seems to be fixed per stream, a higher # Since the value seems to be fixed per stream, a higher
# stride would only be possible for objects that can be built # 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 + 1],
index_stream[j + 2], 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: else:
# TODO: Implement other channel types # TODO: Implement other channel types
self.report( self.report(
@ -232,6 +246,11 @@ def create_object(self, context, name, node_data, geometries):
mesh = bpy.data.meshes.new(name) mesh = bpy.data.meshes.new(name)
mesh.from_pydata(vertices, [], faces) 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 return mesh
@ -243,7 +262,7 @@ def matrix_from_list(list):
it appears as though matrices stored in `.bsi` should be row ordered, it appears as though matrices stored in `.bsi` should be row ordered,
but they are, in fact, column ordered. but they are, in fact, column ordered.
""" """
stride = math.sqrt(len(list)) stride = int(math.sqrt(len(list)))
rows = [] rows = []
for i in range(stride): for i in range(stride):
row = (list[i], list[i+stride], list[i+(stride*2)], list[i+(stride*3)]) row = (list[i], list[i+stride], list[i+(stride*2)], list[i+(stride*3)])