计算骨骼变形网格的AABB结果不准确,求排查解决
骨骼变形网格AABB计算不精准问题
继此前相关提问后,参考社区帖子编写了考虑骨骼权重的代码,用于计算受Skeleton3D骨骼变形的MeshInstance3D的精确AABB,但最终结果并不精准,具体实现如下:
核心计算函数
func get_precise_aabb(mesh_instance : MeshInstance3D): # 获取网格数据 var skeleton:Skeleton3D = mesh_instance.get_node_or_null(mesh_instance.skeleton) var data : Array = mesh_instance.mesh.surface_get_arrays(0) var vertices : Array = data[Mesh.ARRAY_VERTEX] var bones: Array = data[Mesh.ARRAY_BONES] var weights: Array = data[Mesh.ARRAY_WEIGHTS] var bone_count :int = len(weights)/len(vertices) # 找出网格中极值顶点 var low : Vector3 = Vector3.INF var high : Vector3 = -Vector3.INF for vert_idx in len(vertices): var vert = vertices[vert_idx] var deformed_transformation := Transform3D.IDENTITY for i in bone_count: # 对顶点应用骨骼加权变换 var weight = weights[vert_idx * bone_count + i] var bone_idx = bones[vert_idx * bone_count + i] var bone_relative_transform = skeleton.get_bone_global_pose(bone_idx) * skeleton.get_bone_global_rest(bone_idx).inverse() var bone_frame_transform = Transform3D( lerp(Transform3D.IDENTITY.basis, bone_relative_transform.basis, weight), lerp(Transform3D.IDENTITY.origin, bone_relative_transform.origin, weight) ) deformed_transformation = deformed_transformation * skeleton.global_transform * bone_frame_transform vert = deformed_transformation * vert low.x = min(low.x, vert.x) high.x = max(high.x, vert.x) low.y = min(low.y, vert.y) high.y = max(high.y, vert.y) low.z = min(low.z, vert.z) high.z = max(high.z, vert.z) return AABB(low, high - low)
Tool模式调用代码
@tool extends Node3D @export var btn: bool = false :set=set_bth func set_bth(value: bool): if !value: return var precise_aabb = get_precise_aabb($Skeleton3D/Cube) var bounding_box = $BoundingBox bounding_box.scale = precise_aabb.size bounding_box.global_position = precise_aabb.position + precise_aabb.size / 2
问题现象
运行后生成的AABB与变形后的网格不匹配,编辑器截图显示包围盒的位置和大小存在明显偏差,已准备最小复现项目用于排查问题。
内容的提问来源于stack exchange,提问作者Manas R. Makde
相关产品推荐
相关产品推荐

