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:
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py')
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py186
1 files changed, 66 insertions, 120 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
index 1af588b9..ce2f9a59 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
@@ -10,32 +10,34 @@ from io_scene_gltf2.io.com import gltf2_io_debug
from io_scene_gltf2.io.exp import gltf2_io_binary_data
+
def gather_primitive_attributes(blender_primitive, export_settings):
"""
- Gathers the attributes, such as POSITION, NORMAL, TANGENT from a blender primitive.
+ Gathers the attributes, such as POSITION, NORMAL, TANGENT, and all custom attributes from a blender primitive
:return: a dictionary of attributes
"""
attributes = {}
- attributes.update(__gather_position(blender_primitive, export_settings))
- attributes.update(__gather_normal(blender_primitive, export_settings))
- attributes.update(__gather_tangent(blender_primitive, export_settings))
- attributes.update(__gather_texcoord(blender_primitive, export_settings))
- attributes.update(__gather_colors(blender_primitive, export_settings))
- attributes.update(__gather_skins(blender_primitive, export_settings))
- return attributes
+ # loop on each attribute extracted
+ # for skinning, all linked attributes (WEIGHTS_ and JOINTS_) need to be calculated
+ # in one shot (because of normalization), so we need to check that it is called only once.
-def array_to_accessor(array, component_type, data_type, include_max_and_min=False):
- dtype = gltf2_io_constants.ComponentType.to_numpy_dtype(component_type)
- num_elems = gltf2_io_constants.DataType.num_elements(data_type)
+ skin_done = False
+
+ for attribute in blender_primitive["attributes"]:
+ if (attribute.startswith("JOINTS_") or attribute.startswith("WEIGHTS_")) and skin_done is True:
+ continue
+ if attribute.startswith("MORPH_"):
+ continue # Target for morphs will be managed later
+ attributes.update(__gather_attribute(blender_primitive, attribute, export_settings))
+ if (attribute.startswith("JOINTS_") or attribute.startswith("WEIGHTS_")):
+ skin_done = True
+
+ return attributes
- if type(array) is not np.ndarray:
- array = np.array(array, dtype=dtype)
- array = array.reshape(len(array) // num_elems, num_elems)
- assert array.dtype == dtype
- assert array.shape[1] == num_elems
+def array_to_accessor(array, component_type, data_type, include_max_and_min=False):
amax = None
amin = None
@@ -58,109 +60,6 @@ def array_to_accessor(array, component_type, data_type, include_max_and_min=Fals
type=data_type,
)
-
-def __gather_position(blender_primitive, export_settings):
- position = blender_primitive["attributes"]["POSITION"]
- return {
- "POSITION": array_to_accessor(
- position,
- component_type=gltf2_io_constants.ComponentType.Float,
- data_type=gltf2_io_constants.DataType.Vec3,
- include_max_and_min=True
- )
- }
-
-
-def __gather_normal(blender_primitive, export_settings):
- if not export_settings[gltf2_blender_export_keys.NORMALS]:
- return {}
- if 'NORMAL' not in blender_primitive["attributes"]:
- return {}
- normal = blender_primitive["attributes"]['NORMAL']
- return {
- "NORMAL": array_to_accessor(
- normal,
- component_type=gltf2_io_constants.ComponentType.Float,
- data_type=gltf2_io_constants.DataType.Vec3,
- )
- }
-
-
-def __gather_tangent(blender_primitive, export_settings):
- if not export_settings[gltf2_blender_export_keys.TANGENTS]:
- return {}
- if 'TANGENT' not in blender_primitive["attributes"]:
- return {}
- tangent = blender_primitive["attributes"]['TANGENT']
- return {
- "TANGENT": array_to_accessor(
- tangent,
- component_type=gltf2_io_constants.ComponentType.Float,
- data_type=gltf2_io_constants.DataType.Vec4,
- )
- }
-
-
-def __gather_texcoord(blender_primitive, export_settings):
- attributes = {}
- if export_settings[gltf2_blender_export_keys.TEX_COORDS]:
- tex_coord_index = 0
- tex_coord_id = 'TEXCOORD_' + str(tex_coord_index)
- while blender_primitive["attributes"].get(tex_coord_id) is not None:
- tex_coord = blender_primitive["attributes"][tex_coord_id]
- attributes[tex_coord_id] = array_to_accessor(
- tex_coord,
- component_type=gltf2_io_constants.ComponentType.Float,
- data_type=gltf2_io_constants.DataType.Vec2,
- )
- tex_coord_index += 1
- tex_coord_id = 'TEXCOORD_' + str(tex_coord_index)
- return attributes
-
-
-def __gather_colors(blender_primitive, export_settings):
- attributes = {}
- if export_settings[gltf2_blender_export_keys.COLORS]:
- color_index = 0
- color_id = 'COLOR_' + str(color_index)
- while blender_primitive["attributes"].get(color_id) is not None:
- colors = blender_primitive["attributes"][color_id]["data"]
-
- if type(colors) is not np.ndarray:
- colors = np.array(colors, dtype=np.float32)
- colors = colors.reshape(len(colors) // 4, 4)
-
- if blender_primitive["attributes"][color_id]["norm"] is True:
- comp_type = gltf2_io_constants.ComponentType.UnsignedShort
-
- # Convert to normalized ushorts
- colors *= 65535
- colors += 0.5 # bias for rounding
- colors = colors.astype(np.uint16)
-
- else:
- comp_type = gltf2_io_constants.ComponentType.Float
-
- attributes[color_id] = gltf2_io.Accessor(
- buffer_view=gltf2_io_binary_data.BinaryData(colors.tobytes(), gltf2_io_constants.BufferViewTarget.ARRAY_BUFFER),
- byte_offset=None,
- component_type=comp_type,
- count=len(colors),
- extensions=None,
- extras=None,
- max=None,
- min=None,
- name=None,
- normalized=blender_primitive["attributes"][color_id]["norm"],
- sparse=None,
- type=gltf2_io_constants.DataType.Vec4,
- )
-
- color_index += 1
- color_id = 'COLOR_' + str(color_index)
- return attributes
-
-
def __gather_skins(blender_primitive, export_settings):
attributes = {}
@@ -208,8 +107,10 @@ def __gather_skins(blender_primitive, export_settings):
component_type = gltf2_io_constants.ComponentType.UnsignedShort
if max(internal_joint) < 256:
component_type = gltf2_io_constants.ComponentType.UnsignedByte
+ joints = np.array(internal_joint, dtype= gltf2_io_constants.ComponentType.to_numpy_dtype(component_type))
+ joints = joints.reshape(-1, 4)
joint = array_to_accessor(
- internal_joint,
+ joints,
component_type,
data_type=gltf2_io_constants.DataType.Vec4,
)
@@ -236,3 +137,48 @@ def __gather_skins(blender_primitive, export_settings):
attributes[weight_id] = weight
return attributes
+
+
+def __gather_attribute(blender_primitive, attribute, export_settings):
+ data = blender_primitive["attributes"][attribute]
+
+
+ include_max_and_mins = {
+ "POSITION": True
+ }
+
+ if (attribute.startswith("_COLOR") or attribute.startswith("COLOR_")) and blender_primitive["attributes"][attribute]['component_type'] == gltf2_io_constants.ComponentType.UnsignedShort:
+ # Byte Color vertex color, need to normalize
+
+ data['data'] *= 65535
+ data['data'] += 0.5 # bias for rounding
+ data['data'] = data['data'].astype(np.uint16)
+
+ return { attribute : gltf2_io.Accessor(
+ buffer_view=gltf2_io_binary_data.BinaryData(data['data'].tobytes(), gltf2_io_constants.BufferViewTarget.ARRAY_BUFFER),
+ byte_offset=None,
+ component_type=data['component_type'],
+ count=len(data['data']),
+ extensions=None,
+ extras=None,
+ max=None,
+ min=None,
+ name=None,
+ normalized=True,
+ sparse=None,
+ type=data['data_type'],
+ )
+ }
+
+ elif attribute.startswith("JOINTS_") or attribute.startswith("WEIGHTS_"):
+ return __gather_skins(blender_primitive, export_settings)
+
+ else:
+ return {
+ attribute: array_to_accessor(
+ data['data'],
+ component_type=data['component_type'],
+ data_type=data['data_type'],
+ include_max_and_min=include_max_and_mins.get(attribute, False)
+ )
+ }