Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Duroure <julien.duroure@gmail.com>2020-07-10 13:49:27 +0300
committerJulien Duroure <julien.duroure@gmail.com>2020-07-10 13:49:27 +0300
commit01186b0df9c54eefea95cf8861b8f5fb9960ddf3 (patch)
tree485236cebefa16d1b1264bfe8c81e67f08948725
parent955332bf02a7e5c7c17082eddeff9820783e99c2 (diff)
gltf exporter: Fix T76677 primitive extraction code refactoring
-rwxr-xr-xio_scene_gltf2/__init__.py2
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_extract.py813
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py3
3 files changed, 295 insertions, 523 deletions
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 3ea1ce11..2e19cbeb 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,7 +15,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'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),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index e2d224ce..5fe719ee 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -18,40 +18,22 @@
from mathutils import Vector, Quaternion, Matrix
from mathutils.geometry import tessellate_polygon
-from operator import attrgetter
from . import gltf2_blender_export_keys
from ...io.com.gltf2_io_debug import print_console
from ...io.com.gltf2_io_color_management import color_srgb_to_scene_linear
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
#
+class Prim:
+ def __init__(self):
+ self.verts = {}
+ self.indices = []
+
class ShapeKey:
def __init__(self, shape_key, vertex_normals, polygon_normals):
self.shape_key = shape_key
@@ -110,17 +92,17 @@ def convert_swizzle_tangent(tan, armature, blender_object, export_settings):
if (not armature) or (not blender_object):
# Classic case. Mesh is not skined, no need to apply armature transfoms on vertices / normals / tangents
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:
- return Vector((tan[0], tan[1], tan[2], 1.0))
+ return Vector((tan[0], tan[1], tan[2]))
else:
# Mesh is skined, we have to apply armature transforms on data
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]:
- 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:
- 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):
"""
@@ -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):
"""
Extract primitives from a mesh. Polygons are triangulated and sorted by material.
-
- 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.
+ Vertices in multiple faces get split up as necessary.
"""
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.')
-
#
-
- material_map = {}
-
+ # First, decide what attributes to gather (eg. how many COLOR_n, etc.)
+ # 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] = []
- #
- # Directory of materials with its primitive.
- #
- no_material_primitives = {
- MATERIAL_ID: 0,
- INDICES_ID: [],
- ATTRIBUTES_ID: no_material_attributes
- }
+ use_normals = export_settings[gltf2_blender_export_keys.NORMALS]
+ if use_normals:
+ 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()
- material_idx_to_primitives = {0: no_material_primitives}
-
- #
-
- vertex_index_to_new_indices = {}
-
- material_map[0] = vertex_index_to_new_indices
-
- #
- # 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
+ 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:
+ blender_mesh.calc_tangents()
+ use_tangents = True
+ except Exception:
+ print_console('WARNING', 'Could not calculate tangents. Please try to triangulate the mesh first.')
tex_coord_max = 0
- if blender_mesh.uv_layers.active:
- tex_coord_max = len(blender_mesh.uv_layers)
-
- #
-
- vertex_colors = {}
+ if export_settings[gltf2_blender_export_keys.TEX_COORDS]:
+ if blender_mesh.uv_layers.active:
+ tex_coord_max = len(blender_mesh.uv_layers)
- color_index = 0
- for vertex_color in blender_mesh.vertex_colors:
- vertex_color_name = COLOR_PREFIX + str(color_index)
- vertex_colors[vertex_color_name] = vertex_color
+ color_max = 0
+ if export_settings[gltf2_blender_export_keys.COLORS]:
+ color_max = len(blender_mesh.vertex_colors)
- color_index += 1
- if color_index >= GLTF_MAX_COLORS:
- break
- color_max = color_index
-
- #
-
- bone_max = 0
- for blender_polygon in blender_mesh.polygons:
- for loop_index in blender_polygon.loop_indices:
- vertex_index = blender_mesh.loops[loop_index].vertex_index
- bones_count = len(blender_mesh.vertices[vertex_index].groups)
- if bones_count > 0:
- if bones_count % 4 == 0:
- bones_count -= 1
- bone_max = max(bone_max, bones_count // 4 + 1)
-
- #
-
- morph_max = 0
-
- blender_shape_keys = []
-
- if blender_mesh.shape_keys is not None:
+ bone_max = 0 # number of JOINTS_n sets needed (1 set = 4 influences)
+ armature = None
+ if blender_vertex_groups and export_settings[gltf2_blender_export_keys.SKINS]:
+ 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
+
+ # 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
+ is_child_of_arma = (
+ armature and
+ blender_object and
+ blender_object.parent_type == "BONE" and
+ blender_object.parent.name == armature.name
+ )
+ if is_child_of_arma:
+ armature = None
+
+ if armature:
+ skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
+ 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:
- if blender_shape_key != blender_shape_key.relative_key:
- if blender_shape_key.mute is False:
- morph_max += 1
- blender_shape_keys.append(ShapeKey(
- blender_shape_key,
- blender_shape_key.normals_vertex_get(), # calculate vertex normals for this shape key
- blender_shape_key.normals_polygon_get())) # calculate polygon normals for this shape key
-
+ if blender_shape_key == blender_shape_key.relative_key or blender_shape_key.mute:
+ continue
+ if use_morph_normals:
+ vertex_normals = blender_shape_key.normals_vertex_get()
+ polygon_normals = blender_shape_key.normals_polygon_get()
+ else:
+ 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:
- primitive = material_idx_to_primitives[0]
- vertex_index_to_new_indices = material_map[0]
- elif not blender_polygon.material_index in material_idx_to_primitives:
- primitive = material_idx_to_primitives[0]
- vertex_index_to_new_indices = material_map[0]
- else:
- primitive = material_idx_to_primitives[blender_polygon.material_index]
- vertex_index_to_new_indices = material_map[blender_polygon.material_index]
- #
-
- attributes = primitive[ATTRIBUTES_ID]
-
- face_normal = blender_polygon.normal
- face_tangent = Vector((0.0, 0.0, 0.0))
- face_bitangent = Vector((0.0, 0.0, 0.0))
- if use_tangents:
- for loop_index in blender_polygon.loop_indices:
- temp_vertex = blender_mesh.loops[loop_index]
- face_tangent += temp_vertex.tangent
- face_bitangent += temp_vertex.bitangent
-
- face_tangent.normalize()
- face_bitangent.normalize()
-
- #
-
- indices = primitive[INDICES_ID]
+ for blender_polygon in blender_mesh.polygons:
+ material_idx = -1
+ if use_materials:
+ material_idx = blender_polygon.material_index
+
+ prim = prims.get(material_idx)
+ if not prim:
+ prim = Prim()
+ prims[material_idx] = prim
+
+ if use_normals:
+ face_normal = None
+ if not (blender_polygon.use_smooth or blender_mesh.use_auto_smooth):
+ # Calc face normal/tangents
+ face_normal = blender_polygon.normal
+ if use_tangents:
+ face_tangent = Vector((0.0, 0.0, 0.0))
+ face_bitangent = Vector((0.0, 0.0, 0.0))
+ for loop_index in blender_polygon.loop_indices:
+ loop = blender_mesh.loops[loop_index]
+ face_tangent += loop.tangent
+ face_bitangent += loop.bitangent
+ face_tangent.normalize()
+ face_bitangent.normalize()
loop_index_list = []
@@ -335,7 +273,6 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
triangles = tessellate_polygon((polyline,))
for triangle in triangles:
-
for triangle_index in triangle:
loop_index_list.append(blender_polygon.loop_indices[triangle_index])
else:
@@ -343,366 +280,200 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
for loop_index in loop_index_list:
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:
- vertex_index_to_new_indices[vertex_index] = []
-
- #
-
- v = None
- n = None
- t = None
- b = None
- uvs = []
- colors = []
- joints = []
- weights = []
-
- target_positions = []
- target_normals = []
- target_tangents = []
+ # vert will be a tuple of all the vertex attributes.
+ # Used as cache key in prim.verts.
+ vert = (vertex_index,)
- 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 blender_polygon.use_smooth or blender_mesh.use_auto_smooth:
- if blender_mesh.has_custom_normals:
- n = convert_swizzle_normal(blender_mesh.loops[loop_index].normal, armature, blender_object, export_settings)
+ if use_normals:
+ if face_normal is None:
+ if blender_mesh.has_custom_normals:
+ 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:
- n = convert_swizzle_normal(vertex.normal, armature, blender_object, export_settings)
- if use_tangents:
- t = convert_swizzle_tangent(blender_mesh.loops[loop_index].tangent, armature, blender_object, export_settings)
- b = convert_swizzle_location(blender_mesh.loops[loop_index].bitangent, armature, blender_object, export_settings)
- else:
- n = convert_swizzle_normal(face_normal, armature, blender_object, export_settings)
+ n = face_normal
+ if use_tangents:
+ t = face_tangent
+ b = face_bitangent
+ vert += ((n[0], n[1], n[2]),)
if use_tangents:
- t = convert_swizzle_tangent(face_tangent, armature, blender_object, export_settings)
- b = convert_swizzle_location(face_bitangent, armature, blender_object, export_settings)
-
- if use_tangents:
- tv = Vector((t[0], t[1], t[2]))
- bv = Vector((b[0], b[1], b[2]))
- nv = Vector((n[0], n[1], n[2]))
-
- if (nv.cross(tv)).dot(bv) < 0.0:
- t[3] = -1.0
-
- if blender_mesh.uv_layers.active:
- for tex_coord_index in range(0, tex_coord_max):
- uv = blender_mesh.uv_layers[tex_coord_index].data[loop_index].uv
- uvs.append([uv.x, 1.0 - uv.y])
-
- #
-
- if color_max > 0 and export_color:
- for color_index in range(0, color_max):
- color_name = COLOR_PREFIX + str(color_index)
- color = vertex_colors[color_name].data[loop_index].color
- colors.append([
- color_srgb_to_scene_linear(color[0]),
- color_srgb_to_scene_linear(color[1]),
- 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:
+ vert += ((t[0], t[1], t[2]),)
+ vert += ((b[0], b[1], b[2]),)
+ # TODO: store just bitangent_sign in vert, not whole bitangent?
+
+ for tex_coord_index in range(0, tex_coord_max):
+ uv = blender_mesh.uv_layers[tex_coord_index].data[loop_index].uv
+ uv = (uv.x, 1.0 - uv.y)
+ vert += (uv,)
+
+ for color_index in range(0, color_max):
+ color = blender_mesh.vertex_colors[color_index].data[loop_index].color
+ col = (
+ color_srgb_to_scene_linear(color[0]),
+ color_srgb_to_scene_linear(color[1]),
+ color_srgb_to_scene_linear(color[2]),
+ color[3],
+ )
+ vert += (col,)
+
+ if bone_max:
+ bones = []
+ if vertex.groups:
+ for group_element in vertex.groups:
+ weight = group_element.weight
+ if weight <= 0.0:
continue
-
- #
-
- vertex_group_index = group_element.group
-
- if vertex_group_index < 0 or vertex_group_index >= len(blender_vertex_groups):
+ try:
+ joint = group_to_joint[group_element.group]
+ except Exception:
continue
- vertex_group_name = blender_vertex_groups[vertex_group_index].name
-
- joint_index = None
-
- if armature:
- skin = gltf2_blender_gather_skins.gather_skin(armature, export_settings)
- 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)
-
- #
+ if joint is None:
+ continue
+ bones.append((joint, weight))
+ bones.sort(key=lambda x: x[1], reverse=True)
+ bones = tuple(bones)
+ vert += (bones,)
- 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:
- temp_normals = blender_shape_key.vertex_normals
- n_morph = (temp_normals[vertex_index * 3 + 0], temp_normals[vertex_index * 3 + 1],
- temp_normals[vertex_index * 3 + 2])
+ normals = shape_key.vertex_normals
+ n_morph = Vector((
+ normals[vertex_index * 3 + 0],
+ normals[vertex_index * 3 + 1],
+ normals[vertex_index * 3 + 2],
+ ))
else:
- temp_normals = blender_shape_key.polygon_normals
- n_morph = (
- temp_normals[blender_polygon.index * 3 + 0], temp_normals[blender_polygon.index * 3 + 1],
- temp_normals[blender_polygon.index * 3 + 2])
-
- n_morph = convert_swizzle_normal(Vector(n_morph), armature, blender_object, export_settings)
-
- # Store delta.
- n_morph -= n
-
- target_normals.append(n_morph)
-
- #
-
- if use_tangents:
- rotation = n_morph.rotation_difference(n)
-
- t_morph = Vector((t[0], t[1], t[2]))
+ normals = shape_key.polygon_normals
+ n_morph = Vector((
+ normals[blender_polygon.index * 3 + 0],
+ normals[blender_polygon.index * 3 + 1],
+ normals[blender_polygon.index * 3 + 2],
+ ))
+ n_morph = n_morph - n # store delta
+ vert += ((n_morph[0], n_morph[1], n_morph[2]),)
+
+ vert_idx = prim.verts.setdefault(vert, len(prim.verts))
+ prim.indices.append(vert_idx)
- t_morph.rotate(rotation)
-
- target_tangents.append(t_morph)
-
- #
- #
-
- create = True
+ #
+ # Put the verts into attribute arrays.
+ #
- for current_new_index in vertex_index_to_new_indices[vertex_index]:
- found = True
+ result_primitives = []
- for i in range(0, 3):
- if attributes[POSITION_ATTRIBUTE][current_new_index * 3 + i] != v[i]:
- found = False
- break
+ for material_idx, prim in prims.items():
+ if not prim.indices:
+ continue
- if attributes[NORMAL_ATTRIBUTE][current_new_index * 3 + i] != n[i]:
- found = False
- break
+ vs = []
+ ns = []
+ 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:
- for i in range(0, 4):
- if attributes[TANGENT_ATTRIBUTE][current_new_index * 4 + i] != t[i]:
- found = False
- break
-
- if not found:
- continue
-
- for tex_coord_index in range(0, tex_coord_max):
- uv = uvs[tex_coord_index]
-
- tex_coord_id = TEXCOORD_PREFIX + str(tex_coord_index)
- for i in range(0, 2):
- if attributes[tex_coord_id][current_new_index * 2 + i] != uv[i]:
- found = False
- break
-
- if export_color:
- for color_index in range(0, color_max):
- color = colors[color_index]
-
- color_id = COLOR_PREFIX + str(color_index)
- for i in range(0, 3):
- # Alpha is always 1.0 - see above.
- current_color = attributes[color_id][current_new_index * 4 + i]
- if color_srgb_to_scene_linear(current_color) != color[i]:
- found = False
- break
-
- if export_settings[gltf2_blender_export_keys.SKINS]:
- for bone_index in range(0, bone_max):
- joint = joints[bone_index]
- weight = weights[bone_index]
-
- joint_id = JOINTS_PREFIX + str(bone_index)
- weight_id = WEIGHTS_PREFIX + str(bone_index)
- for i in range(0, 4):
- if attributes[joint_id][current_new_index * 4 + i] != joint[i]:
- found = False
- break
- if attributes[weight_id][current_new_index * 4 + i] != weight[i]:
- found = False
- break
-
- if export_settings[gltf2_blender_export_keys.MORPH]:
- for morph_index in range(0, morph_max):
- target_position = target_positions[morph_index]
- target_normal = target_normals[morph_index]
- if use_tangents:
- target_tangent = target_tangents[morph_index]
-
- target_position_id = MORPH_POSITION_PREFIX + str(morph_index)
- target_normal_id = MORPH_NORMAL_PREFIX + str(morph_index)
- target_tangent_id = MORPH_TANGENT_PREFIX + str(morph_index)
- for i in range(0, 3):
- if attributes[target_position_id][current_new_index * 3 + i] != target_position[i]:
- found = False
- break
- if attributes[target_normal_id][current_new_index * 3 + i] != target_normal[i]:
- found = False
- break
- if use_tangents:
- if attributes[target_tangent_id][current_new_index * 3 + i] != target_tangent[i]:
- found = False
- break
-
- if found:
- indices.append(current_new_index)
-
- 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)))
+ t = vert[i]
+ i += 1
+ t = convert_swizzle_tangent(t, armature, blender_object, export_settings)
+ ts.extend(t)
+
+ b = vert[i]
+ i += 1
+ b = convert_swizzle_tangent(b, armature, blender_object, export_settings)
+ b_sign = -1.0 if (Vector(n).cross(Vector(t))).dot(Vector(b)) < 0.0 else 1.0
+ ts.append(b_sign)
+
+ for tex_coord_index in range(0, tex_coord_max):
+ uv = vert[i]
+ i += 1
+ uvs[tex_coord_index].extend(uv)
+
+ for color_index in range(0, color_max):
+ col = vert[i]
+ i += 1
+ cols[color_index].extend(col)
+
+ if bone_max:
+ bones = vert[i]
+ i += 1
+ for j in range(0, 4 * bone_max):
+ if j < len(bones):
+ joint, weight = bones[j]
+ else:
+ joint, weight = 0, 0.0
+ joints[j//4].append(joint)
+ weights[j//4].append(weight)
+
+ for shape_key_index in range(0, len(shape_keys)):
+ v_morph = vert[i]
+ i += 1
+ v_morph = convert_swizzle_location(v_morph, armature, blender_object, export_settings)
+ vs_morph[shape_key_index].extend(v_morph)
+
+ if use_morph_normals:
+ n_morph = vert[i]
+ i += 1
+ n_morph = convert_swizzle_normal(n_morph, armature, blender_object, export_settings)
+ ns_morph[shape_key_index].extend(n_morph)
+
+ if use_morph_tangents:
+ rotation = n_morph.rotation_difference(n)
+ t_morph = Vector(t)
+ t_morph.rotate(rotation)
+ ts_morph[shape_key_index].extend(t_morph)
+
+ attributes = {}
+ attributes['POSITION'] = vs
+ if ns: attributes['NORMAL'] = ns
+ if ts: attributes['TANGENT'] = ts
+ for i, uv in enumerate(uvs): attributes['TEXCOORD_%d' % i] = uv
+ for i, col in enumerate(cols): attributes['COLOR_%d' % i] = col
+ for i, js in enumerate(joints): attributes['JOINTS_%d' % i] = js
+ for i, ws in enumerate(weights): attributes['WEIGHTS_%d' % i] = ws
+ for i, vm in enumerate(vs_morph): attributes['MORPH_POSITION_%d' % i] = vm
+ for i, nm in enumerate(ns_morph): attributes['MORPH_NORMAL_%d' % i] = nm
+ for i, tm in enumerate(ts_morph): attributes['MORPH_TANGENT_%d' % i] = tm
+
+ result_primitives.append({
+ 'attributes': attributes,
+ 'indices': prim.indices,
+ 'material': material_idx,
+ })
+
+ print_console('INFO', 'Primitives created: %d' % len(result_primitives))
return result_primitives
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
index ce5e1aed..bb1bf272 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
@@ -79,7 +79,8 @@ def pbr_specular_glossiness(mh):
)
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(
mh,
location=(510, -970),