Skip to content
Snippets Groups Projects
Commit 01186b0d authored by Julien Duroure's avatar Julien Duroure
Browse files

gltf exporter: Fix T76677 primitive extraction code refactoring

parent 955332bf
Branches
Tags
No related merge requests found
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
bl_info = { bl_info = {
'name': 'glTF 2.0 format', 'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', 'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (1, 3, 28), "version": (1, 3, 29),
'blender': (2, 90, 0), 'blender': (2, 90, 0),
'location': 'File > Import-Export', 'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0', 'description': 'Import-Export as glTF 2.0',
......
...@@ -18,40 +18,22 @@ ...@@ -18,40 +18,22 @@
from mathutils import Vector, Quaternion, Matrix from mathutils import Vector, Quaternion, Matrix
from mathutils.geometry import tessellate_polygon from mathutils.geometry import tessellate_polygon
from operator import attrgetter
from . import gltf2_blender_export_keys from . import gltf2_blender_export_keys
from ...io.com.gltf2_io_debug import print_console from ...io.com.gltf2_io_debug import print_console
from ...io.com.gltf2_io_color_management import color_srgb_to_scene_linear from ...io.com.gltf2_io_color_management import color_srgb_to_scene_linear
from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
#
# Globals
#
INDICES_ID = 'indices'
MATERIAL_ID = 'material'
ATTRIBUTES_ID = 'attributes'
COLOR_PREFIX = 'COLOR_'
MORPH_TANGENT_PREFIX = 'MORPH_TANGENT_'
MORPH_NORMAL_PREFIX = 'MORPH_NORMAL_'
MORPH_POSITION_PREFIX = 'MORPH_POSITION_'
TEXCOORD_PREFIX = 'TEXCOORD_'
WEIGHTS_PREFIX = 'WEIGHTS_'
JOINTS_PREFIX = 'JOINTS_'
TANGENT_ATTRIBUTE = 'TANGENT'
NORMAL_ATTRIBUTE = 'NORMAL'
POSITION_ATTRIBUTE = 'POSITION'
GLTF_MAX_COLORS = 2
# #
# Classes # Classes
# #
class Prim:
def __init__(self):
self.verts = {}
self.indices = []
class ShapeKey: class ShapeKey:
def __init__(self, shape_key, vertex_normals, polygon_normals): def __init__(self, shape_key, vertex_normals, polygon_normals):
self.shape_key = shape_key self.shape_key = shape_key
...@@ -110,17 +92,17 @@ def convert_swizzle_tangent(tan, armature, blender_object, export_settings): ...@@ -110,17 +92,17 @@ def convert_swizzle_tangent(tan, armature, blender_object, export_settings):
if (not armature) or (not blender_object): if (not armature) or (not blender_object):
# Classic case. Mesh is not skined, no need to apply armature transfoms on vertices / normals / tangents # Classic case. Mesh is not skined, no need to apply armature transfoms on vertices / normals / tangents
if export_settings[gltf2_blender_export_keys.YUP]: if export_settings[gltf2_blender_export_keys.YUP]:
return Vector((tan[0], tan[2], -tan[1], 1.0)) return Vector((tan[0], tan[2], -tan[1]))
else: else:
return Vector((tan[0], tan[1], tan[2], 1.0)) return Vector((tan[0], tan[1], tan[2]))
else: else:
# Mesh is skined, we have to apply armature transforms on data # Mesh is skined, we have to apply armature transforms on data
apply_matrix = armature.matrix_world.inverted() @ blender_object.matrix_world apply_matrix = armature.matrix_world.inverted() @ blender_object.matrix_world
new_tan = apply_matrix.to_quaternion() @ tan new_tan = apply_matrix.to_quaternion() @ Vector((tan[0], tan[1], tan[2]))
if export_settings[gltf2_blender_export_keys.YUP]: if export_settings[gltf2_blender_export_keys.YUP]:
return Vector((new_tan[0], new_tan[2], -new_tan[1], 1.0)) return Vector((new_tan[0], new_tan[2], -new_tan[1]))
else: else:
return Vector((new_tan[0], new_tan[1], new_tan[2], 1.0)) return Vector((new_tan[0], new_tan[1], new_tan[2]))
def convert_swizzle_rotation(rot, export_settings): def convert_swizzle_rotation(rot, export_settings):
""" """
...@@ -151,173 +133,129 @@ def decompose_transition(matrix, export_settings): ...@@ -151,173 +133,129 @@ def decompose_transition(matrix, export_settings):
def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vertex_groups, modifiers, export_settings): def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vertex_groups, modifiers, export_settings):
""" """
Extract primitives from a mesh. Polygons are triangulated and sorted by material. Extract primitives from a mesh. Polygons are triangulated and sorted by material.
Vertices in multiple faces get split up as necessary.
Furthermore, primitives are split up, if the indices range is exceeded.
Finally, triangles are also split up/duplicated, if face normals are used instead of vertex normals.
""" """
print_console('INFO', 'Extracting primitive: ' + blender_mesh.name) print_console('INFO', 'Extracting primitive: ' + blender_mesh.name)
if blender_mesh.has_custom_normals:
# Custom normals are all (0, 0, 0) until calling calc_normals_split() or calc_tangents().
blender_mesh.calc_normals_split()
use_tangents = False
if blender_mesh.uv_layers.active and len(blender_mesh.uv_layers) > 0:
try:
blender_mesh.calc_tangents()
use_tangents = True
except Exception:
print_console('WARNING', 'Could not calculate tangents. Please try to triangulate the mesh first.')
# #
# First, decide what attributes to gather (eg. how many COLOR_n, etc.)
material_map = {} # Also calculate normals/tangents now if necessary.
# #
# Gathering position, normal and tex_coords.
#
no_material_attributes = {
POSITION_ATTRIBUTE: [],
NORMAL_ATTRIBUTE: []
}
if use_tangents:
no_material_attributes[TANGENT_ATTRIBUTE] = []
# use_normals = export_settings[gltf2_blender_export_keys.NORMALS]
# Directory of materials with its primitive. if use_normals:
# if blender_mesh.has_custom_normals:
no_material_primitives = { # Custom normals are all (0, 0, 0) until calling calc_normals_split() or calc_tangents().
MATERIAL_ID: 0, blender_mesh.calc_normals_split()
INDICES_ID: [],
ATTRIBUTES_ID: no_material_attributes
}
material_idx_to_primitives = {0: no_material_primitives} use_tangents = False
if use_normals and export_settings[gltf2_blender_export_keys.TANGENTS]:
# if blender_mesh.uv_layers.active and len(blender_mesh.uv_layers) > 0:
try:
vertex_index_to_new_indices = {} blender_mesh.calc_tangents()
use_tangents = True
material_map[0] = vertex_index_to_new_indices except Exception:
print_console('WARNING', 'Could not calculate tangents. Please try to triangulate the mesh first.')
#
# Create primitive for each material.
#
for (mat_idx, _) in enumerate(blender_mesh.materials):
attributes = {
POSITION_ATTRIBUTE: [],
NORMAL_ATTRIBUTE: []
}
if use_tangents:
attributes[TANGENT_ATTRIBUTE] = []
primitive = {
MATERIAL_ID: mat_idx,
INDICES_ID: [],
ATTRIBUTES_ID: attributes
}
material_idx_to_primitives[mat_idx] = primitive
#
vertex_index_to_new_indices = {}
material_map[mat_idx] = vertex_index_to_new_indices
tex_coord_max = 0 tex_coord_max = 0
if blender_mesh.uv_layers.active: if export_settings[gltf2_blender_export_keys.TEX_COORDS]:
tex_coord_max = len(blender_mesh.uv_layers) if blender_mesh.uv_layers.active:
tex_coord_max = len(blender_mesh.uv_layers)
#
vertex_colors = {}
color_index = 0 color_max = 0
for vertex_color in blender_mesh.vertex_colors: if export_settings[gltf2_blender_export_keys.COLORS]:
vertex_color_name = COLOR_PREFIX + str(color_index) color_max = len(blender_mesh.vertex_colors)
vertex_colors[vertex_color_name] = vertex_color
color_index += 1 bone_max = 0 # number of JOINTS_n sets needed (1 set = 4 influences)
if color_index >= GLTF_MAX_COLORS: armature = None
break if blender_vertex_groups and export_settings[gltf2_blender_export_keys.SKINS]:
color_max = color_index if modifiers is not None:
modifiers_dict = {m.type: m for m in modifiers}
# if "ARMATURE" in modifiers_dict:
modifier = modifiers_dict["ARMATURE"]
bone_max = 0 armature = modifier.object
for blender_polygon in blender_mesh.polygons:
for loop_index in blender_polygon.loop_indices: # Skin must be ignored if the object is parented to a bone of the armature
vertex_index = blender_mesh.loops[loop_index].vertex_index # (This creates an infinite recursive error)
bones_count = len(blender_mesh.vertices[vertex_index].groups) # So ignoring skin in that case
if bones_count > 0: is_child_of_arma = (
if bones_count % 4 == 0: armature and
bones_count -= 1 blender_object and
bone_max = max(bone_max, bones_count // 4 + 1) blender_object.parent_type == "BONE" and
blender_object.parent.name == armature.name
# )
if is_child_of_arma:
morph_max = 0 armature = None
blender_shape_keys = [] if armature:
skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
if blender_mesh.shape_keys is not None: if not skin:
armature = None
else:
joint_name_to_index = {joint.name: index for index, joint in enumerate(skin.joints)}
group_to_joint = [joint_name_to_index.get(g.name) for g in blender_vertex_groups]
# Find out max number of bone influences
for blender_polygon in blender_mesh.polygons:
for loop_index in blender_polygon.loop_indices:
vertex_index = blender_mesh.loops[loop_index].vertex_index
groups_count = len(blender_mesh.vertices[vertex_index].groups)
bones_count = (groups_count + 3) // 4
bone_max = max(bone_max, bones_count)
use_morph_normals = use_normals and export_settings[gltf2_blender_export_keys.MORPH_NORMAL]
use_morph_tangents = use_morph_normals and use_tangents and export_settings[gltf2_blender_export_keys.MORPH_TANGENT]
shape_keys = []
if blender_mesh.shape_keys and export_settings[gltf2_blender_export_keys.MORPH]:
for blender_shape_key in blender_mesh.shape_keys.key_blocks: for blender_shape_key in blender_mesh.shape_keys.key_blocks:
if blender_shape_key != blender_shape_key.relative_key: if blender_shape_key == blender_shape_key.relative_key or blender_shape_key.mute:
if blender_shape_key.mute is False: continue
morph_max += 1 if use_morph_normals:
blender_shape_keys.append(ShapeKey( vertex_normals = blender_shape_key.normals_vertex_get()
blender_shape_key, polygon_normals = blender_shape_key.normals_polygon_get()
blender_shape_key.normals_vertex_get(), # calculate vertex normals for this shape key else:
blender_shape_key.normals_polygon_get())) # calculate polygon normals for this shape key vertex_normals = None
polygon_normals = None
shape_keys.append(ShapeKey(
blender_shape_key,
vertex_normals,
polygon_normals,
))
armature = None
if modifiers is not None:
modifiers_dict = {m.type: m for m in modifiers}
if "ARMATURE" in modifiers_dict:
modifier = modifiers_dict["ARMATURE"]
armature = modifier.object
use_materials = export_settings[gltf2_blender_export_keys.MATERIALS]
# #
# Convert polygon to primitive indices and eliminate invalid ones. Assign to material. # Gather the verts and indices for each primitive.
# #
for blender_polygon in blender_mesh.polygons:
export_color = True
# prims = {}
if export_settings['gltf_materials'] is False: for blender_polygon in blender_mesh.polygons:
primitive = material_idx_to_primitives[0] material_idx = -1
vertex_index_to_new_indices = material_map[0] if use_materials:
elif not blender_polygon.material_index in material_idx_to_primitives: material_idx = blender_polygon.material_index
primitive = material_idx_to_primitives[0]
vertex_index_to_new_indices = material_map[0] prim = prims.get(material_idx)
else: if not prim:
primitive = material_idx_to_primitives[blender_polygon.material_index] prim = Prim()
vertex_index_to_new_indices = material_map[blender_polygon.material_index] prims[material_idx] = prim
#
if use_normals:
attributes = primitive[ATTRIBUTES_ID] face_normal = None
if not (blender_polygon.use_smooth or blender_mesh.use_auto_smooth):
face_normal = blender_polygon.normal # Calc face normal/tangents
face_tangent = Vector((0.0, 0.0, 0.0)) face_normal = blender_polygon.normal
face_bitangent = Vector((0.0, 0.0, 0.0)) if use_tangents:
if use_tangents: face_tangent = Vector((0.0, 0.0, 0.0))
for loop_index in blender_polygon.loop_indices: face_bitangent = Vector((0.0, 0.0, 0.0))
temp_vertex = blender_mesh.loops[loop_index] for loop_index in blender_polygon.loop_indices:
face_tangent += temp_vertex.tangent loop = blender_mesh.loops[loop_index]
face_bitangent += temp_vertex.bitangent face_tangent += loop.tangent
face_bitangent += loop.bitangent
face_tangent.normalize() face_tangent.normalize()
face_bitangent.normalize() face_bitangent.normalize()
#
indices = primitive[INDICES_ID]
loop_index_list = [] loop_index_list = []
...@@ -335,7 +273,6 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert ...@@ -335,7 +273,6 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
triangles = tessellate_polygon((polyline,)) triangles = tessellate_polygon((polyline,))
for triangle in triangles: for triangle in triangles:
for triangle_index in triangle: for triangle_index in triangle:
loop_index_list.append(blender_polygon.loop_indices[triangle_index]) loop_index_list.append(blender_polygon.loop_indices[triangle_index])
else: else:
...@@ -343,366 +280,200 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert ...@@ -343,366 +280,200 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
for loop_index in loop_index_list: for loop_index in loop_index_list:
vertex_index = blender_mesh.loops[loop_index].vertex_index vertex_index = blender_mesh.loops[loop_index].vertex_index
vertex = blender_mesh.vertices[vertex_index]
if vertex_index_to_new_indices.get(vertex_index) is None: # vert will be a tuple of all the vertex attributes.
vertex_index_to_new_indices[vertex_index] = [] # Used as cache key in prim.verts.
vert = (vertex_index,)
#
v = None
n = None
t = None
b = None
uvs = []
colors = []
joints = []
weights = []
target_positions = []
target_normals = []
target_tangents = []
vertex = blender_mesh.vertices[vertex_index] v = vertex.co
vert += ((v[0], v[1], v[2]),)
v = convert_swizzle_location(vertex.co, armature, blender_object, export_settings) if use_normals:
if blender_polygon.use_smooth or blender_mesh.use_auto_smooth: if face_normal is None:
if blender_mesh.has_custom_normals: if blender_mesh.has_custom_normals:
n = convert_swizzle_normal(blender_mesh.loops[loop_index].normal, armature, blender_object, export_settings) n = blender_mesh.loops[loop_index].normal
else:
n = vertex.normal
if use_tangents:
t = blender_mesh.loops[loop_index].tangent
b = blender_mesh.loops[loop_index].bitangent
else: else:
n = convert_swizzle_normal(vertex.normal, armature, blender_object, export_settings) n = face_normal
if use_tangents: if use_tangents:
t = convert_swizzle_tangent(blender_mesh.loops[loop_index].tangent, armature, blender_object, export_settings) t = face_tangent
b = convert_swizzle_location(blender_mesh.loops[loop_index].bitangent, armature, blender_object, export_settings) b = face_bitangent
else: vert += ((n[0], n[1], n[2]),)
n = convert_swizzle_normal(face_normal, armature, blender_object, export_settings)
if use_tangents: if use_tangents:
t = convert_swizzle_tangent(face_tangent, armature, blender_object, export_settings) vert += ((t[0], t[1], t[2]),)
b = convert_swizzle_location(face_bitangent, armature, blender_object, export_settings) vert += ((b[0], b[1], b[2]),)
# TODO: store just bitangent_sign in vert, not whole bitangent?
if use_tangents:
tv = Vector((t[0], t[1], t[2])) for tex_coord_index in range(0, tex_coord_max):
bv = Vector((b[0], b[1], b[2])) uv = blender_mesh.uv_layers[tex_coord_index].data[loop_index].uv
nv = Vector((n[0], n[1], n[2])) uv = (uv.x, 1.0 - uv.y)
vert += (uv,)
if (nv.cross(tv)).dot(bv) < 0.0:
t[3] = -1.0 for color_index in range(0, color_max):
color = blender_mesh.vertex_colors[color_index].data[loop_index].color
if blender_mesh.uv_layers.active: col = (
for tex_coord_index in range(0, tex_coord_max): color_srgb_to_scene_linear(color[0]),
uv = blender_mesh.uv_layers[tex_coord_index].data[loop_index].uv color_srgb_to_scene_linear(color[1]),
uvs.append([uv.x, 1.0 - uv.y]) color_srgb_to_scene_linear(color[2]),
color[3],
# )
vert += (col,)
if color_max > 0 and export_color:
for color_index in range(0, color_max): if bone_max:
color_name = COLOR_PREFIX + str(color_index) bones = []
color = vertex_colors[color_name].data[loop_index].color if vertex.groups:
colors.append([ for group_element in vertex.groups:
color_srgb_to_scene_linear(color[0]), weight = group_element.weight
color_srgb_to_scene_linear(color[1]), if weight <= 0.0:
color_srgb_to_scene_linear(color[2]),
color[3]
])
#
bone_count = 0
# Skin must be ignored if the object is parented to a bone of the armature
# (This creates an infinite recursive error)
# So ignoring skin in that case
if blender_object and blender_object.parent_type == "BONE" and blender_object.parent.name == armature.name:
bone_max = 0 # joints & weights will be ignored in following code
else:
# Manage joints & weights
if blender_vertex_groups is not None and vertex.groups is not None and len(vertex.groups) > 0 and export_settings[gltf2_blender_export_keys.SKINS]:
joint = []
weight = []
vertex_groups = vertex.groups
if not export_settings['gltf_all_vertex_influences']:
# sort groups by weight descending
vertex_groups = sorted(vertex.groups, key=attrgetter('weight'), reverse=True)
for group_element in vertex_groups:
if len(joint) == 4:
bone_count += 1
joints.append(joint)
weights.append(weight)
joint = []
weight = []
#
joint_weight = group_element.weight
if joint_weight <= 0.0:
continue continue
try:
# joint = group_to_joint[group_element.group]
except Exception:
vertex_group_index = group_element.group
if vertex_group_index < 0 or vertex_group_index >= len(blender_vertex_groups):
continue continue
vertex_group_name = blender_vertex_groups[vertex_group_index].name if joint is None:
continue
joint_index = None bones.append((joint, weight))
bones.sort(key=lambda x: x[1], reverse=True)
if armature: bones = tuple(bones)
skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings) vert += (bones,)
for index, j in enumerate(skin.joints):
if j.name == vertex_group_name:
joint_index = index
break
#
if joint_index is not None:
joint.append(joint_index)
weight.append(joint_weight)
if len(joint) > 0:
bone_count += 1
for fill in range(0, 4 - len(joint)):
joint.append(0)
weight.append(0.0)
joints.append(joint)
weights.append(weight)
for fill in range(0, bone_max - bone_count):
joints.append([0, 0, 0, 0])
weights.append([0.0, 0.0, 0.0, 0.0])
#
if morph_max > 0 and export_settings[gltf2_blender_export_keys.MORPH]:
for morph_index in range(0, morph_max):
blender_shape_key = blender_shape_keys[morph_index]
v_morph = convert_swizzle_location(blender_shape_key.shape_key.data[vertex_index].co,
armature, blender_object,
export_settings)
# Store delta.
v_morph -= v
target_positions.append(v_morph)
#
n_morph = None for shape_key in shape_keys:
v_morph = shape_key.shape_key.data[vertex_index].co
v_morph = v_morph - v # store delta
vert += ((v_morph[0], v_morph[1], v_morph[2]),)
if use_morph_normals:
if blender_polygon.use_smooth: if blender_polygon.use_smooth:
temp_normals = blender_shape_key.vertex_normals normals = shape_key.vertex_normals
n_morph = (temp_normals[vertex_index * 3 + 0], temp_normals[vertex_index * 3 + 1], n_morph = Vector((
temp_normals[vertex_index * 3 + 2]) normals[vertex_index * 3 + 0],
normals[vertex_index * 3 + 1],
normals[vertex_index * 3 + 2],
))
else: else:
temp_normals = blender_shape_key.polygon_normals normals = shape_key.polygon_normals
n_morph = ( n_morph = Vector((
temp_normals[blender_polygon.index * 3 + 0], temp_normals[blender_polygon.index * 3 + 1], normals[blender_polygon.index * 3 + 0],
temp_normals[blender_polygon.index * 3 + 2]) normals[blender_polygon.index * 3 + 1],
normals[blender_polygon.index * 3 + 2],
n_morph = convert_swizzle_normal(Vector(n_morph), armature, blender_object, export_settings) ))
n_morph = n_morph - n # store delta
# Store delta. vert += ((n_morph[0], n_morph[1], n_morph[2]),)
n_morph -= n
vert_idx = prim.verts.setdefault(vert, len(prim.verts))
target_normals.append(n_morph) prim.indices.append(vert_idx)
#
if use_tangents:
rotation = n_morph.rotation_difference(n)
t_morph = Vector((t[0], t[1], t[2]))
t_morph.rotate(rotation) #
# Put the verts into attribute arrays.
target_tangents.append(t_morph) #
#
#
create = True
for current_new_index in vertex_index_to_new_indices[vertex_index]: result_primitives = []
found = True
for i in range(0, 3): for material_idx, prim in prims.items():
if attributes[POSITION_ATTRIBUTE][current_new_index * 3 + i] != v[i]: if not prim.indices:
found = False continue
break
if attributes[NORMAL_ATTRIBUTE][current_new_index * 3 + i] != n[i]: vs = []
found = False ns = []
break ts = []
uvs = [[] for _ in range(tex_coord_max)]
cols = [[] for _ in range(color_max)]
joints = [[] for _ in range(bone_max)]
weights = [[] for _ in range(bone_max)]
vs_morph = [[] for _ in shape_keys]
ns_morph = [[] for _ in shape_keys]
ts_morph = [[] for _ in shape_keys]
for vert in prim.verts.keys():
i = 0
i += 1 # skip over Blender mesh index
v = vert[i]
i += 1
v = convert_swizzle_location(v, armature, blender_object, export_settings)
vs.extend(v)
if use_normals:
n = vert[i]
i += 1
n = convert_swizzle_normal(n, armature, blender_object, export_settings)
ns.extend(n)
if use_tangents: if use_tangents:
for i in range(0, 4): t = vert[i]
if attributes[TANGENT_ATTRIBUTE][current_new_index * 4 + i] != t[i]: i += 1
found = False t = convert_swizzle_tangent(t, armature, blender_object, export_settings)
break ts.extend(t)
if not found: b = vert[i]
continue i += 1
b = convert_swizzle_tangent(b, armature, blender_object, export_settings)
for tex_coord_index in range(0, tex_coord_max): b_sign = -1.0 if (Vector(n).cross(Vector(t))).dot(Vector(b)) < 0.0 else 1.0
uv = uvs[tex_coord_index] ts.append(b_sign)
tex_coord_id = TEXCOORD_PREFIX + str(tex_coord_index) for tex_coord_index in range(0, tex_coord_max):
for i in range(0, 2): uv = vert[i]
if attributes[tex_coord_id][current_new_index * 2 + i] != uv[i]: i += 1
found = False uvs[tex_coord_index].extend(uv)
break
for color_index in range(0, color_max):
if export_color: col = vert[i]
for color_index in range(0, color_max): i += 1
color = colors[color_index] cols[color_index].extend(col)
color_id = COLOR_PREFIX + str(color_index) if bone_max:
for i in range(0, 3): bones = vert[i]
# Alpha is always 1.0 - see above. i += 1
current_color = attributes[color_id][current_new_index * 4 + i] for j in range(0, 4 * bone_max):
if color_srgb_to_scene_linear(current_color) != color[i]: if j < len(bones):
found = False joint, weight = bones[j]
break else:
joint, weight = 0, 0.0
if export_settings[gltf2_blender_export_keys.SKINS]: joints[j//4].append(joint)
for bone_index in range(0, bone_max): weights[j//4].append(weight)
joint = joints[bone_index]
weight = weights[bone_index] for shape_key_index in range(0, len(shape_keys)):
v_morph = vert[i]
joint_id = JOINTS_PREFIX + str(bone_index) i += 1
weight_id = WEIGHTS_PREFIX + str(bone_index) v_morph = convert_swizzle_location(v_morph, armature, blender_object, export_settings)
for i in range(0, 4): vs_morph[shape_key_index].extend(v_morph)
if attributes[joint_id][current_new_index * 4 + i] != joint[i]:
found = False if use_morph_normals:
break n_morph = vert[i]
if attributes[weight_id][current_new_index * 4 + i] != weight[i]: i += 1
found = False n_morph = convert_swizzle_normal(n_morph, armature, blender_object, export_settings)
break ns_morph[shape_key_index].extend(n_morph)
if export_settings[gltf2_blender_export_keys.MORPH]: if use_morph_tangents:
for morph_index in range(0, morph_max): rotation = n_morph.rotation_difference(n)
target_position = target_positions[morph_index] t_morph = Vector(t)
target_normal = target_normals[morph_index] t_morph.rotate(rotation)
if use_tangents: ts_morph[shape_key_index].extend(t_morph)
target_tangent = target_tangents[morph_index]
attributes = {}
target_position_id = MORPH_POSITION_PREFIX + str(morph_index) attributes['POSITION'] = vs
target_normal_id = MORPH_NORMAL_PREFIX + str(morph_index) if ns: attributes['NORMAL'] = ns
target_tangent_id = MORPH_TANGENT_PREFIX + str(morph_index) if ts: attributes['TANGENT'] = ts
for i in range(0, 3): for i, uv in enumerate(uvs): attributes['TEXCOORD_%d' % i] = uv
if attributes[target_position_id][current_new_index * 3 + i] != target_position[i]: for i, col in enumerate(cols): attributes['COLOR_%d' % i] = col
found = False for i, js in enumerate(joints): attributes['JOINTS_%d' % i] = js
break for i, ws in enumerate(weights): attributes['WEIGHTS_%d' % i] = ws
if attributes[target_normal_id][current_new_index * 3 + i] != target_normal[i]: for i, vm in enumerate(vs_morph): attributes['MORPH_POSITION_%d' % i] = vm
found = False for i, nm in enumerate(ns_morph): attributes['MORPH_NORMAL_%d' % i] = nm
break for i, tm in enumerate(ts_morph): attributes['MORPH_TANGENT_%d' % i] = tm
if use_tangents:
if attributes[target_tangent_id][current_new_index * 3 + i] != target_tangent[i]: result_primitives.append({
found = False 'attributes': attributes,
break 'indices': prim.indices,
'material': material_idx,
if found: })
indices.append(current_new_index)
print_console('INFO', 'Primitives created: %d' % len(result_primitives))
create = False
break
if not create:
continue
new_index = 0
if primitive.get('max_index') is not None:
new_index = primitive['max_index'] + 1
primitive['max_index'] = new_index
vertex_index_to_new_indices[vertex_index].append(new_index)
#
#
indices.append(new_index)
#
attributes[POSITION_ATTRIBUTE].extend(v)
attributes[NORMAL_ATTRIBUTE].extend(n)
if use_tangents:
attributes[TANGENT_ATTRIBUTE].extend(t)
if blender_mesh.uv_layers.active:
for tex_coord_index in range(0, tex_coord_max):
tex_coord_id = TEXCOORD_PREFIX + str(tex_coord_index)
if attributes.get(tex_coord_id) is None:
attributes[tex_coord_id] = []
attributes[tex_coord_id].extend(uvs[tex_coord_index])
if export_color:
for color_index in range(0, color_max):
color_id = COLOR_PREFIX + str(color_index)
if attributes.get(color_id) is None:
attributes[color_id] = []
attributes[color_id].extend(colors[color_index])
if export_settings[gltf2_blender_export_keys.SKINS]:
for bone_index in range(0, bone_max):
joint_id = JOINTS_PREFIX + str(bone_index)
if attributes.get(joint_id) is None:
attributes[joint_id] = []
attributes[joint_id].extend(joints[bone_index])
weight_id = WEIGHTS_PREFIX + str(bone_index)
if attributes.get(weight_id) is None:
attributes[weight_id] = []
attributes[weight_id].extend(weights[bone_index])
if export_settings[gltf2_blender_export_keys.MORPH]:
for morph_index in range(0, morph_max):
target_position_id = MORPH_POSITION_PREFIX + str(morph_index)
if attributes.get(target_position_id) is None:
attributes[target_position_id] = []
attributes[target_position_id].extend(target_positions[morph_index])
target_normal_id = MORPH_NORMAL_PREFIX + str(morph_index)
if attributes.get(target_normal_id) is None:
attributes[target_normal_id] = []
attributes[target_normal_id].extend(target_normals[morph_index])
if use_tangents:
target_tangent_id = MORPH_TANGENT_PREFIX + str(morph_index)
if attributes.get(target_tangent_id) is None:
attributes[target_tangent_id] = []
attributes[target_tangent_id].extend(target_tangents[morph_index])
#
# Add non-empty primitives
#
result_primitives = [
primitive
for primitive in material_idx_to_primitives.values()
if len(primitive[INDICES_ID]) != 0
]
print_console('INFO', 'Primitives created: ' + str(len(result_primitives)))
return result_primitives return result_primitives
...@@ -79,7 +79,8 @@ def pbr_specular_glossiness(mh): ...@@ -79,7 +79,8 @@ def pbr_specular_glossiness(mh):
) )
if mh.pymat.occlusion_texture is not None: if mh.pymat.occlusion_texture is not None:
node = make_settings_node(mh, location=(610, -1060)) node = make_settings_node(mh)
node.location = (610, -1060)
occlusion( occlusion(
mh, mh,
location=(510, -970), location=(510, -970),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment