diff options
Diffstat (limited to 'servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp')
-rw-r--r-- | servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index da55b68109..3bc1b476cb 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -430,6 +430,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) s->aabb = new_surface.aabb; s->bone_aabbs = new_surface.bone_aabbs; //only really useful for returning them. + s->mesh_to_skeleton_xform = p_surface.mesh_to_skeleton_xform; s->uv_scale = new_surface.uv_scale; @@ -617,6 +618,7 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { } sd.bone_aabbs = s.bone_aabbs; + sd.mesh_to_skeleton_xform = s.mesh_to_skeleton_xform; if (s.blend_shape_buffer.is_valid()) { sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer); @@ -663,15 +665,16 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { for (uint32_t i = 0; i < mesh->surface_count; i++) { AABB laabb; - if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) { - int bs = mesh->surfaces[i]->bone_aabbs.size(); - const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr(); + const Mesh::Surface &surface = *mesh->surfaces[i]; + if ((surface.format & RS::ARRAY_FORMAT_BONES) && surface.bone_aabbs.size()) { + int bs = surface.bone_aabbs.size(); + const AABB *skbones = surface.bone_aabbs.ptr(); int sbs = skeleton->size; ERR_CONTINUE(bs > sbs); const float *baseptr = skeleton->data.ptr(); - bool first = true; + bool found_bone_aabb = false; if (skeleton->use_2d) { for (int j = 0; j < bs; j++) { @@ -691,11 +694,13 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { mtx.basis.rows[1][1] = dataptr[5]; mtx.origin.y = dataptr[7]; - AABB baabb = mtx.xform(skbones[j]); + // Transform bounds to skeleton's space before applying animation data. + AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]); + baabb = mtx.xform(baabb); - if (first) { + if (!found_bone_aabb) { laabb = baabb; - first = false; + found_bone_aabb = true; } else { laabb.merge_with(baabb); } @@ -723,21 +728,29 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { mtx.basis.rows[2][2] = dataptr[10]; mtx.origin.z = dataptr[11]; - AABB baabb = mtx.xform(skbones[j]); - if (first) { + // Transform bounds to skeleton's space before applying animation data. + AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]); + baabb = mtx.xform(baabb); + + if (!found_bone_aabb) { laabb = baabb; - first = false; + found_bone_aabb = true; } else { laabb.merge_with(baabb); } } } + if (found_bone_aabb) { + // Transform skeleton bounds back to mesh's space if any animated AABB applied. + laabb = surface.mesh_to_skeleton_xform.affine_inverse().xform(laabb); + } + if (laabb.size == Vector3()) { - laabb = mesh->surfaces[i]->aabb; + laabb = surface.aabb; } } else { - laabb = mesh->surfaces[i]->aabb; + laabb = surface.aabb; } if (i == 0) { |