Skip to content

Commit

Permalink
Merge branch 'blender-v4.3-release'
Browse files Browse the repository at this point in the history
  • Loading branch information
julienduroure committed Oct 16, 2024
2 parents 79ddc42 + eaf661c commit 628c972
Show file tree
Hide file tree
Showing 106 changed files with 3,022 additions and 1,833 deletions.
259 changes: 147 additions & 112 deletions addons/io_scene_gltf2/__init__.py

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions addons/io_scene_gltf2/blender/com/blender_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
BLENDER_GLTF_SPECIAL_COLLECTION = "glTF_not_exported"

LIGHTS = {
"POINT": "point",
"SUN": "directional",
"SPOT": "spot"
}
"POINT": "point",
"SUN": "directional",
"SPOT": "spot"
}
29 changes: 21 additions & 8 deletions addons/io_scene_gltf2/blender/com/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
# Industry convention, biological peak at 555nm, scientific standard as part of SI candela definition.



# This means use the inverse of the TRS transform.
def inverted_trs_mapping_node(mapping_transform):
offset = mapping_transform["offset"]
Expand All @@ -36,13 +35,15 @@ def inverted_trs_mapping_node(mapping_transform):
return None

new_offset = Matrix.Rotation(-rotation, 3, 'Z') @ Vector((-offset[0], -offset[1], 1))
new_offset[0] /= scale[0]; new_offset[1] /= scale[1]
new_offset[0] /= scale[0]
new_offset[1] /= scale[1]
return {
"offset": new_offset[0:2],
"rotation": -rotation,
"scale": [1/scale[0], 1/scale[1]],
"scale": [1 / scale[0], 1 / scale[1]],
}


def texture_transform_blender_to_gltf(mapping_transform):
"""
Converts the offset/rotation/scale from a Mapping node applied in Blender's
Expand All @@ -60,6 +61,7 @@ def texture_transform_blender_to_gltf(mapping_transform):
'scale': [scale[0], scale[1]],
}


def texture_transform_gltf_to_blender(texture_transform):
"""
Converts a KHR_texture_transform into the equivalent offset/rotation/scale
Expand All @@ -77,6 +79,7 @@ def texture_transform_gltf_to_blender(texture_transform):
'scale': [scale[0], scale[1]],
}


def get_target(property):
return {
"delta_location": "translation",
Expand All @@ -91,6 +94,7 @@ def get_target(property):
"value": "weights"
}.get(property, None)


def get_component_type(attribute_component_type):
return {
"INT8": gltf2_io_constants.ComponentType.Float,
Expand All @@ -101,19 +105,21 @@ def get_component_type(attribute_component_type):
"FLOAT_VECTOR_4": gltf2_io_constants.ComponentType.Float,
"QUATERNION": gltf2_io_constants.ComponentType.Float,
"FLOAT4X4": gltf2_io_constants.ComponentType.Float,
"INT": gltf2_io_constants.ComponentType.Float, # No signed Int in glTF accessor
"INT": gltf2_io_constants.ComponentType.Float, # No signed Int in glTF accessor
"FLOAT": gltf2_io_constants.ComponentType.Float,
"BOOLEAN": gltf2_io_constants.ComponentType.Float,
"UNSIGNED_BYTE": gltf2_io_constants.ComponentType.UnsignedByte
}.get(attribute_component_type)


def get_channel_from_target(target):
return {
"rotation": "rotation_quaternion",
"translation": "location",
"scale": "scale"
}.get(target)


def get_data_type(attribute_component_type):
return {
"INT8": gltf2_io_constants.DataType.Scalar,
Expand All @@ -129,6 +135,7 @@ def get_data_type(attribute_component_type):
"BOOLEAN": gltf2_io_constants.DataType.Scalar,
}.get(attribute_component_type)


def get_data_length(attribute_component_type):
return {
"INT8": 1,
Expand All @@ -144,6 +151,7 @@ def get_data_length(attribute_component_type):
"BOOLEAN": 1
}.get(attribute_component_type)


def get_numpy_type(attribute_component_type):
return {
"INT8": np.float32,
Expand All @@ -154,17 +162,18 @@ def get_numpy_type(attribute_component_type):
"FLOAT_VECTOR_4": np.float32,
"QUATERNION": np.float32,
"FLOAT4X4": np.float32,
"INT": np.float32, #signed integer are not supported by glTF
"INT": np.float32, # signed integer are not supported by glTF
"FLOAT": np.float32,
"BOOLEAN": np.float32,
"UNSIGNED_BYTE": np.uint8,
}.get(attribute_component_type)


def get_attribute_type(component_type, data_type):
if gltf2_io_constants.DataType.num_elements(data_type) == 1:
return {
gltf2_io_constants.ComponentType.Float: "FLOAT",
gltf2_io_constants.ComponentType.UnsignedByte: "INT" # What is the best for compatibility?
gltf2_io_constants.ComponentType.UnsignedByte: "INT" # What is the best for compatibility?
}.get(component_type, None)
elif gltf2_io_constants.DataType.num_elements(data_type) == 2:
return {
Expand All @@ -178,7 +187,7 @@ def get_attribute_type(component_type, data_type):
return {
gltf2_io_constants.ComponentType.Float: "FLOAT_COLOR",
gltf2_io_constants.ComponentType.UnsignedShort: "BYTE_COLOR",
gltf2_io_constants.ComponentType.UnsignedByte: "BYTE_COLOR" # What is the best for compatibility?
gltf2_io_constants.ComponentType.UnsignedByte: "BYTE_COLOR" # What is the best for compatibility?
}.get(component_type, None)
elif gltf2_io_constants.DataType.num_elements(data_type) == 16:
return {
Expand All @@ -187,24 +196,28 @@ def get_attribute_type(component_type, data_type):
else:
pass


def get_attribute(attributes, name, data_type, domain):
attribute = attributes.get(name)
if attribute is not None and attribute.data_type == data_type and attribute.domain == domain:
return attribute
else:
return None


def get_gltf_interpolation(interpolation):
return {
return {
"BEZIER": "CUBICSPLINE",
"LINEAR": "LINEAR",
"CONSTANT": "STEP"
}.get(interpolation, "LINEAR")


def get_anisotropy_rotation_gltf_to_blender(rotation):
# glTF rotation is in randian, Blender in 0 to 1
return rotation / (2 * np.pi)


def get_anisotropy_rotation_blender_to_gltf(rotation):
# glTF rotation is in randian, Blender in 0 to 1
return rotation * (2 * np.pi)
Expand Down
24 changes: 17 additions & 7 deletions addons/io_scene_gltf2/blender/com/data_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def get_target_object_path(data_path: str) -> str:
return ""
return path_split[0]


def get_rotation_modes(target_property: str):
"""Retrieve rotation modes based on target_property"""
if target_property in ["rotation_euler", "delta_rotation_euler"]:
Expand All @@ -45,41 +46,50 @@ def get_rotation_modes(target_property: str):
else:
return False, []


def is_location(target_property):
return "location" in target_property


def is_rotation(target_property):
return "rotation" in target_property


def is_scale(target_property):
return "scale" in target_property


def get_delta_modes(target_property: str) -> str:
"""Retrieve location based on target_property"""
return target_property.startswith("delta_")


def is_bone_anim_channel(data_path: str) -> bool:
return data_path[:10] == "pose.bones"


def get_sk_exported(key_blocks):
return [
k
for k in key_blocks
if not skip_sk(key_blocks, k)
]
k
for k in key_blocks
if not skip_sk(key_blocks, k)
]


def skip_sk(key_blocks, k):
# Do not export:
# - if muted
# - if relative key is SK itself (this avoid exporting Basis too if user didn't change order)
# - the Basis (the first SK of the list)
# - if muted
# - if relative key is SK itself (this avoid exporting Basis too if user didn't change order)
# - the Basis (the first SK of the list)
return k == k.relative_key \
or k.mute \
or is_first_index(key_blocks, k) is True


def is_first_index(key_blocks, k):
return key_blocks[0].name == k.name


def get_object_from_datapath(blender_object, data_path: str):
if "." in data_path:
# gives us: ('modifiers["Subsurf"]', 'levels')
Expand Down
33 changes: 18 additions & 15 deletions addons/io_scene_gltf2/blender/com/gltf2_blender_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ def swizzle_yup_value(value: typing.Any) -> typing.Any:
return value


def transform(v: typing.Union[Vector, Quaternion], data_path: str, transform: Matrix = Matrix.Identity(4), need_rotation_correction: bool = False) -> typing \
.Union[Vector, Quaternion]:
def transform(v: typing.Union[Vector, Quaternion], data_path: str, transform: Matrix = Matrix.Identity(
4), need_rotation_correction: bool = False) -> typing .Union[Vector, Quaternion]:
"""Manage transformations."""
target = get_target_property_name(data_path)
transform_func = {
Expand All @@ -130,28 +130,31 @@ def transform(v: typing.Union[Vector, Quaternion], data_path: str, transform: Ma
return transform_func(v, transform, need_rotation_correction)


def transform_location(location: Vector, transform: Matrix = Matrix.Identity(4), need_rotation_correction:bool = False) -> Vector:
def transform_location(location: Vector, transform: Matrix = Matrix.Identity(4),
need_rotation_correction: bool = False) -> Vector:
"""Transform location."""
correction = Quaternion((2**0.5/2, -2**0.5/2, 0.0, 0.0))
correction = Quaternion((2**0.5 / 2, -2**0.5 / 2, 0.0, 0.0))
m = Matrix.Translation(location)
if need_rotation_correction:
m @= correction.to_matrix().to_4x4()
m = transform @ m
return m.to_translation()


def transform_rotation(rotation: Quaternion, transform: Matrix = Matrix.Identity(4), need_rotation_correction: bool = False) -> Quaternion:
def transform_rotation(rotation: Quaternion, transform: Matrix = Matrix.Identity(4),
need_rotation_correction: bool = False) -> Quaternion:
"""Transform rotation."""
rotation.normalize()
correction = Quaternion((2**0.5/2, -2**0.5/2, 0.0, 0.0))
correction = Quaternion((2**0.5 / 2, -2**0.5 / 2, 0.0, 0.0))
m = rotation.to_matrix().to_4x4()
if need_rotation_correction:
m @= correction.to_matrix().to_4x4()
m = transform @ m
return m.to_quaternion()


def transform_scale(scale: Vector, transform: Matrix = Matrix.Identity(4), need_rotation_correction: bool = False) -> Vector:
def transform_scale(scale: Vector, transform: Matrix = Matrix.Identity(4),
need_rotation_correction: bool = False) -> Vector:
"""Transform scale."""
m = Matrix.Identity(4)
m[0][0] = scale.x
Expand Down Expand Up @@ -197,20 +200,20 @@ def nearby_signed_perm_matrix(rot):
a, b, c = abs(x[0]), abs(x[1]), abs(x[2])
i = 0 if a >= b and a >= c else 1 if b >= c else 2
x[i] = 1 if x[i] > 0 else -1
x[(i+1) % 3] = 0
x[(i+2) % 3] = 0
x[(i + 1) % 3] = 0
x[(i + 2) % 3] = 0

# Same for second row: only two columns to consider now.
a, b = abs(y[(i+1) % 3]), abs(y[(i+2) % 3])
j = (i+1) % 3 if a >= b else (i+2) % 3
a, b = abs(y[(i + 1) % 3]), abs(y[(i + 2) % 3])
j = (i + 1) % 3 if a >= b else (i + 2) % 3
y[j] = 1 if y[j] > 0 else -1
y[(j+1) % 3] = 0
y[(j+2) % 3] = 0
y[(j + 1) % 3] = 0
y[(j + 2) % 3] = 0

# Same for third row: only one column left
k = (0 + 1 + 2) - i - j
z[k] = 1 if z[k] > 0 else -1
z[(k+1) % 3] = 0
z[(k+2) % 3] = 0
z[(k + 1) % 3] = 0
z[(k + 2) % 3] = 0

return m
Loading

0 comments on commit 628c972

Please sign in to comment.