Automatically transform Skeleton2D calculations so pivots are not needed
This commit is contained in:
parent
0f8f0ab126
commit
eb9c2b878a
10 changed files with 92 additions and 4 deletions
|
|
@ -440,6 +440,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
|
|||
const Item::CommandMesh *cm = static_cast<const Item::CommandMesh *>(c);
|
||||
if (cm->mesh_instance.is_valid()) {
|
||||
mesh_storage->mesh_instance_check_for_update(cm->mesh_instance);
|
||||
mesh_storage->mesh_instance_set_canvas_item_transform(cm->mesh_instance, canvas_transform_inverse * ci->final_transform);
|
||||
update_skeletons = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,16 @@ uniform highp float blend_weight;
|
|||
uniform lowp float blend_shape_count;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SKELETON
|
||||
uniform mediump vec2 skeleton_transform_x;
|
||||
uniform mediump vec2 skeleton_transform_y;
|
||||
uniform mediump vec2 skeleton_transform_offset;
|
||||
|
||||
uniform mediump vec2 inverse_transform_x;
|
||||
uniform mediump vec2 inverse_transform_y;
|
||||
uniform mediump vec2 inverse_transform_offset;
|
||||
#endif
|
||||
|
||||
vec2 signNotZero(vec2 v) {
|
||||
return mix(vec2(-1.0), vec2(1.0), greaterThanEqual(v.xy, vec2(0.0)));
|
||||
}
|
||||
|
|
@ -164,10 +174,13 @@ void main() {
|
|||
m += GET_BONE_MATRIX(bones.z, bones_a.z, in_weight_attrib.z);
|
||||
m += GET_BONE_MATRIX(bones.w, bones_a.w, in_weight_attrib.w);
|
||||
|
||||
mat4 skeleton_matrix = mat4(vec4(skeleton_transform_x, 0.0, 0.0), vec4(skeleton_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(skeleton_transform_offset, 0.0, 1.0));
|
||||
mat4 inverse_matrix = mat4(vec4(inverse_transform_x, 0.0, 0.0), vec4(inverse_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(inverse_transform_offset, 0.0, 1.0));
|
||||
mat4 bone_matrix = mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
//reverse order because its transposed
|
||||
out_vertex = (vec4(out_vertex, 0.0, 1.0) * bone_matrix).xy;
|
||||
bone_matrix = skeleton_matrix * transpose(bone_matrix) * inverse_matrix;
|
||||
|
||||
out_vertex = (bone_matrix * vec4(out_vertex, 0.0, 1.0)).xy;
|
||||
#endif // USE_SKELETON
|
||||
|
||||
#else // MODE_2D
|
||||
|
|
|
|||
|
|
@ -997,6 +997,11 @@ void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {
|
|||
}
|
||||
}
|
||||
|
||||
void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) {
|
||||
MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
|
||||
mi->canvas_item_transform_2d = p_transform;
|
||||
}
|
||||
|
||||
void MeshStorage::_blend_shape_bind_mesh_instance_buffer(MeshInstance *p_mi, uint32_t p_surface) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p_mi->surfaces[p_surface].vertex_buffers[0]);
|
||||
|
||||
|
|
@ -1163,6 +1168,16 @@ void MeshStorage::update_mesh_instances() {
|
|||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);
|
||||
|
||||
if (can_use_skeleton) {
|
||||
Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);
|
||||
|
||||
Transform2D inverse_transform = transform.affine_inverse();
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);
|
||||
|
||||
// Do last blendshape in the same pass as the Skeleton.
|
||||
_compute_skeleton(mi, sk, i);
|
||||
can_use_skeleton = false;
|
||||
|
|
@ -1201,6 +1216,16 @@ void MeshStorage::update_mesh_instances() {
|
|||
continue;
|
||||
}
|
||||
|
||||
Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);
|
||||
|
||||
Transform2D inverse_transform = transform.affine_inverse();
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);
|
||||
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);
|
||||
|
||||
glBindVertexArray(mi->mesh->surfaces[i]->skeleton_vertex_array);
|
||||
_compute_skeleton(mi, sk, i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ struct MeshInstance {
|
|||
bool weights_dirty = false;
|
||||
SelfList<MeshInstance> weight_update_list;
|
||||
SelfList<MeshInstance> array_update_list;
|
||||
Transform2D canvas_item_transform_2d;
|
||||
MeshInstance() :
|
||||
weight_update_list(this), array_update_list(this) {}
|
||||
};
|
||||
|
|
@ -423,6 +424,7 @@ public:
|
|||
virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override;
|
||||
virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override;
|
||||
virtual void mesh_instance_check_for_update(RID p_mesh_instance) override;
|
||||
virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) override;
|
||||
virtual void update_mesh_instances() override;
|
||||
|
||||
// TODO: considering hashing versions with multimesh buffer RID.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue