[flutter] Dart side wrapping of skeleton, incomplete.

This commit is contained in:
Mario Zechner 2022-08-27 15:17:57 +02:00
parent 95c567ab03
commit 7adc7a2919
6 changed files with 152 additions and 7 deletions

View File

@ -53,6 +53,7 @@ class AnimationStateEvents extends StatelessWidget {
Widget build(BuildContext context) {
final controller = SpineWidgetController((controller) {
final trackEntry = controller.animationState?.setAnimation(0, "walk", true);
controller.skeleton.setColor(1, 0, 0, 1);
});
return Scaffold(

View File

@ -118,10 +118,154 @@ class SkeletonData {
}
}
class Bone {
final spine_bone _bone;
Bone(this._bone);
}
class Slot {
final spine_slot _slot;
Slot(this._slot);
}
class Attachment {
final spine_attachment _attachment;
Attachment(this._attachment);
}
class IkConstraint {
final spine_ik_constraint _constraint;
IkConstraint(this._constraint);
}
class TransformConstraint {
final spine_transform_constraint _constraint;
TransformConstraint(this._constraint);
}
class PathConstraint {
final spine_path_constraint _constraint;
PathConstraint(this._constraint);
}
class Skeleton {
final spine_skeleton _skeleton;
Skeleton(this._skeleton);
/// Caches information about bones and constraints. Must be called if bones, constraints or weighted path attachments are added
/// or removed.
void updateCache() {
_bindings.spine_skeleton_update_cache(_skeleton);
}
/// Updates the world transform for each bone and applies constraints.
void updateWorldTransform() {
_bindings.spine_skeleton_update_world_transform(_skeleton);
}
void updateWorldTransformBone(Bone parent) {
_bindings.spine_skeleton_update_world_transform_bone(_skeleton, parent._bone);
}
/// Sets the bones, constraints, and slots to their setup pose values.
void setToSetupPose() {
_bindings.spine_skeleton_set_to_setup_pose(_skeleton);
}
/// Sets the bones and constraints to their setup pose values.
void setBonesToSetupPose() {
_bindings.spine_skeleton_set_bones_to_setup_pose(_skeleton);
}
void setSlotsToSetupPose() {
_bindings.spine_skeleton_set_slots_to_setup_pose(_skeleton);
}
Bone? findBone(String boneName) {
final nameNative = boneName.toNativeUtf8();
final bone = _bindings.spine_skeleton_find_bone(_skeleton, nameNative.cast());
calloc.free(nameNative);
if (bone.address == nullptr.address) return null;
return Bone(bone);
}
Slot? findSlot(String slotName) {
final nameNative = slotName.toNativeUtf8();
final slot = _bindings.spine_skeleton_find_slot(_skeleton, nameNative.cast());
calloc.free(nameNative);
if (slot.address == nullptr.address) return null;
return Slot(slot);
}
/// Attachments from the new skin are attached if the corresponding attachment from the old skin was attached.
/// If there was no old skin, each slot's setup mode attachment is attached from the new skin.
/// After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
/// See Skeleton::setSlotsToSetupPose()
/// Also, often AnimationState::apply(Skeleton&) is called before the next time the
/// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
/// @param newSkin May be NULL.
void setSkin(String skinName) {
final nameNative = skinName.toNativeUtf8();
_bindings.spine_skeleton_set_skin(_skeleton, nameNative.cast());
calloc.free(nameNative);
}
Attachment? getAttachmentByName(String slotName, String attachmentName) {
final slotNameNative = slotName.toNativeUtf8();
final attachmentNameNative = attachmentName.toNativeUtf8();
final attachment = _bindings.spine_skeleton_get_attachment_by_name(_skeleton, slotNameNative.cast(), attachmentNameNative.cast());
calloc.free(slotNameNative);
calloc.free(attachmentNameNative);
if (attachment.address == nullptr.address) return null;
return Attachment(attachment);
}
Attachment? getAttachment(int slotIndex, String attachmentName) {
final attachmentNameNative = attachmentName.toNativeUtf8();
final attachment = _bindings.spine_skeleton_get_attachment(_skeleton, slotIndex, attachmentNameNative.cast());
calloc.free(attachmentNameNative);
if (attachment.address == nullptr.address) return null;
return Attachment(attachment);
}
void setAttachment(String slotName, String attachmentName) {
final slotNameNative = slotName.toNativeUtf8();
final attachmentNameNative = attachmentName.toNativeUtf8();
_bindings.spine_skeleton_set_attachment(_skeleton, slotNameNative.cast(), attachmentNameNative.cast());
calloc.free(slotNameNative);
calloc.free(attachmentNameNative);
}
IkConstraint? findIkConstraint(String constraintName) {
final nameNative = constraintName.toNativeUtf8();
final constraint = _bindings.spine_skeleton_find_ik_constraint(_skeleton, nameNative.cast());
calloc.free(nameNative);
if (constraint.address == nullptr.address) return null;
return IkConstraint(constraint);
}
TransformConstraint? findTransformConstraint(String constraintName) {
final nameNative = constraintName.toNativeUtf8();
final constraint = _bindings.spine_skeleton_find_transform_constraint(_skeleton, nameNative.cast());
calloc.free(nameNative);
if (constraint.address == nullptr.address) return null;
return TransformConstraint(constraint);
}
PathConstraint? findPathConstraint(String constraintName) {
final nameNative = constraintName.toNativeUtf8();
final constraint = _bindings.spine_skeleton_find_path_constraint(_skeleton, nameNative.cast());
calloc.free(nameNative);
if (constraint.address == nullptr.address) return null;
return PathConstraint(constraint);
}
}
class Animation {

View File

@ -1243,7 +1243,7 @@ class SpineFlutterBindings {
void spine_skeleton_update_world_transform_bone(
spine_skeleton skeleton,
ffi.Pointer<spine_bone> parent,
spine_bone parent,
) {
return _spine_skeleton_update_world_transform_bone(
skeleton,
@ -1252,12 +1252,11 @@ class SpineFlutterBindings {
}
late final _spine_skeleton_update_world_transform_bonePtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(spine_skeleton, ffi.Pointer<spine_bone>)>>(
ffi.NativeFunction<ffi.Void Function(spine_skeleton, spine_bone)>>(
'spine_skeleton_update_world_transform_bone');
late final _spine_skeleton_update_world_transform_bone =
_spine_skeleton_update_world_transform_bonePtr
.asFunction<void Function(spine_skeleton, ffi.Pointer<spine_bone>)>();
.asFunction<void Function(spine_skeleton, spine_bone)>();
void spine_skeleton_set_to_setup_pose(
spine_skeleton skeleton,

View File

@ -204,9 +204,10 @@ class _SpineRenderObject extends RenderBox {
..save()
..clipRect(offset & size);
final commands = _skeletonDrawable.render();
canvas.save();
canvas.translate(offset.dx + size.width / 2, offset.dy + size.height);
final commands = _skeletonDrawable.render();
for (final cmd in commands) {
canvas.drawVertices(cmd.vertices, BlendMode.modulate,
_skeletonDrawable.atlas.atlasPagePaints[cmd.atlasPageIndex]);

View File

@ -660,7 +660,7 @@ FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform(spine_skeleton skel
_skeleton->updateWorldTransform();
}
FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone *parent) {
FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone parent) {
if (skeleton == nullptr) return;
if (parent == nullptr) return;
Skeleton *_skeleton = (Skeleton*)skeleton;

View File

@ -183,7 +183,7 @@ FFI_PLUGIN_EXPORT float spine_track_entry_get_track_complete(spine_track_entry e
FFI_PLUGIN_EXPORT void spine_skeleton_update_cache(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone *parent);
FFI_PLUGIN_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone parent);
FFI_PLUGIN_EXPORT void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton);
FFI_PLUGIN_EXPORT void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton);